wpf用不同的容器安排布局。每个容器有各自的布局逻辑,有些容器以堆栈方式布局容器。另一些容器在网格中不可见的单元格中排列元素。wpf之前,windows采用基于坐标的布局,使用类似于web的流布局,开发人员能够创建与显示分辨率和窗口大小无关的、在不同显示器上正确缩放的用户界面;窗口内容发生改变时,界面可以自身调整。
一、基础知识
1、布局原则
wpf窗口只能包含单个元素,为了在窗口上放置多个元素。需要在窗口上放置一个容器,然后在这个容器中添加其他元素。这是因为window类继承自ContentControl类。
- 不应显示设定元素(如控件)的尺寸。
- 不应使用屏幕坐标指定元素的位置。
- 布局容器的子元素“共享”可用的空间。
- 可嵌套的布局容器。典型的用户界面使用Grid作为开始。
2、布局过程
(1)测量阶段:容器遍历所有的元素,并询问子元素它们所期望的尺寸。
(2)排列阶段:容器在合适的位置放置子元素。
布局容器不提供任何滚动支持,滚动支持由特定的内容控件 ScrollViewer提供。
3、wpf核心布局面板
参考:https://blog.csdn.net/ceclar123/article/details/9319547
(1) StackPanel
是面板最简单的布局容器之一,该面板简单地单行或单列以堆栈形式放置其子元素。
子元素的布局属性:
<StackPanel Orientation="Vertical" VerticalAlignment="Center" Margin="5,5,5,5" MinHeight="50" MinWidth="100" MaxWidth="600" MaxHeight="300" Height="200" Width="400">
<Button Content="Hello World1" MinWidth="50" MaxWidth="100"></Button>
<Button Content="Hello World2" MinWidth="50" MaxWidth="100"></Button>
<Button Content="Hello World3" MinWidth="50" MaxWidth="100"></Button>
<Button Content="Hello World4" MinWidth="50" MaxWidth="100"></Button>
<Button Content="Hello World5" MinWidth="50" MaxWidth="100"></Button>
<Button Content="Hello World6" MinWidth="50" MaxWidth="100"></Button>
</StackPanel>
不同的布局容器可以为它们的子元素提供附加属性,列如Grid对象的所有子元素可以获得Row和Column属性。
(2)WrapPanel面板
在可能的空间中,以一次一行或一列的布局方式布置控件。与Stackpanel控件类似,WrapPanel也有一个Orientation属性,默认值Horizontal,控件将从左向右进行排列。如果容器的宽度不足以排放所有控件时,将会一个新行从左向右进行排列。
WrapPanel通常用在一些小范围的布局场合,而不是整个窗口的总体布局,比如可以使用WrapPanel来保持控件以一种类似工具条的形式。
<WrapPanel Margin="3">
<Button Name="btn1" Content="按钮1" VerticalAlignment="Top" />
<Button Name="btn2" MaxHeight="60" Content="按钮2" />
<Button Name="btn3" VerticalAlignment="Center">居中按钮</Button>
</WrapPanel>
(3)DockPanel
沿着一条外边缘来拉伸所有包含的控件。Dockpanel容器面板用于拉伸空间以停靠在指定的窗口边缘。
DockPanel 控件提供了附加属性Dock。这是一个Dock枚举类型,可选的值如下,
Left:位于DockPanel左侧的子元素。
Top:位于DockPanel的顶部的子元素。
Right:位于DockPanel右侧的子元素。
Bottom:位于DockPanel底部的子元素。
(4)Grid面板
Grid面板是WPF中功能最强大的布局容器。Grid面板将元素分割到不可见的行列网格中,每个单元格放置一个元素。
Grid.RowDefinitions:用于设置行数量
Grid面板调整行和列的三种设置方式:
- 绝对设置尺度方式:使用设备无关单位准确设置尺寸 如: <ColumnDefinition Width="5"/>
- 自动设置尺度方式:每行和每列的尺度刚好满足需求 如: <ColumnDefinition Width="Auto"/>
- 按比例设置尺度方式:按比例将空间分割到一组行和列中 如:<ColumnDefinition Width="*"/>
设置两行:
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
Grid.ColumnDefinitions用于设置列数量
设置三列:
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
设置两行三列:
ShowGridLines=”True”用于设置程序运行后显示网格线,在测试环境中使用
<Window x:Class="combination.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="396" Width="502">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
</Grid>
</Window>
设置元素在Grid中的位置
使用Grid.Row和Grid.Column的数值设定第几行第几列, Grid.Row=”0” Grid.Column=”0”表示第0行第0列。如图代码展示出的按钮位置。
<Window x:Class="combination.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="396" Width="502">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Content="Button" Grid.Row="0" Grid.Column="0" />
<Button Content="Button" Grid.Row="0" Grid.Column="1"/>
<Button Content="Button" Grid.Row="1" Grid.Column="2"/>
</Grid>
</Window>
分割窗口
在WPF中,分割条由GridSplitter类表示,它是Grid面板的功能之一,使用后用户可以改变行和列的尺寸。
使用原则:
- GridSplitter对象必须放到Grid单元格中。
- GridSplitter对象总是改变整行或整列的尺寸(而非改变单个单元格的尺度)。
- GridSplitter对象很小不易看见,需要将VerticalAlignment 或HorizontalAlignment属性设置为Stretch(使分割条填充满区域的整个高度)
- GridSplitter对齐方式决定了分割条是水平的(用于改变行的尺寸)还是竖直的(用于改变列的尺寸)。对于水平分割条,需要将VerticalAlignment属性设置为Center,以指明拖动分割条改变上面行和下面行的尺寸。分割条是竖直的则相反。
Grid面板中使用分割线GridSplitter:
设置两行四列
<Window x:Class="combination.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="396" Width="502">
<Grid >
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" ></ColumnDefinition>
<ColumnDefinition Width="Auto" ></ColumnDefinition>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="4*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Content="Button" Grid.Row="0" Grid.Column="0" />
<Button Content="Button" Grid.Row="0" Grid.Column="2"/>
<Button Content="Button" Grid.Row="1" Grid.Column="3"/>
<GridSplitter Grid.Column="1" Width="3" Grid.RowSpan="2" VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
</Grid>
</Window>
参考:https://blog.csdn.net/Maybe_ch/article/details/80591637
二、常用组件
1、Viewbox
(1)作用:按特定比例伸缩或按固定窗口大小伸缩
<Viewbox>
<Grid Background="#FFE5E5E5" Margin="0,0,3.6,0" Height="370" VerticalAlignment="Top">
</Grid>
</Viewbox>
当窗口放大和缩小后,grid中的元素会跟着窗口放大和缩小。
(2)TabControl 和TabItem添加选项卡
<TabControl Margin="5,5,10,-9" TabStripPlacement="Top">
<TabItem Header="Range" >
<Grid Background="WhiteSmoke" Margin="0,0,0,14.8" >
</Grid>
</TabItem>
<TabItem Header="Range" >
<Grid Background="WhiteSmoke" Margin="0,0,0,14.8" >
</Grid>
</TabItem>
</TabControl>
效果: