《WPF程序设计指南》读书笔记——第5章 Stack与Wrap
1.StackPanel面板
using System; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Windows.Controls; namespace LY.StactTheButtons { public class StackTheButton:Window { [STAThread] public static void Main() { new Application().Run(new StackTheButton()); } public StackTheButton() { Title = "Stack The Button"; StackPanel stack = new StackPanel(); stack.Background = Brushes.AliceBlue; //设定面板的子元素水平方向排列 //stack.Orientation = Orientation.Horizontal; //设定面板对齐方式为在窗口中央 //stack.HorizontalAlignment = HorizontalAlignment.Center; //将窗体根据内容设定大小 SizeToContent = SizeToContent.WidthAndHeight; ResizeMode = ResizeMode.CanMinimize; stack.Margin = new Thickness(5); Content = stack; Random rand = new Random(); for (int i = 0; i < 10; i++) { Button btn = new Button(); btn.Name = "A" + i; //FontSize默认值为System.Windows.SystemFonts.MessageFontSize btn.FontSize += rand.Next(10); //btn.HorizontalAlignment = HorizontalAlignment.Center; btn.Margin = new Thickness(5); btn.Content = "Button " + btn.Name + " Says 'Click Me'"; stack.Children.Add(btn); //btn.Click += btn_Click; } //添加事件,可取代上面的btn.Click+=btn_Click,但两者的区别是sender对象不同 //AddHandler定义的事件会对面板中的所以button对象起作用 //这里如果去掉stack也可以,即设定为窗口为sender stack.AddHandler(Button.ClickEvent, new RoutedEventHandler(btn_Click)); stack.Children[0].Focus(); } void btn_Click(object sender, RoutedEventArgs e) { Button btn = e.Source as Button; MessageBox.Show("Button " + btn.Name + " has been clicked", "Button Click"); } } }
Stack面板嵌套/ScrollViewer控件/Viewbox控件/e.Source的使用注意
using System; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Windows.Controls; using System.Windows.Controls.Primitives; namespace LY.StackThirtyButtons { class StackThirtyButtons:Window { [STAThread] public static void Main() { new Application().Run(new StackThirtyButtons()); } public StackThirtyButtons() { Title = "嵌套Stack面板"; AddHandler(Button.ClickEvent, new RoutedEventHandler(Button_Click)); //使用可滚动区域控件 ScrollViewer scroll = new ScrollViewer(); scroll.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto; scroll.VerticalScrollBarVisibility = ScrollBarVisibility.Visible; Content = scroll; //Viewbox控件可以代替ScrollViewer使用,它没有滚动条, //但会根据内容缩放其大小,保证所有内容可见 //Viewbox view = new Viewbox(); //Content = view; StackPanel mainStack = new StackPanel(); mainStack.Orientation = Orientation.Horizontal; mainStack.Margin = new Thickness(5); scroll.Content = mainStack; //view.Child = mainStack; for (int i = 0; i < 3; i++) { StackPanel stack = new StackPanel(); stack.Margin = new Thickness(5); mainStack.Children.Add(stack); for (int j = 0; j < 10; j++) { Button btn = new Button(); btn.Content = "Button No. " + (10 * i + j + 1); stack.Children.Add(btn); } } } private void Button_Click(object sender, RoutedEventArgs e) {
//e.Source指向Button,而此时Sender是this Button btn = e.Source as Button; /* * 因为AddHandler的Sender是窗口,当点击滚动条上的 * 按钮(RepeatButton类型,继承自ButtonBase,有Click事件), * 则无法转换成Button,btn此时为Null,可以在 * AddHandler前加上mainStack,将其Sender设定为mainStack */ if (btn != null) MessageBox.Show(btn.Content + " has been clicked", "Button Click"); } } }
GroupBox控件/RadioButton控件
using System; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Windows.Controls; namespace LY.TuneTheRadio { class TuneTheRadio : Window { [STAThread] public static void Main() { new Application().Run(new TuneTheRadio()); } public TuneTheRadio() { Title = "单选按钮的使用"; SizeToContent = SizeToContent.WidthAndHeight; GroupBox group = new GroupBox(); //设定GroupBox控件的标头属性 group.Header = "Window Style属性"; group.Margin = new Thickness(96); group.Padding = new Thickness(5); Content = group; StackPanel stack = new StackPanel(); group.Content = stack; stack.Children.Add(CreateRadioButton("无边框样式", WindowStyle.None, "1")); stack.Children.Add(CreateRadioButton("单边框样式", WindowStyle.SingleBorderWindow, "1")); stack.Children.Add(CreateRadioButton("三维边框样式", WindowStyle.ThreeDBorderWindow, "2")); stack.Children.Add(CreateRadioButton("固定工具框样式", WindowStyle.ToolWindow, "2")); AddHandler(RadioButton.CheckedEvent, new RoutedEventHandler(RadioOnChecked)); } private void RadioOnChecked(object sender, RoutedEventArgs e) { RadioButton radio = e.Source as RadioButton; WindowStyle = (WindowStyle)radio.Tag; } private RadioButton CreateRadioButton(string strText, WindowStyle winStyle, string groupNum) { RadioButton radio = new RadioButton(); //GroupName属性可以将GroupBox中的单选按钮分成组 radio.GroupName = groupNum; radio.Content = strText; //存储有关此元素的自定义信息 radio.Tag = winStyle; radio.Margin = new Thickness(5); radio.IsChecked = (WindowStyle == winStyle); return radio; } } }
将GroupBox的Content设定为StackPanel,再在StackPanel的Children中加入多个RadioButton。也就是说只有面板Panel中才能放多个控件对象,其他ContentControl只能通过Content放入一个对象。主要的面板控件有:
2.WrapPanel面板
WrapPanel以由左到右,由上到下形式摆放控件;一般用于不确定包含多少个控件时,如资源管理器。平常用StackPanel比较多。
WrapPanel面板一般搭配ScrollViewer控件使用。
using System; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Windows.Controls; namespace LY.ExploreDirectories { class ExploreDirectories : Window { [STAThread] public static void Main() { new Application().Run(new ExploreDirectories()); } public ExploreDirectories() { Title = "Explore Directories"; ScrollViewer scroll = new ScrollViewer(); Content = scroll; WrapPanel wrap = new WrapPanel(); scroll.Content = wrap; wrap.Children.Add(new FileSystemInfoButton()); } } }
using System; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Windows.Controls; using System.IO; using System.Diagnostics; namespace LY.ExploreDirectories { public class FileSystemInfoButton : Button { FileSystemInfo info; public FileSystemInfoButton() : this(new DirectoryInfo( Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments))) { } public FileSystemInfoButton(FileSystemInfo info) { this.info = info; Content = info.Name; if (info is DirectoryInfo) FontWeight = FontWeights.Bold; Margin = new Thickness(10); } public FileSystemInfoButton(FileSystemInfo info, string str) : this(info) { Content = str; } protected override void OnClick() { if (info is FileInfo) Process.Start(info.FullName); else if (info is DirectoryInfo) { DirectoryInfo dir = info as DirectoryInfo; Application.Current.MainWindow.Title = dir.FullName; Panel pnl = Parent as Panel; pnl.Children.Clear(); if (dir.Parent != null) pnl.Children.Add(new FileSystemInfoButton(dir.Parent, "..")); foreach (FileSystemInfo inf in dir.GetFileSystemInfos()) { pnl.Children.Add(new FileSystemInfoButton(inf)); } } base.OnClick(); } } }