WPF 布局简述
WPF布局是通过面板(Panel)对页面元素进行全面规划和安排。简单地说,就是把一些控件有条理地摆放在界面上合适的位置。在应用程序界面设计中,合理的元素布局至关重要,它可以方便用户操作,并用清晰的页面逻辑呈现用户信息。
如果内置布局控件不能清足需要,用户还可以创建自定义的布局元素。
WPF 布局原则
WinForm的布局是采用基于坐标的方式,当窗口内容发生变化时,里面的控件不会随之动态调整,用户体验不够好。而WPF采用了基于流的布局方式,像Web开发模式。流式布局特点是:所有的元素总是默认地自动向左上角靠近,在设计时,通过控制元素相对位置的方式使其达到预计的效果,即元素的位置依赖于相邻元素的位置和尺寸。
合成布局元素
WPF的合成布局模型是用来满足广泛的应用场景布局,允许某种布局控件被嵌套在其他布局控件中。合成布局模型通过布局契约来实现子控件和父布局控件间的通信问题。布局契约包括两种设计思想,即根据内容调整尺寸和两段布局。
1.根据内容调整尺寸
根据内容调整尺寸,即每个控件都根据内容来确定控件大小,这个设计思想应用于UI中的所有控件。例如,窗口能够调整大小来适应它们内部的控件,文本框控件能调整尺寸来适应它内部的文本。当然每个元素会被询问其期望的尺寸大小,以确保根据内容调整尺寸的设计思想能够实施。
2.两段布局
两段布局是指在两个完全不同的阶段来确定控件的最佳尺寸。在这两个阶段布局模型让父布局控件和子控件达成元素最后尺寸的约定。两个阶段分别是测量(Measure) 和排列(Arrange) 。测量阶段需要做的主要工作是:对整个UI页面的检测,并询问每个元素的期望尺寸(Desired Size) ,元素返回一个可用的尺寸(Avilable Size),当所有的元索都被询问并测量好以后,就进入到排列阶段。在排列阶段,父元素通知每个子元素的实际尺寸(Actual Size)和位置。
在两段布局中。父元素和子元素需要协商出需要的尺寸大小,涉及可用尺寸 ,期望尺寸、实际尺寸,在此辨析3个尺寸。其中,可用尺寸是测量阶段的初始约束值,即父元素愿意给子元素的最大空间值;期望尺寸是子元素想要的尺寸;实际尺寸是父元元素分配给子元素的最终尺寸。这3个尺寸要符合下面的不等式条件:
- Desired Size ≤ Actual Size ≤ Available Size
了解WPF合成布局模型,学习WPF布局机制,才能理解合成布局模型的来龙去陆页面布局时做到得心应手。
布局机制
WPF界面上的每个元素的边界框尺寸和排列是WPF自动计算出来的。通过WPF合成布局模型的学习,了解WPF渲染布局的过程中,执行测量( Measure) 和排列(Arrango) 两个步骤。在布局机制中,详细分解在WPF布局的不同阶段,后台类的调用过程。在测量阶段,布局容器遍历所有子元素,并询问子元素所期望的尺寸;在排列阶段,布局控件在合适的位置放置子元素,并设置元素的最终尺寸;这是一个递归的过程,界面中任何一个容器元素都会被遍历到。
因为面板可以嵌套,所以处理过程是递归的,布局(Layout)处理的过程如下图所示:
在此,简要说明WPF布局处理过程。由WPF框架可知,所有UI元素的根元素后UIElement类型,在UlElement中定义了一些基本的关于UI显示的属性(如Clip和Visibility) 。在UIElement.Measure(Size availableSize) 方法执行阶段,就是对这些基本属性做评估,获得适合的Size。同样,FrameworkElement.MeasureCore(Size availablblesiz) 方法评估时,在FrameworkElement中定义且有可能影响UI布局的属性,得出更适合的Size,这个Size将被传递给FrameworkElement.MeasureOverride(Size availbeSize) WPF提供的Panel类型(如Grid)中就会重写该方法来处理,处理完后将得到个系统期望的Size(称为DesiredSize) 。布局系统将按照这个Size来显示该Element,测量(Measure)阶段结束。Size确定后,把Size包装为Rect实例,传递给UIElement.Arrange(Rect,finalRect) ,进行排列(Arrange)处理。根据Size值,Arrange方法为元素创建边界框,边框打包到Rect实例,传给FrameworkElement.ArrangeCore(Rect finalRet) 方法。ArrangeCore将继续评估DesiredSize,计算边界留白(Margin,Padding)等信息,获得ArrangeSize,并传给FrameworkElement.Arrangeovrride(Size finalSize) 。这个方法也是可重写的,WPF提供的Panel类型会重写该方法来处理,最终获得finalSize. 当finalSize 确定后,ArrangeOverride执行完毕。控制权回到ArrangeCore方法, ArrangeCore把该Element放到它的边界框中。到此,该Element的Layout处理完成。
布局通用属性
所有的WPF布局面板都由System.Windows.Controls.Panel抽象类派生。Panel就是所有布局元素的基类,用于放置和排列WPF元素,这个抽象类包含3个公共属性:Background
、Children
和IsItemHost(IsItemHost标志着控件是不是类似TreeView 和ListView这样的控件)
。布局容器内的子元素对自身的对齐方式(HorizontalAlignment、VerticalAlignment)
、宽度(Width)
、高度(Height)
、四周间隙(Margin)
等有一定的决定权。子元素可以设置自身的布局属性来调整自己的位置和大小。
下表给出了WPF布局面板中的通用属性:
属性名称 | 表征意义 |
---|---|
Background | 布局面板背景着色,在响应鼠标事件时,该值非空(含透明) |
Children | 布局面板中存储的条目集合,条目还可以含更多的条目 |
IsItemHost | 布尔值,是否为由ItemsControl生成的UI项的容器 |
HorizontalAlignment | 水平对齐方式,有Center、Left.、Right、Stretch属性值可选 |
VerticalAlignment | 垂直对齐方式,有Center、Left、Right、Stretch属性值可选 |
MinWidth/MinHeight | 最小宽度尺寸/最小高度尺寸,默认单位是像素 |
MaxWidth/MaxHeight | 最大宽度尺寸/最大高度尺寸,默认单位是像素 |
Width/Height | 宽度尺寸/高度尺寸,默认单位是像索 |
Margin | 在元素周围空白尺寸,默认单位是像素 |
WPF布局面板
WPF的布局面板实现基本的布局,布局面板类型有Canvas
、DockPanel
、StackPanel
、WrapPanel
、Grid
和UniformGrid
。
布局面板的类型及其使用规则
布局面板类型 | 使用规则 |
---|---|
Canvas | 画布。通过Top、Left、Right 和 Bottom 4个属性将子元素定位 |
DockPanel | 停靠面板。让子元素停靠在整个面板的某一条边上,然后拉伸元素以填满全部宽度或高度。 类似于Windows Form编程中控件的Dock属性 |
StackPanel | 堆式面板。子元素按照声明的先后顺序,自上往下或从左往右摆放 |
WrapPanel | 自动折行面板。子元素按照声明的先后顺序,从左往右摆放,摆满一行后,自动折行。 与HTML中的流式布局相似 |
Grid | 网格。通过定义行高和列宽来调整子元素。类似于HTML中的Table. |
UniformGrid | 画布。通过Top、Left、Right 和 Bottom 4个属性将子元素定位 |
小结
本章的第一部分重点介绍了WPF布局原则。但是布局内容远不止这些,当了解更多的控件以后,可以做出个性化的布局。一个好的布局,能让UI根据用户的需求调整屏幕大小,窗口的大小,并根据内容来改变尺寸。在之后的章节中会依次讲到本文所提到的的布局面板并详细讲述。
相关阅读
上一篇:WPF编程基础入门 ——— 第二章 XAML.
下一篇:WPF编程基础入门 ——— 第三章 布局(二)布局面板Canvas.
WPF编程基础入门 ——— 目录导航.