目录
布局
布局容器
所有布局容器都是派生自System.Windows.Control.Panel抽象类的面板。Panel类添加了少量成员,包括三个共有属性。
名称 | 摘要 |
---|---|
Blackground | 该属性用于面板背景着色的画刷。若想接收鼠标事件,就必须设置该属性为非空值 |
Children | 该属性是在面板中存储的条目集合。这是第一级条目——这些条目自身也可以包含更多的条目 |
IsItemsHost | 该属性是一个布尔值,如果面板用于显示与ItemsControl控件关联的项,该属性值为true |
核心布局面板
名称 | 说明 |
---|---|
StackPanel | 在水平或垂直的堆栈中放置元素。这个布局容器通常用于更大、更复杂窗口中的一些小区域 |
WrapPanel | 在一系列可换行的行中放置元素。在水平方向上,WrapPanel面板从左向右放置条目,然后在随后的行中放置元素。在垂直方向上,WrapPanel面板在自上而下的列中放置元素,并使用附加的列放置剩余的条目 |
DockPanel | 根据容器的整个边界调整元素 |
Grid | 根据不可见的表格在行和列中排列元素,这是最灵活、最常用的容器之一 |
UniformGrid | 在不可见但是强制所有单元格具有相同尺寸的表中放置元素,这个布局容器不常用 |
Canvas | 使用固定坐标绝对定位元素。这个布局容器与传统Windows窗体应用程序最相似,但没有提供锚定或停靠功能。因此,对于尺寸可变的窗口,该布局容器不是合适的选择。如果选择的话,需要另外做一些工作。 |
使用StackPanel面板进行简单布局
在Grid里面放入一个StackPanel
<Grid>
<StackPanel>
<Label>A Button Stack</Label>
<Button>Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
<Button>Button 4</Button>
</StackPanel>
</Grid>
默认情况下是垂直分布的布局(Vertical)
当然可以修改为水平分布的,补充属性
<StackPanel Orientation="Horizontal">
然后就会变成(很丑的样子)
布局属性
名称 | 说明 |
---|---|
HorizontalAlignment | 当水平方向上有额外的空间时,该属性决定了子元素在布局容器中如何定位。可选用Center、Left、Right或Stretch等属性值 |
VerticalAlignment | 当垂直方向上有额外的空间时,该属性决定了子元素在布局容器中如何定位。可选用Center、Left、Right或Stretch等属性值 |
Margin | 该属性用于在元素的周围添加一定的空间。Margin属性是System.Windows.Thickness结构的一个实例,该结构具有分别用于顶部、底部、左边和右边添加空间的独立组件 |
MinWidth 和 MinHeight | 这两个属性用于设置元素的最小尺寸。如果一个元素对于其他布局容器来说太大,该元素将被裁剪以适合容器 |
MaxWidth 和 MaxHeight | 这两个属性用于设置元素的最大尺寸。 |
Width 和 Height | 这两个属性用于显式地设置元素尺寸。这一设置会重写为HorizontalAlignment和VerticalAlignment属性设置的Stretch值,但不能超过MinWidth 和 MinHeight、MaxWidth 和 MaxHeight属性设置范围。 |
对齐方式
<StackPanel Orientation="Vertical">
<Label HorizontalAlignment="Center">A Button Stack</Label>
<Button HorizontalAlignment="Left">Button 1</Button>
<Button HorizontalAlignment="Right">Button 2</Button>
<Button HorizontalAlignment="Stretch">Button 3</Button>
<Button>Button 4</Button>
</StackPanel>
效果
Stretch就是默认状态
边距
Margin在上一篇文章写了,就不再写了,放链接
最小尺寸、最大尺寸以及显式地设置尺寸
<StackPanel Orientation="Vertical">
<Label HorizontalAlignment="Center" Margin="3">A Button Stack</Label>
<Button Margin="3" MaxWidth="200" MinWidth="100">Button 1</Button>
<Button Margin="3" MaxWidth="200" MinWidth="100">Button 2</Button>
<Button Margin="3" MaxWidth="200" MinWidth="100">Button 3</Button>
<Button Margin="3" MaxWidth="200" MinWidth="100">Button 4</Button>
</StackPanel>
Border控件
名称 | 说明 |
---|---|
Background | 使用Brush对象设置边框中所有内容后面的背景。可使用固定颜色背景,也可以使用其他更特殊的背景 |
BorderBrush和BorderThickness | 使用Brush对象设置位于Border对象边缘的边框的颜色,并设置边框的宽度。为显示边框,必须设置这两个属性 |
CornerRadius | 该属性可使边框具有雅致的圆角。CornerRadius的值越大,圆角效果就越明显 |
Padding | 该属性在边缘和内部的内容之间添加空间(与此相对,Margin属性在边框之外添加空间) |
轻微圆角效果的简单边框
<Border Margin="5" Padding="5" Background="LightYellow" BorderBrush="SteelBlue" BorderThickness="3,5,3,5" CornerRadius="3" VerticalAlignment="Top">
<StackPanel Orientation="Vertical">
<Label HorizontalAlignment="Center" Margin="3">A Button Stack with a border</Label>
<Button Margin="3" MaxWidth="200" MinWidth="100">One</Button>
<Button Margin="3" MaxWidth="200" MinWidth="100">Two</Button>
<Button Margin="3" MaxWidth="200" MinWidth="100">Three</Button>
<Button Margin="3" MaxWidth="200" MinWidth="100">Four</Button>
</StackPanel>
</Border>
WrapPanel和DockPanel面板
最复杂的布局容器是Grid面板。WrapPanel和DockPanel面板是WPF提供的两个更简单的布局容器。这两个布局容器通过不同的布局行为对StackPanel面板进行补充。
WrapPanel面板
WrapPanel.Orientation属性默认设置为Horizontal,也就是水平布置的。但也可以设置为Vertical,在多个列放置。
默认布置的WrapPanel面板
<WrapPanel Margin="3">
<Button VerticalAlignment="Top">Top Button</Button>
<Button MinHeight="60">Tall Button</Button>
<Button VerticalAlignment="Bottom">Buttom Button</Button>
<Button>Stretch Button</Button>
<Button VerticalAlignment="Center">Centered Button</Button>
</WrapPanel>
拖小一点
第二行的高度保持为最小按钮的高度
DockPanel面板
DockPanel面板是沿着一条外边缘来拉伸所包含的控件。
<DockPanel LastChildFill="True">
<Button DockPanel.Dock="Top">Top Button</Button>
<Button DockPanel.Dock="Bottom">Buttom Button</Button>
<Button DockPanel.Dock="Left">Left Button</Button>
<Button DockPanel.Dock="Right">Right Button</Button>
<Button>Remaining Space</Button>
</DockPanel>
LastChildFill属性设置为true表示用最后一个元素占满剩余空间。如果都是DockPanel.Dock属性值都是Top的话,就按照顺序排下来,可以自己试试。
增加一些其他属性的效果。
<DockPanel LastChildFill="True">
<Button DockPanel.Dock="Top">A Stretched Top Button</Button>
<Button DockPanel.Dock="Top" HorizontalAlignment="Center">A Centered Top Button</Button>
<Button DockPanel.Dock="Top" HorizontalAlignment="Left">A Left Top Button</Button>
<Button DockPanel.Dock="Bottom">Buttom Button</Button>
<Button DockPanel.Dock="Left">Left Button</Button>
<Button DockPanel.Dock="Right">Right Button</Button>
<Button>Remaining Space</Button>
</DockPanel>
嵌套布局容器
下面DockPanel嵌套StackPanel面板
<DockPanel LastChildFill="True">
<StackPanel DockPanel.Dock="Bottom" HorizontalAlignment="Right" Orientation="Horizontal">
<Button Margin="10,10,2,10" Padding="3">OK</Button>
<Button Margin="2,10,10,10" Padding="3">Cancel</Button>
</StackPanel>
<TextBox DockPanel.Dock="Top" Margin="10">This is a test.</TextBox>
</DockPanel>
改变按钮位置到中间
Grid面板
分割面板,两行三列
利用Grid.RowDefinitions和Grid.ColumnDefinitions,其中分别有多少个RowDefinition就有多少行,有多少ColumnDefinition就有多少列
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
</Grid>
往里面填元素的时候利用Grid.Row和Grid.Column来确定位置填充
在上面的基础下在Grid里面加上
<Button Grid.Row="0" Grid.Column="0">按钮(0,0)</Button>
<Button Grid.Row="0" Grid.Column="1">按钮(0,1)</Button>
<Button Grid.Row="1" Grid.Column="1">按钮(1,1)</Button>
<Button Grid.Row="1" Grid.Column="2">按钮(1,2)</Button>
调整行和列
- 绝对设置尺寸方式:直接写出数值。这是最无用的策略,不够灵活,难以适应内容大小和容器大小的改变。
- 自动设置尺寸方式:每行和每列的尺寸刚好满足需要。这是最有用的尺寸设置方式。
- 按比例设置尺寸方式:按比例将空间分割到一组行和列中。
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="2*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
布局舍入
当Grid内像素边界出现模糊问题的时候,可以用UseLayoutRounding="True"来解决。消除所有模糊问题。
跨越行和列
分割窗口
分隔条用GridSplitter类表示,它是Grid面板功能之一。
GridSplitter的使用:
- GridSplitter对象必须放在Grid单元格中,最好是单独留一行或列来放置,将预留的行或列的Height和Width属性设置为Auto,不过也可以和其他的已存在的内容放一起,需要调整边距设置,使它们不重叠。
- GridSplitter对象总是改变整行货整列的尺寸,所以GridSplitter对象要拉伸到整行或整列,而不是限制在一个单元格里面。
- GridSplitter对象很小不易看见,所以要设置最小尺寸比较好。
- GridSplitter对齐方式决定了分割线是水平还是竖直的。
Grid嵌套Grid,每个Grid可以有自己的GridSplitter。
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" Margin="3">Top Left</Button>
<Button Grid.Row="1" Margin="3">Buttom Right</Button>
</Grid>
<GridSplitter Grid.Column="1" Width="3" HorizontalAlignment="Center" VerticalAlignment="Stretch" ShowsPreview="False"></GridSplitter>
<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" Margin="3">Top Right</Button>
<Button Grid.Row="2" Margin="3">Button Right</Button>
<GridSplitter Grid.Row="1" Height="3" VerticalAlignment="Center" HorizontalAlignment="Stretch" ShowsPreview="False"></GridSplitter>
</Grid>
</Grid>
共享尺寸组
<Grid Grid.IsSharedSizeScope="True" Margin="3">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="3" Background="LightYellow" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="TextLabel"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Margin="5">A very long bit of text</Label>
<!-- <GridSplitter Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Center" Width="10"></GridSplitter> -->
<Label Grid.Column="1" Margin="5">More text</Label>
<TextBox Grid.Column="2" Margin="5">A text box</TextBox>
</Grid>
<Label Grid.Row="1" >Some text in between the two grids...</Label>
<Grid Grid.Row="2" Margin="3" Background="LightYellow" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="TextLabel"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Margin="5">Short</Label>
<TextBox Grid.Column="1" Margin="5">A text box</TextBox>
</Grid>
</Grid>
为了共享一个组,需要在包含具有共享列的Grid对象容器中,在包含Grid对象前明确地将Grid.IsSharedSizeScope属性设置为true。
UniformGrid面板
有一种不遵循的网格,不需要预先定义列行。
<UniformGrid Rows="2" Columns="2">
<Button>Top Left</Button>
<Button>Top Right</Button>
<Button>Bottom Left</Button>
<Button>Bottom Right</Button>
</UniformGrid>
使用Canvas面板进行基于坐标的布局
<Canvas>
<Button Canvas.Left="10" Canvas.Top="10">(10,10)</Button>
<Button Canvas.Left="120" Canvas.Top="30">(120,30)</Button>
<Button Canvas.Left="60" Canvas.Top="80" Width="50" Height="50">(60,80)</Button>
<Button Canvas.Left="70" Canvas.Top="120" Width="100" Height="50">(70,120)</Button>
</Canvas>
用Canvas,无论怎么移动窗口的大小,里面的控件大小不变,与左上角的位置也不变,
Z顺序
如果Canvas面板中有多个相互重叠的元素,可以通过设置Canvas.ZIndex附加属性来控制它们的层叠方式。具有更高的ZIndex值的元素显示在上面。如果元素具有相同的ZIndex值,就按它们在Canvas.Children集合中的顺序进行显示。
InkCanvas元素
InkCanvas元素主要目的是用于接收手写笔输入。
布局示例
列设置
<Grid Margin="3,3,10,3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Margin="3" VerticalAlignment="Center">Home:</Label>
<TextBox Grid.Row="0" Grid.Column="1" Margin="3" Height="auto" VerticalAlignment="Center">c:</TextBox>
<Button Grid.Row="0" Grid.Column="2" Margin="3" Padding="2">Browse</Button>
<Label Grid.Row="1" Grid.Column="0" Margin="3" VerticalAlignment="Center">Network:</Label>
<TextBox Grid.Row="1" Grid.Column="1" Margin="3" Height="auto" VerticalAlignment="Center">e:Shared</TextBox>
<Button Grid.Row="1" Grid.Column="2" Margin="3" Padding="2">Browse</Button>
<Label Grid.Row="2" Grid.Column="0" Margin="3" VerticalAlignment="Center">Web:</Label>
<TextBox Grid.Row="2" Grid.Column="1" Margin="3" Height="auto" VerticalAlignment="Center">c:</TextBox>
<Button Grid.Row="2" Grid.Column="2" Margin="3" Padding="2">Browse</Button>
<Label Grid.Row="3" Grid.Column="0" Margin="3" VerticalAlignment="Center">Secondary:</Label>
<TextBox Grid.Row="3" Grid.Column="1" Margin="3" Height="auto" VerticalAlignment="Center">c:</TextBox>
<Button Grid.Row="3" Grid.Column="2" Margin="3" Padding="2">Browse</Button>
</Grid>