本文最后更新于 2025年6月10日 晚上
                  
                
              
            
            
              
                
                前言
先说一下这一系列的文章是笔记而不是教程,毕竟我也是刚刚接触这一方面的知识,写这些的目的一是为了加强我对相关知识的巩固,二就是方便以后进行查阅,这次的WPF我是根据https://www.wpfsoft.com/introduction 这个网站进行学习的,我也在网上找了一下相关的视频资料发现大部分都比较老了或是断更了,OK,接下来进入正文
布局
GRID 布局
在WPF中的 grid 布局其实和前端的 grid 布局差不多,都是将一块空间按照行和列的方式进行分割,然后再指定子元素的所在位置,在 WPF 中的布局需要写在xaml文件中,在 VS 2022 所创建的 WPF 项目中默认就使用了 grid 布局,在 window 标签下只可以有一个子元素,一般就是布局元素,只需要在 window 标签写便可以实现 grid 布局
基础用法
但是这样所添加的子元素默认会占满 Grid 元素的全空间,可以通过ZIndex调整它们的显示顺序,而要解决这种情况我们就需要定义行和列,在 WPF 中我们通过如下代码定义行和列
1 2 3 4 5 6 7 8 9 10 11 12
   | <Grid ShowGridLines="True">     <Grid.RowDefinitions>         <RowDefinition></RowDefinition>         <RowDefinition></RowDefinition>         <RowDefinition></RowDefinition>     </Grid.RowDefinitions>     <Grid.ColumnDefinitions>         <ColumnDefinition></ColumnDefinition>         <ColumnDefinition></ColumnDefinition>         <ColumnDefinition></ColumnDefinition>     </Grid.ColumnDefinitions> </Grid>
 
  | 
 
其中的ShowGridLines="True"用于显示分割线,而<Grid.RowDefinitions>和<Grid.ColumnDefinitions>分别用来定义行数和列数,向其中添加几个子元素便是添加几行或是几列,上面的代码便是定义了一个 3 行 3 列的 Grid 布局元素
在其它元素中我们可以通过Grid.Column 和Grid.Row属性来指定它们所在的行和列,行的顺序是从上到下,从 0 开始,列则是从左往右,也是从 0 开始,如下代码便是往 Grid 布局中添加了 9 个按钮
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
   | <Window x:Class="WpfApp1.Window1"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"         xmlns:local="clr-namespace:WpfApp1"         mc:Ignorable="d"         Title="Window1" Height="450" Width="800">     <Grid ShowGridLines="True">         <Grid.RowDefinitions>             <RowDefinition></RowDefinition>             <RowDefinition></RowDefinition>             <RowDefinition></RowDefinition>         </Grid.RowDefinitions>         <Grid.ColumnDefinitions>             <ColumnDefinition></ColumnDefinition>             <ColumnDefinition></ColumnDefinition>             <ColumnDefinition></ColumnDefinition>         </Grid.ColumnDefinitions>         <Button Grid.Column="0" Grid.Row="0" FontSize="48">按钮1</Button>         <Button Grid.Column="1" Grid.Row="0" FontSize="48">按钮2</Button>         <Button Grid.Column="2" Grid.Row="0" FontSize="48">按钮3</Button>         <Button Grid.Column="0" Grid.Row="1" FontSize="48">按钮4</Button>         <Button Grid.Column="1" Grid.Row="1" FontSize="48">按钮5</Button>         <Button Grid.Column="2" Grid.Row="1" FontSize="48">按钮6</Button>         <Button Grid.Column="0" Grid.Row="2" FontSize="48">按钮7</Button>         <Button Grid.Column="1" Grid.Row="2" FontSize="48">按钮8</Button>         <Button Grid.Column="2" Grid.Row="2" FontSize="48">按钮9</Button>     </Grid> </Window>
 
 
  | 
 
显示效果如图所示

限制宽度
如果我们需要限制某一列的宽度,则可以在定义这一列时添加Width属性
1
   | <ColumnDefinition Width="240"></ColumnDefinition>
 
  | 
 
需要注意的是WPF是像素无关的,也就是在定义宽度时不需要带px这个单位,效果如图

