WPF 布局控件

wpf 布局控件有很多,常用的有:Grid, UniformGrid, Border, StackPanel, WrapPanel, DockPanel。

1. Grid

Grid 经常作为控件的 Content 使用,常作为 Windows, UserControl 等 UI 元素的根节点。它用来展示一个 n 行 n 列的排版。

因此就有下面几个常用且重要的属性:

  1. RowDefinitionsColumnDefinitions:行定义、列定义
  2. Grid.RowGrid.Column:子元素位于 Grid 第几行、第几列

1.1 RowDefinitions 和 ColumnDefinitions

RowDefinitions :有个重要属性 Height,它有 3 种值:

  • 常规数值,如100,200,单位是像素,表示该行的实际像素高度。
  • * 值, 如1*,2*,1.5*,表示占比,比如 2 * 就是 1* 的两倍高。
  • "Auto", 表示高度自动伸缩。

ColumnDefinitions :也有个重要属性 Width,也有类似 3 种值:

  • 常规数值,如100,200,单位是像素,表示该列的实际像素宽度。
  • * 值, 如1*,2*,1.5*,表示占比,比如 2 * 就是 1* 的两倍宽。
  • "Auto", 表示宽度自动伸缩。

1.2 Grid.Row 和 Grid.Column

这两个属性,实际上是 RowColumn 属性,为什么要加上 Grid. ,原因是它们是定义在 Grid 类里的 附加属性

它俩是用来标识当前控件位于 Grid 哪行哪列,即:

Grid.Row 设置值: 表示该控件处于父类 Grid 的第几行。
Grid.Column 设置值: 表示该控件处于父类 Grid 的第几列。

例子,

xml 复制代码
 <!-- 创建一个 3 行 3 列 的布局 -->
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="1.5*" />
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>

    <Grid Grid.Row="0" Grid.Column="0" Background="Red" />
    <Grid Grid.Row="0" Grid.Column="1" Background="IndianRed" />
    <Grid Grid.Row="0" Grid.Column="2" Background="OrangeRed" />

    <Grid Grid.Row="1" Grid.Column="0" Background="Green" />
    <Grid Grid.Row="1" Grid.Column="1" Background="GreenYellow" />
    <Grid Grid.Row="1" Grid.Column="2" Background="DarkSlateGray" />

    <Grid Grid.Row="2" Grid.Column="0" Background="Blue" />
    <Grid Grid.Row="2" Grid.Column="1" Background="DodgerBlue" />
    <Grid Grid.Row="2" Grid.Column="2" Background="PowderBlue" />
</Grid>

结果:

为什么只剩 2 行 2 列了?第 1 行和第 3 列哪去了?

因为:第 1 行高度和第 3 列宽度都被设置为了 Auto, Auto 会根据相邻或子元素自动排版,没有子元素时,实际宽高就为0。

给第 1 行任意一列填充实际子元素,第 3 列任意一行填充实际子元素,

xml 复制代码
<Grid Grid.Row="0" Grid.Column="0" Background="Red">
    <TextBlock Height="80" Text="第 1 行,第 1 列" />
</Grid>
<Grid Grid.Row="0" Grid.Column="1" Background="IndianRed" />
<Grid Grid.Row="0" Grid.Column="2" Background="OrangeRed" />

<Grid Grid.Row="1" Grid.Column="0" Background="Green" />
<Grid Grid.Row="1" Grid.Column="1" Background="GreenYellow" />
<Grid Grid.Row="1" Grid.Column="2" Background="DarkSlateGray" />

<Grid Grid.Row="2" Grid.Column="0" Background="Blue" />
<Grid Grid.Row="2" Grid.Column="1" Background="DodgerBlue" />
<Grid Grid.Row="2" Grid.Column="2" Background="PowderBlue">
    <TextBlock Height="80" Text="第 3 行,第 3 列" />
</Grid>

所有行列就都显示了:

2. UniformGrid

一般称作网格布局,因为它以均匀的网格方式排列容器中的子元素,不用再像 Grid 那样手动指定每个元素的行和列,会自动按顺序(从左到右、从上到下)展示。每个子元素占用相同大小的空间。

xml 复制代码
<UniformGrid Columns="2" Rows="2">
    <Grid Background="Red">
        <TextBlock Text="1" FontSize="20" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
    <Grid Background="Brown">
        <TextBlock Text="2" FontSize="20" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
    <Grid Background="DarkGoldenrod">
        <TextBlock Text="3" FontSize="20" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
    <Grid Width="100" Height="100" Background="Green">
        <TextBlock Text="4" FontSize="20" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
</UniformGrid>

3. Border

Border 就是带有边框的区域布局,既然是边框就有边框颜色和边框厚度。

BorderBrush: 边框颜色
BorderThickness: 边框厚度(从左右到依次:左、上、 右、 下 厚度)

