1,什么是布局
这是一个很简单的问题。简单来说,就是把一些控件有条理的摆放在界面上合适的位置,显然摆的乱七八糟不能算布局。在WPF中,这个条理与WinForm中略有不同,让我们看个很简单的界面:
这样子的界面大家在熟悉不过了。依图所示,WPF先用蓝线(假设的线)将界面划分为上下两部分,然后再有红线划分出多个方格,最后放入控件,其中每部分中的控件或划分的空格只能纵向排列,或横向排列,不能有其他选择。大多数情况下,WPF程序界面上的控件都要按照此种递归的方法逐个排列,最终形成所看到的界面。简单的
2,基本元素——面板
在上节中我们了解了WPF布局原理,这可以简单理解为大控件中按排或列放入小控件,小控件在按照同样规则放入更小控件。这种能放入其他控件的控件是WPF布局系统中的基本元素——面板。面板是用来放东西的,既包括控件元素,也包括面板自己。面板不仅能承载其他子元素(控件),还能控制子元素的大小,位置以及如何排列。例如上述例子中,蓝线划分的面板控制子元素只能上下排列,而红线划分的面板控制的子元素只能横向排列。
WPF默认提供了几种面板都是从基面板(Panel)继承而来,看一下它们的继承链。
System.Windows.Threading.DispatcherObject
System.Windows.DependencyObject
System.Windows.Media.Visual
System.Windows.UIElement
System.Windows.FrameworkElement
System.Windows.Controls.Control
System.Windows.Controls.Panel
System.Windows.Controls.Canvas
System.Windows.Controls.DockPanel
System.Windows.Controls.Grid
System.Windows.Controls.StackPanel
System.Windows.Controls.VirtualizingPanel
System.Windows.Controls.WrapPanel
3、常用容器控件
WPF默认提供了数种布局控件,常用的包括如下几种:
(1)Canvas:此面板可承载任意元素,包括控件,图形,甚至文字。各种元素依据屏幕坐标确定位置。
(2)DockPanel:此面板可指定元素的排列停靠方式,每个子元素的排列方式可以不同。
(3)Grid:此面板使子元素按照纵横网格排列。
(4)StackPanel:此面板使子元素按照水平或垂直方向排列,两个方向只能选其一。
(5)VirtualizingStackPanel与StackPanel相同,不同之处在于它可以使内容虚拟化。
(6)WrapPanel:使子元素按照水平或垂直方向排列,在行或列处换行或列,依旧按照水平或垂直方向从左到右或从上到下排列。
4、附加属性
通过上面我们了解到子元素通过一些属性值的设置实现在面板上布局,比如Alignment对齐属性,Dock停靠排列属性。这些属性不属于子元素本身,而依赖与所在的父元素。比如同样是Button,在DockPanel中有Dock属性,而在Grid中就没有。这些属性的存在依赖与父元素,在WPF中称做“附加属性”。
附加属性的用途是允许不同的子元素为实际在父元素中定义的属性指定唯一值,目的是让子元素通知父元素它将如何在界面中呈现。如上面提到的DockPanel.Dock 属性,因为它将在 DockPanel 中包含的元素上设置,而不是在 DockPanel 本身设置。注意,相对于子元素,父元素提供的附加属性相当于全局属性。
5、布局与性能
通过上面我们了解到,当给界面元素的布局属性赋值时,布局系统需要重新计算和排列所有子元素的“FinalSize”(因为改变影响不可知)。这是一个递归的过程。如果不注意,可能会带来性能问题。因此在设计时应注意下面几点:
1,应注意哪些属性值更改会引起执行布局系统的递归更新;
2,如有可能,应使用 RenderTransform 而不要使用 LayoutTransform;
3,避免不必要地调用 UpdateLayout,因为UpdateLayout强制调用布局系统的递归更新;
4,当包含大量元素集合时,请使用 VirtualizingStackPanel虚拟化元素;
总结:这四大要点主要说明了布局的几个因素,我们可以通过布局控件,StackPanel、DockPanel、Canvas....等这些布局面板来实现我们的页面模块的格,再面板里面再设置一下我们想要的布局控件和页面内容的显示,就能简单的搭建一个demo。