WPF常用的容器组件主要有Grid、Canvas、StackPanel、WrapPanel、UniformGrid等几类,每类容器组件的特点如下表描述:
容器名称 | 布局特点 |
Grid | 按行列排列内容,如果没有特别说明行列则内容充满容器,多个内容则重叠充满内容 |
StackPanel | 水平或垂直的放置内容元素 |
WrapPanel | 自动换行的方式放置内容元素 |
DockPanel | 按照Top、left、right等方式布局内容元素,最后一个元素充满可利用的容器空间 |
UniformGrid | 自动根据容器大小,自动采用行列方式排列内容元素 |
Canvas | 在内容元素中设置附加属性Top、Left,根据Top、Left布局内容元素 |
一、Grid布局示例:
grid 不特别指明长、宽时,自动充满父容器,定义了行列属性时,按照行列设置在其内容放置内容元素,示例如下:
<Grid Width="200" Height="100" >
<!--定义了两列-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="100*"/>
</Grid.ColumnDefinitions>
<!--定义了四行-->
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" TextAlignment="Right" Text="用户名:" Name="UserName"/>
<!--第一行第一列-->
<TextBlock Grid.Row="1" Grid.Column="0" TextAlignment="Right" Text="密码:" Name="pass"/>
<TextBlock Grid.Row="2" Grid.Column="0" TextAlignment="Right" Text="确认密码:" Name="repass"/>
<Button Grid.Row="3" Grid.ColumnSpan="2" Height="23" Width="100" Content="确认" Click="Button_Click" Name="btn"/>
<!--Grid.ColumnSpan="2":合并单元格-->
<TextBox Name="TxtBoxName" Grid.Row="0" Grid.Column="1" Text="" />
<!--第一行第二列-->
<PasswordBox Name="pass1" Grid.Row="1" Grid.Column="1"/>
<!--密码框-->
<PasswordBox Name="pass2" Grid.Row="2" Grid.Column="1" />
</Grid>
当然也可以不设置行列属性,默认情况下,内容元素充满grid容器;示例如下:
<Grid>
<Border Background="Blue" Opacity="0.7" Panel.ZIndex="2"/>
<Border Background="Red" Opacity="0.45" Panel.ZIndex="1"/>
</Grid>
默认情况下,在容器中最后定义的内容元素覆盖前面的内容元素,如果设置了Panel.ZIndex属性按照ZIndex属性来重叠布局
二、StackPanel布局
放置其中的元素,按照StackPanel的属性Orientation确定采用横排布局还是纵向布局;示例如下 :
<StackPanel Orientation="Vertical">
<Label HorizontalAlignment="Center">A button click</Label>
<Button HorizontalAlignment="Left">Button 1</Button>
<Button HorizontalAlignment="Right">Button 2</Button>
<Button>Button 3</Button>
<Button>Button 4</Button>
</StackPanel>
纵向布局内容要素,界面如图示意:
三、Canvas布局
Canvas主要用于作图使用,提供了ClipToBounds对超出容器的内容进行裁剪,当ClipToBounds=true时,自动裁剪超过容器的内容
<Canvas Margin="0,0,0,0" Background="White">
<Rectangle Fill="Blue" Stroke="Azure" Width="250" Height="200" Canvas.Left="210" Canvas.Top="101"/>
<Ellipse Fill="Red" Stroke="Green" Width="250" Height="100" Panel.ZIndex="1"
Canvas.Left="65" Canvas.Top="45"/>
</Canvas>
内容元素通过Canvas.Left、Canvas.Top附加属性设置在容器中的实际位置,通过Panel.Zindex附加属性设置显示上的重叠属性
四、DockPanel布局
DockPanel采用停靠的方式设置其内容元素的布局,最后一个元素默认情况充满剩下容器空间,示例如下:
<DockPanel>
<Button DockPanel.Dock="Top" Background="Aqua">1(Top)</Button>
<Button DockPanel.Dock="Left" Background="Green">2(Left)</Button>
<Button DockPanel.Dock="Right" Background="Yellow">3(Right)</Button>
<Button DockPanel.Dock="Bottom" Background="Blue">4(Bottom)</Button>
<Button Background="Orange">5</Button>
</DockPanel>
布局界面如下示意:
五、WrapPanel布局
WrapPanel默认按照从左到右的方式(主要依据FlowDirection)布局内容元素,不满一行后自动换行。示例如下:
<WrapPanel FlowDirection="LeftToRight">
<Button Content="btn1" Width="80" Height="30" Margin="5"/>
<Button Content="btn2" Width="80" Height="30" Margin="5"/>
</WrapPanel>
六、UniformGrid布局
UniformGrid 就是Grid的简化版,每个单元格的大小相同,不需要定义行列集合。每个单元格始终具有相同的大小,每个单元格只能容纳一个控件,将自动按照定义在其内部的元素个数,自动创建行列,并通常保持相同的行列数。
<UniformGrid Rows="2" Columns="2">
<Button>第一个(0,0)</Button>
<Button>第二个(0,1)</Button>
<Button>第三个(1,0)</Button>
<Button Name="btnAddByCode" Click="btnAddByCode_Click">第四个(1,1)</Button>
</UniformGrid>