xml 复制代码
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <!-- 不带边框 -->
    <Border
        Width="100"
        Height="100"
        Background="DeepPink" />

    <!-- 带边框 -->
    <Border Grid.Column="1"
            Width="100"
        Height="100"
        Background="DeepPink"
        BorderBrush="Black"
        BorderThickness="4" />
</Grid>

4. StackPanel 和 WrapPanel

从名字可以看出,StackPanel 即按照栈的方式排版子元素,WrapPanel 在按照栈方式排版基础上,超出显示范围时可以自动换行或换列。

4.1 StackPanel

StackPanel 演示

横向排列:

xml 复制代码
<StackPanel Orientation="Horizontal">
    <Grid Width="100" Height="40" Background="DeepPink"></Grid>
    <Grid Width="100" Height="40" Background="DarkOrchid"></Grid>
    <Grid Width="100" Height="40" Background="DarkGreen"></Grid>
</StackPanel>

竖向排列:

xml 复制代码
<StackPanel Orientation="Vertical">
    <Grid Width="100" Height="40" Background="DeepPink" />
    <Grid Width="100" Height="40" Background="DarkOrchid" />
    <Grid Width="100" Height="40" Background="DarkGreen" />
</StackPanel>

4.2 WrapPanel

WrapPanel 演示

横向排列:

xml 复制代码
<WrapPanel Orientation="Horizontal">
    <Grid Width="100" Height="40" Background="DeepPink" />
    <Grid Width="100" Height="40" Background="DarkOrchid"/>
    <Grid Width="100" Height="40" Background="DarkGreen"/>
</WrapPanel>

当宽度显示不下时自动换行:

竖向排列:

xml 复制代码
<WrapPanel Orientation="Vertical">
    <Grid Width="100" Height="40" Background="DeepPink"/>
    <Grid Width="100" Height="40" Background="DarkOrchid"/>
    <Grid Width="100" Height="40" Background="DarkGreen"/>
</WrapPanel>

当高度显示不下时,自动换列

5. DockPanel

使用锚点停靠方式在 DockPanel 区域中进行排版。

例如,

xml 复制代码
<DockPanel>
    <Grid DockPanel.Dock="Left" Width="40" Background="DeepPink" />
    <Grid DockPanel.Dock="Top" Height="40" Background="GreenYellow" />
    <Grid DockPanel.Dock="Right" Width="40" Background="DodgerBlue" />
    <Grid DockPanel.Dock="Bottom" Height="40" Background="Coral" />
</DockPanel>

为什么底部 Grid 元素不是在最下面,跑中间去了?

默认情况下,后添加的元素只能使用剩余空间,无论对 DockPanel 的最后一个子元素设置任何停靠值,该子元素都将始终填满剩余的空间。如果不希望最后一个元素填充剩余区域,可以将 DockPanel 属性 LastChildFill设置为 false,还必须为最后一个子元素显式指定停靠方向。

我们可以做个实验,把底部 Grid 高度设置去掉,

xml 复制代码
<Grid DockPanel.Dock="Bottom" Background="Coral" />

就变成了,

最后我们实验一下 LastChildFill 设置

xml 复制代码
<DockPanel LastChildFill="False">
    <Grid DockPanel.Dock="Left" Width="40" Background="DeepPink" />
    <Grid DockPanel.Dock="Top" Height="40" Background="GreenYellow" />
    <Grid DockPanel.Dock="Right" Width="40" Background="DodgerBlue" />
    <Grid DockPanel.Dock="Bottom" Height="40" Background="Coral" />
</DockPanel>
相关推荐
玉面小君3 天前
从 WPF 到 Avalonia 的迁移系列实战篇6:Trigger、MultiTrigger、DataTrigger 的迁移
wpf·avalonia
招风的黑耳4 天前
Java生态圈核心组件深度解析:Spring技术栈与分布式系统实战
java·spring·wpf
lfw20194 天前
WPF 数据绑定模式详解(TwoWay、OneWay、OneTime、OneWayToSource、Default)
wpf
Magnum Lehar4 天前
3d wpf游戏引擎的导入文件功能c++的.h实现
3d·游戏引擎·wpf
FuckPatience5 天前
WPF Telerik.Windows.Controls.Data.PropertyGrid 自定义属性编辑器
wpf
almighty275 天前
C#WPF控制USB摄像头参数:曝光、白平衡等高级设置完全指南
开发语言·c#·wpf·usb相机·参数设置
军训猫猫头5 天前
12.NModbus4在C#上的部署与使用 C#例子 WPF例子
开发语言·c#·wpf
我要打打代码5 天前
在WPF项目中使用阿里图标库iconfont
wpf
拾忆,想起6 天前
Redisson 分布式锁的实现原理
java·开发语言·分布式·后端·性能优化·wpf
weixin_464078076 天前
wpf依赖注入驱动的 MVVM实现(含免费源代码demo)
wpf