布局的基本原则:
a. 一个窗口中只能包含一个元素
b . 不应使用坐标设置元素的位置
c. 大多数情况不应显示定义元素尺寸
d. 支持多元素时, 可使用嵌套容器
布局属性:
HorizontalAlignment:用于设置子元素在容器中的水平位置。参数: Center、Left、Right、Stretch
VerticalAlignment:用于设置子元素在容器中的垂直位置。参数: Center、Top、Bottom、Stretch
Margin:用于设置子元素在容器中的边距。
参数: 4个方向的边距(左、上、右、下)
使用: 可以同时设置4个相同边距、也可以单独设置每条边的边距。
Height/Width、MinHeight/MinWidth、MaxHeight/ MaxWidth:
设置元素的基本尺寸、有固定尺寸、最小尺寸、最大尺寸
常用六大基础布局容器:Grid、StackPanel、WrapPanel、DockPanel和UniformGrid
1. Grid网格:可以自定义行和列并通过行列的数量、行高列宽来调整控件的布局,近似HTML代码中的table
Grid为最常用的布局容器, 作为View中的主要组成部分, 负责框架中整体的页面布局。
ShowGridLines: 可以设置行业的边距线的显示。
Grid. RowDefinitions : 可以创建任意行, 进行固定高度与百分比或自适应高度设置。
Grid. ColumnDefinitions: 可以创建任意列, 进行固定宽度与百分或自适应宽度设置。
示例代码:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="2*"/>
<RowDefinition/>
</Grid.RowDefinitions>
</Grid>
2.StackPanel:栈式面板。可将包含的元素在水平或垂直方向排成一条线,当移除一个元素后,后面的元素会自动向前填充空缺(菜单栏经常用到此布局)。
Orientation: 用于设置StackPanel的元素排列方式。默认以垂直的方式布局。
Horizontal为水平布局, Vertical为垂直布局, 分别设置水平和垂直的效果如下:
<StackPanel Orientation="Horizontal">
<Button Width="40" Height="40" Background="Red"/>
<Button Width="40" Height="40" Background="Beige" />
<Button Width="40" Height="40" Background="DarkBlue"/>
<Button Width="40" Height="40" Background="Pink"/>
<Button Width="40" Height="40" Background="DarkGray" />
</StackPanel>
3. WrapPanel:自动折行面板。内部元素在排满一行后能够自动折行,类似于Html中的流式布局。
与StackPanel类似的功能, 相对于WrapPanel , 具有在有限的容器范围内, 可以自动换行, 或者换列处理。具体则取决于WrapPanel的排列方式 (Orientation )。默认水平布局方向(Horizontal)
下图演示当容器的大小不足够呈现有限的元素时, 针对元素会自动换行/列:
<Grid>
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Width="40" Height="40" Background="Red"/>
<Button Width="40" Height="40" Background="Beige" />
<Button Width="40" Height="40" Background="DarkBlue"/>
<Button Width="40" Height="40" Background="Pink"/>
<Button Width="40" Height="40" Background="DarkGray" />
</WrapPanel>
</Grid>
4. DockPanel:泊靠式面板。内部元素可以选择泊靠的方向(上下左右),类似于Winform中设置控件的Dock属性
包含在DockPanel中的元素, 具备DockPanel.Dock的4个枚举值(Top/Left/Right/Bottom) 用于设置元素的锚定位置 .LastChildFill : 容器中的最后一个元素时, 默认该元素填充DockPanel所有空间, 默认值为True .DockPanel中的元素未显示添加DockPanel.Dock属性时, 系统则会默认为DockPanel.Dock=“Left”
<DockPanel LastChildFill="True" Margin="10">
<Button DockPanel.Dock="Top" Width="40" Height="40" Background="Red"/>
<Button DockPanel.Dock="Left“ Width="40" Height="40" Background="Beige" />
<Button DockPanel.Dock="Right" Width="40" Height="40" Background="DarkBlue"/>
<Button DockPanel.Dock="Bottom" Width="40" Height="40" Background="Pink"/>
</DockPanel>
5. UniformGrid:
与Grid不同的是, 该容器具备Columns/Rows 属性, 通过设置该属性, UniformGrid则具备相应的行与列, 但是设置的Columns/Rows不允许单独的进行容器的大小设置。
位于UniformGrid中的子元素, 按输入顺序排列至容器中, 直至填充容器的所有空间。
未显示指定Columns/Rows, UniformGrid则为子元素动态分配Columns/Rows, 换行与换列的基准主要基于UniformGrid的容器大小 ( 宽度与高度) 。
<UniformGrid Margin="10">
<Button Width="40" Height="40" Background="Red"/>
<Button Width="40" Height="40" Background="Beige" />
<Button Width="40" Height="40" Background="DarkBlue"/>
<Button Width="40" Height="40" Background="Pink"/>
<Button Width="40" Height="40" Background="DarkKhaki"/>
<Button Width="40" Height="40" Background="PaleGreen"/>
<Button Width="40" Height="40" Background="OliveDrab"/>
<Button Width="40" Height="40" Background="Beige" />
<Button Width="40" Height="40" Background="Moccasin"/>
</UniformGrid>
<!--显示设置Columns -->
<UniformGrid Margin="10" Columns="4">
<Button Width="40" Height="40" Background="Red"/>
<Button Width="40" Height="40" Background="Beige" />
<Button Width="40" Height="40" Background="DarkBlue"/>
<Button Width="40" Height="40" Background="Pink"/>
<Button Width="40" Height="40" Background="DarkKhaki"/>
<Button Width="40" Height="40" Background="PaleGreen"/>
<Button Width="40" Height="40" Background="OliveDrab"/>
<Button Width="40" Height="40" Background="Beige" />
<Button Width="40" Height="40" Background="Moccasin"/>
</UniformGrid>
6、Canvas:画布。内部元素可以使用以像素为单位的绝对坐标进行定位,类似于Windows Form 的布局方式
Canvas面板是基于坐标的布局容器;Canvas中的子元素的位置是需要显性设定的固定位置,通过Canvas的属性Left/Rigth/Top/Bottom来设置子元素相的位置。可以通过设定Canvas.ZIndex属性值或Panel.ZIndex来调整元素的重叠顺序,值越大的越靠前
<Window x:Class="WPF_Code.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Canvas>
<Ellipse Fill="Gainsboro" Canvas.Left="25" Canvas.Top="25" Width="200" Height="200" />
<Rectangle Canvas.ZIndex="1" Fill="LightBlue" Canvas.Left="25" Canvas.Top="25" Width="50" Height="50" />
<Rectangle Panel.ZIndex="2" Fill="LightCoral" Canvas.Left="50" Canvas.Top="50" Width="50" Height="50" />
<Rectangle Panel.ZIndex="3" Fill="LightCyan" Canvas.Left="75" Canvas.Top="75" Width="50" Height="50" />
</Canvas>
</Window>
总结:
掌握最为常用的最外层布局容器 Grid , StackPanel则为有限的空间内垂直或水平分布元素。
WrapPanel 相对于StackPanel 其自适应空间, 可进行自动 ( 换行/换列)处理, 适用于自适应布局及元素的个数不固定的情况。
DockPanel 具备4个方向的锚定功能, 可适应灵活的非固定的页面布局