WPF学习笔记1————布局

前言

先说一下这一系列的文章是笔记而不是教程,毕竟我也是刚刚接触这一方面的知识,写这些的目的一是为了加强我对相关知识的巩固,二就是方便以后进行查阅,这次的WPF我是根据https://www.wpfsoft.com/introduction 这个网站进行学习的,我也在网上找了一下相关的视频资料发现大部分都比较老了或是断更了,OK,接下来进入正文

布局

GRID布局

WPF中的grid布局其实和前端的grid布局差不多,都是将一块空间按照行和列的方式进行分割,然后再指定子元素的所在位置,在WPF中的布局需要写在xaml文件中,在VS 2022所创建的WPF项目中默认就使用了grid布局,在window标签下只可以有一个子元素,一般就是布局元素,只需要在window标签写便可以实现grid布局

基础用法

1
2
3
<Grid>
...
</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.ColumnGrid.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>

显示效果如图所示

image-20240705165657369

限制宽度

如果我们需要限制某一列的宽度,则可以在定义这一列时添加Width属性

1
<ColumnDefinition Width="240"></ColumnDefinition>

需要注意的是WPF是像素无关的,也就是在定义宽度时不需要带px这个单位,效果如图

image-20240705170014046

跨行列

如果需要实现跨列或者跨行的效果,可以添加Grid.ColumnSpanGrid.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用于设置字体大小

image-20240705170349166

StackPanel布局

stackpanel布局通过设置Orientation属性来实现水平(Horizontal)或垂直布局(Vertical),默认为Vertical即垂直布局

垂直布局

在垂直布局时高度根据内容自适应,宽度则默认占满父元素的宽度

image-20240705184306498

同时我们可以为元素设置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>

image-20240705184640552

水平布局

在水平布局时它的高度默认占满父元素的高度,而宽度根据内容自适应

1
2
3
4
5
6
7
8
<StackPanel Orientation="Horizontal">
<Button Content="按钮"/>
<Button Content="按钮"/>
<Button Content="按钮"/>
<Button Content="按钮"/>
<Button Content="按钮"/>
<Button Content="按钮"/>
</StackPanel>

image-20240705184123172

此时可以设置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>

image-20240705184854295

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>

image-20240705190335904

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>

image-20240705190904126

默认来说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>

image-20240705191532595

当一个元素同时设置左右或上下时,优先级是左大于右,上大于下(仅是个人测试结果)

THE END

以上就是我目前所学习的几种常见的布局方式