一、布局过程
WPF 布局包括两个阶段:一个测量阶段和排列阶段
- 在测量阶段,容器遍历所有子元素,并询问子元素它们所期望的尺寸。
- 在排列阶段,容器在合适的位置放置子元素。(每个元素都被其父元素告知它自己的尺寸是多少以设定尺寸和位置)
这两个阶段让父和子元素能够协商需要多少空间。
3个尺寸被协商:
1)可用尺寸: 用于测量阶段的初始约束。(父元素愿意给子元素的最大空间)
2)期望尺寸: 子控件向想要的尺寸,
3)实际尺寸: 父元素分配给子元素的最终尺寸。
Measure、MeasureCore、Arrange 和 ArrangeCore 实现了布局的两个阶段。
Visibility 来控制子对象如何参与进布局:
Visible(显示): 它们将被显示出来并将占用布局控件中的某个空间。
Hidden(隐藏): 不显示,但占用布局控件中的空间。
Collapsed(折叠): 既不显示也占用布局控件中的空间。
注意:布局容器不能提供任何滚动支持。
1)槽(Slot)模型
Margin、Padding、HorizontalAlignment、VerticalAlignment
2)FlowDirection
FlowDirection 是 FrameworkElement (以及其他一些类)的属性,它可以改变元素的内部流的方向。
作用: 用来处理面板子元素的布局问题,但它也可以应用于 那些内容在子控件中对齐的情况。
有两种值:
LeftToRight(FrameworkElement 的默认值):从左向右
RightToLeft:从右向左
3)变换
ReaderTransform 和 LayoutTransform
2D变换类,改变元素的尺寸和位置。
LayoutTransform,它在对元素布局以前被应用。
RenderTransform(继承自 UIElement),它在布局结束后被应用(但在元素被渲染前)。
点击跳转到 文章“WPF 动态变换
两者变换应用区别:
LayoutTransform 没有原点的概念,因为被变换元素的定位是由父面板规则完全控制的。
RenderTransformOrigin 可以被设置为一个 System.Windows.Point ,默认值是 (0,0)。
RenderTransform 5个常见的原点:
RotateTransform
根据3个浮点类型属性的值来旋转元素:
- Angle:旋转角度,单位为度数。
- CenterX:旋转的水平中心。
- CenterY:旋转的垂直中心。
注意:CenterX 和 CenterY 只有当 RotateTransform 被应用为一个 RenderTransform 时才有用,因为如果被应用为 LayoutTransforms 这个位置仍然由父面板决定。
二、布局容器
Panel 类的共有属性
名称 | 说明 |
---|---|
Background | 该属性是用于为面板背景着色的画刷。如果想接收鼠标事件,就必须将该属性设置为非空值。 |
Children | 该属性是在面板中存储的条目集合。这是第一级条目——换句话说,这些条目自身也可以包含更多的条目 |
IsItemsHost | 该属性是一个布尔值,如果面板用于显示与ItemsControl控件关联的项(例如,TreeView 控件中的节点或列表框中的列表项),该属性值为 true。在大多数情况下,甚至不需要知道列表控件使用后台面板来管理它所包含的条目的布局。但如果希望创建自定义的列表,以不同方式放置子元素(例如,以平埔方式显示图像的 ListBox 控件),该细节就变得很重要了。 |
StackPanel | 在水平或垂直的堆栈中放置元素。这个布局容器通常于更大、更复杂窗口中的一些小区域 |
WrapPanel | 在一系列可换行的行中放置元素。在水平方向上,WrapPanel 面板从左向右放置条目,然后在随后的行中放置元素。在垂直方向上,WrapPanel 面板在自上而下的列中放置元素,并使用附加的列放置剩余的条目 |
DockPanel | 根据容器的整个边界调整元素 |
Grid | 根据不可见的表格在行和列中排列元素,这是最灵活,最常用的容器之一 |
UniformGrid | 在不可见但是强制所有单元格具有相同尺寸的表中放置元素,这个布局容器不常用 |
Canvas | 使用固定坐标绝对定位元素。这个布局容器与传统 Windows 窗体应用程序最相似,但没有提供锚定或停靠功能。因此,对于尺寸可变的窗口,该布局容器不是合适的选择。 |
其他面板:
名称 | 说明 |
---|---|
TabPanel | 在TabPanel 面板中包含多个选项卡 |
ToolbarPanel | 工具栏中的多个按钮 |
ToolbarOverflowPanel | Toolbar 控件的溢出菜单中的多个命令 |
VirtualizingStackPanel | 数据绑定列表控件使用该面板以大幅度降低开销 |
InkCanvas | 该控件支持处理平板电脑(TabletPC)上的手写笔(stylus)输入(例如,根据选择的模式,InkCanvas 控件支持使用指针绘制范围,以选择屏幕上的元素。也可通过普通计算机和鼠标使用 InkCanvas 控件) |
三、WrapPanel 和 DockPanel 面板
1、WrapPanel 面板
WrapPanel 面板在可能的空间中,以一次一行或一列的方式布置控件。
如果在 WrapPanel 中放入超过其容器宽度的内容时,这些控件被换行显示以形成换行效果.
<WrapPanel Margin="3">
<Button VerticalAlignment="Top">Top Button</Button>
<Button MinHeight="60">Tall Button</Button>
<Button VerticalAlignment="Bottom">Bottom Button</Button>
<Button >Stretched Button</Button>
<Button VerticalAlignment="Center">Centered Button</Button>
</WrapPanel>
2、DockPanel 面板
DockPanel 提供停靠支持,该容器中的子元素可以使用Dock属性来设置要停靠的容器边缘。
LastChildFill属性为true,该设置告诉 DockPanel 面板使最后一个元素占满剩余的所有空间。
<DockPanel LastChildFill="True">
<Button DockPanel.Dock="Top">Top Button</Button>
<Button DockPanel.Dock="Buttom" H>Buttom Button</Button>
<Button DockPanel.Dock="Left" >Left Button</Button>
<Button DockPanel.Dock="Right">Right Button</Button>
<Button>Remaining Space</Button>
</DockPanel>
在顶部停靠多个元素
<DockPanel LastChildFill="True">
<Button DockPanel.Dock="Top">A Stretched Top Button</Button>
<Button DockPanel.Dock="Top" HorizontalAlignment="Center">A Centered Top Button</Button>
<Button DockPanel.Dock="Top" HorizontalAlignment="Left">A Left-Aligned Top Button</Button>
<Button DockPanel.Dock="Buttom">Buttom Button</Button>
<Button DockPanel.Dock="Left">Left Button</Button>
<Button DockPanel.Dock="Right">Right Button</Button>
<Button>Remaining Space</Button>
</DockPanel>