来自window Presentation Foundation Program Design的读书笔记 第五篇 上
我们将在本章讲解面板Stack和Wrap,首先我们来看下他们的继承结构:
1: UIElement
2: FrameworkElement
3: Panel(abstract)
4: Canvas
5: DockPanel
6: Grid
7: StackPanel
8: UniformGrid
9: WrapPanel
Panel定义了Children property,用来存储Child Element,Children property的类型是UIElementCollection
,也就是UIelement对象的collection,因此面板的对象可以是Image、Shape、TextBlock和Control以及其他的面板对象等。
我们看一段程序,改程序将在面板上建立10个按钮:
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5: using System.Windows;
6: using System.Windows.Controls;
7: using System.Windows.Data;
8: using System.Windows.Documents;
9: using System.Windows.Input;
10: using System.Windows.Media;
11: using System.Windows.Media.Imaging;
12: using System.Windows.Navigation;
13: using System.Windows.Shapes;
14:
15: namespace WPF_StackAndWrap
16: {
17: /// <summary>
18: /// MainWindow.xaml 的交互逻辑
19: /// </summary>
20: public partial class MainWindow : Window
21: {
22: public MainWindow()
23: {
24: InitializeComponent();
25: Loaded += WindowOnLoaded;
26: }
27:
28: private void WindowOnLoaded(object sender, RoutedEventArgs e)
29: {
30: TenButton();
31: }
32:
33: private void TenButton()
34: {
35: Title = "This is Stack";
36: StackPanel panel = new StackPanel();
37: Content = panel;
38:
39: Random rand = new Random();
40: for (int i = 0; i < 10; i++)
41: {
42: Button btn = new Button();
43: btn.Name = ((char)('A' + i)).ToString();
44: btn.Content = "Button " + btn.Name + " Click Me";
45: btn.FontSize += rand.Next(10);
46: panel.Children.Add(btn);
47:
48: btn.Click += (sender, e) =>
49: {
50: MessageBox.Show((sender as Button).Content.ToString());
51: };
52: }
53: }
54: }
55: }
当然,你可以给StackPanel加上背景色,确认StackPanel到底有多大:
1: panel.Background = Brushes.Aquamarine;
或者,改变子元素堆叠的方向,用Orientation property:
1: panel.Orientation = Orientation.Horizontal;
如果你需要选择一个元素,如果这个元素在XAML文件里进行了定义,那么你可以通过如下的方式获取:
1: object obj = FindName("Name");
这个方法调用的是window的FindName(),但是它会递归查询元素,当然,你还可以通过Children这个UIElementCollection元素来获取节点:
1: UIElement ele = panel.Children[0];
或者,如果el是panel的一个子节点,那么:
1: int index = panel.Children.IndexOf(el);
如果找到就返回相应的index,没有就返回-1;
除了在循环中绑定btn.Click事件意外,我们还可以通过以下方式来绑定事件:
1: AddHandler(Button.ClickEvent,new RoutedEventHandler(ButtonOnClick));
2:
3: private void ButtonOnClick(object sender, RoutedEventArgs e)
4: {
5: MessageBox.Show(((Button)e.Source).Name);
6: }
在这里需要注意,ButtonOnClick这个方法里的sender指向的是window,而e.Source属性指向的是事件的具体触发者。
如果你需要显示的内容太多,一屏幕显示不了的时候,你就需要一个滚动条了,在这里ScrollViewer类就可以帮助你完成这个需求,ScrollViewer类和window和ButtonBase类一样,同样继承自ContentControl,我们下面的例子,将创建50个按钮来演示ScrollViewer:
1: private void ScrollViewerTest()
2: {
3: ScrollViewer scroll = new ScrollViewer();
4: Content = scroll;
5:
6: StackPanel stack = new StackPanel();
7: scroll.Content = stack;
8: Random rand =new Random();
9:
10: for (int i = 0; i < 50; i++)
11: {
12: Button btn = new Button();
13: btn.Content = ((char)('A' + i)).ToString();
14: btn.FontSize += rand.Next(10);
15:
16: stack.Children.Add(btn);
17: }
18: }
你可以尝试着把scroll.VerticalScrollBarVisibility设置成为VerticalScrollBarVisibility.auto:
1: scroll.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
这样竖向的滚动条就会在需要的时候显示。
昨天接了个长电话,所以博文没有写完,今天一定补上。