跨行列
如果需要实现跨列或者跨行的效果,可以添加Grid.ColumnSpan或Grid.RowSpan属性,它的值便是所需要跨的行或列数,示例代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | <Grid>     <Grid.RowDefinitions>         <RowDefinition></RowDefinition>         <RowDefinition></RowDefinition>         <RowDefinition></RowDefinition>     </Grid.RowDefinitions>     <Grid.ColumnDefinitions>         <ColumnDefinition></ColumnDefinition>         <ColumnDefinition></ColumnDefinition>         <ColumnDefinition></ColumnDefinition>     </Grid.ColumnDefinitions>     <Button Grid.Column="0" Grid.Row="0" Margin="10" FontSize="48">这是区块一</Button>     <Button Grid.Column="1" Grid.Row="0" Margin="10" FontSize="48">这是区块二</Button>     <Button Grid.Column="0" Grid.Row="1" Margin="10" FontSize="48">这是区块三</Button>     <Button Grid.Column="1" Grid.Row="1" Margin="10" FontSize="48">这是区块四</Button>     <Button Grid.Row="2" Grid.ColumnSpan="3" FontSize="48" Margin="10">这是区块5</Button>     <Button Grid.Column="2" Grid.RowSpan="2" Margin="10" FontSize="48">这是区块6</Button> </Grid>
 
 
  | 
 
运行效果如图所示,其中 Margin 属性用于设置边距,FontSize用于设置字体大小

StackPanel 布局
stackpanel 布局通过设置Orientation属性来实现水平(Horizontal)或垂直布局(Vertical),默认为 Vertical 即垂直布局
垂直布局
在垂直布局时高度根据内容自适应,宽度则默认占满父元素的宽度

同时我们可以为元素设置HorizontalAlignment来设置它的布局居中,居左或居右,此时它的宽度也会重新计算改为自适应内容宽度
1 2 3 4 5 6 7 8
   | <StackPanel Orientation="Vertical">     <Button Content="按钮" HorizontalAlignment="Left"/>     <Button Content="按钮" HorizontalAlignment="Center"/>     <Button Content="按钮" HorizontalAlignment="Right"/>     <Button Content="按钮" HorizontalAlignment="Stretch"/>     <Button Content="按钮"/>     <Button Content="按钮"/> </StackPanel>
 
  | 
 

水平布局
在水平布局时它的高度默认占满父元素的高度,而宽度根据内容自适应
1 2 3 4 5 6 7 8
   | <StackPanel Orientation="Horizontal">     <Button Content="按钮"/>     <Button Content="按钮"/>     <Button Content="按钮"/>     <Button Content="按钮"/>     <Button Content="按钮"/>     <Button Content="按钮"/> </StackPanel>
 
  | 
 

此时可以设置VerticalAlignment属性使其居上,居中或居下
1 2 3 4 5 6 7 8
   | <StackPanel Orientation="Horizontal">     <Button Content="按钮" VerticalAlignment="Top"/>     <Button Content="按钮" VerticalAlignment="Center"/>     <Button Content="按钮" VerticalAlignment="Bottom"/>     <Button Content="按钮" VerticalAlignment="Stretch"/>     <Button Content="按钮"/>     <Button Content="按钮"/> </StackPanel>
 
  | 
 

WrapPanel 布局
WrapPanel 布局可以实现自动换行效果,即第一行显示不下则自动到第二行,它有以下几个常用的属性
ItemWidth 和 ItemHeight
这两个属性用于指定子元素的宽高
Orientation
和 stackpanel 差不多指定垂直或是水平布局
代码演示
1 2 3 4 5 6 7 8 9 10
   | <WrapPanel Orientation="Vertical" ItemHeight="74" ItemWidth="74">     <Button Margin="10"></Button>     <Button Margin="10"></Button>     <Button Margin="10"></Button>     <Button Margin="10"></Button>     <Button Margin="10"></Button>     <Button Margin="10"></Button>     <Button Margin="10"></Button>     <Button Margin="10"></Button> </WrapPanel>
 
  | 
 

DockPanel 布局
顾名思义,这个布局可以指定子元素停靠在哪个方向,通过对子元素设定DockPanel.Dock属性来实现
代码演示
1 2 3 4 5 6 7
   | <DockPanel>     <Button DockPanel.Dock="Bottom">底部</Button>     <Button DockPanel.Dock="Left">左侧</Button>     <Button DockPanel.Dock="Right"> 右侧</Button>     <Button DockPanel.Dock="Top">上侧</Button>     <Button>内容</Button> </DockPanel>
 
  | 
 

默认来说 DockPanel 的最后一个元素会占满剩余空间,可以设置LastChildFill="False"来取消这一设定
Canvas 布局
Canvas 布局即绝对布局,可以对子元素设定对于上下左右的距离,具体看代码演示
1 2 3 4 5 6
   | <Canvas>     <Button Canvas.Left="50" Canvas.Top="30">内容</Button>     <Button Canvas.Bottom="90" Canvas.Right="10">内容</Button>     <Button Canvas.Top="100" Canvas.Right="0">内容</Button>     <Button Canvas.Bottom="0" Canvas.Left="90">内容</Button> </Canvas>
 
  | 
 

当一个元素同时设置左右或上下时,优先级是左大于右,上大于下(仅是个人测试结果)
THE END
以上就是我目前所学习的几种常见的布局方式