在WPF休系中,对于布局,要比WinForm 丰富,也比web中丰富(尽管web中可以利用Table和div很好的完成布局),因为WPF这个技术就是专门为UI层来设计的,所以在处理UI的时候,变的异常丰富。
支持UI主要用面板(即一个父控件,起承载的作用)来实现,在WPF中,主要的面板有以下几种:
元素名称 | 说明 |
定义一个区域,在此区域内,您可以使用相对于 Canvas 区域的坐标显式定位子元素。 | |
定义一个区域,在此区域中,您可以使子元素互相水平或垂直排列。 | |
将子元素排列成一行(可沿水平或垂直方向)。 | |
处理 TabControl 中选项卡按钮的布局。 | |
在 ToolBar 控件内排列内容。 | |
UniformGrid 用于在网格内按全部相等的单元格大小排列子元素。 | |
提供面板的一个基类,该基类能够“虚拟化”面板的子集合。 | |
将内容排列成一行(可沿水平或垂直方向),并使内容虚拟化。 | |
WrapPanel 从左至右按顺序位置定位子元素,并在包含框的边缘处将内容断开至下一行。 后续排序按照从上至下或从右至左的顺序进行,具体取决于 Orientation 属性的值。 |
这些面板都是继承Panel而来。
Panel是一个面板的抽象类,是所有面板的基类,它是继承结构如下:
System .Object
System.Windows.Threading .DispatcherObject
System.Windows .DependencyObject
System.Windows.Media .Visual
System.Windows .UIElement
System.Windows .FrameworkElement
System.Windows.Controls .Panel
System.Windows.Controls .Canvas
System.Windows.Controls .DockPanel
System.Windows.Controls .Grid
System.Windows.Controls.Primitives .TabPanel
System.Windows.Controls.Primitives .ToolBarOverflowPanel
System.Windows.Controls.Primitives .UniformGrid
System.Windows.Controls .StackPanel
System.Windows.Controls .VirtualizingPanel
System.Windows.Controls .WrapPanel
不同的面板,来分别实现不同的布局,这要比WinForm和WebForm中的Panel细化一层,可以实现不同的布局,这也能体现出WPF在做UI的更强大的一面。
WPF中的布局,是依据自己的特性来展开的,因为WPF是采用标签嵌套的方式来表示标签间的关系,所以在更新父级标签时,在布局上要影响子标签的显示。所以在WPF中,一但父级标签布局发生变化,所有子级标签都要进行更新。
一个布局发生变化,并最终完成变化的生命周期是先由变化的布局标签的父类UIElement(因为所有的Panel子类都是从UIElement继承下来的),的对应属性发生变化,然后是FrameworkElement类相应的属性发生改变,再由具体的Panel根据自己的特点来计算标签的大小,如果该标签还有子标签,那就再计算,依次递归,计算好后,就可以来布局计算好的标签了。当再次某标签布局发生变化,这个过程就重复执行。
更新标签时,分两步来进行,第一步是计算标签的相应值(比如宽Width和高Height),第二步是布局标签。计算和布局分别由MeasureOverride和ArrangeOverride方法来完成的,这两个方法都是从FrameworkElement继承而来的。
因为Panel布局时,要引发本标签下的所有标签计算和布局,所以尽量避免引发不必要的重新Panel计算和Panel布局。