WPF中的布局原则
- 不应显示设置元素的尺寸,设置最大,最小尺寸来控制控件的尺寸范围
- 不使用屏幕坐标指定元素的位置,元素之间的空白可以使用Margin属性
- 布局容器和他们的子元素“共享可以使用的控件”
-
布局过程
测量阶段:遍历所有子元素,并询问他们所期望的尺寸
- 排列阶段:在合适的位置放置子元素
布局容器
- 布局容器派生与Panel类,该类提供了三个公用属性:
- BackGroud 主要设置面板背景色;要接收鼠标事件,则属性值非空;
- Children 存储的条目集合
- IsItemHost 显示与一个ItemsControl控件相关联的项
- Margin属性,类似html中的边距,它的赋值时 左,上,右,下 ,且相邻边距会进行叠加
- Padding属性,类似html中的边距,它的赋值时 左,上,右,下 ,一般用于有Content属性的控件
核心布局的面板 | 名称 | 效果 | 用途 | | —- | —- | —- | | StackPanel | 在一个水平或垂直堆栈中放置元素 | 通常用于小的布局区域 | | WrapPanel | 在可换行的行中放置元素 | 类似Html中的流似布局,当排满一行后能够自动折行 | | DockPannel | 根据容器的整个边界调整元素,泊靠面板 | 主要用于大体的界面布局时,其中最后一个元素会自动填充剩余的空间。 | | Grid | 根据行列进行排列的元素 | 最经常用到的布局元素,也更灵活 | | UniformGrid | 强制单元格的元素具有相同的尺寸 |
| | Canvas | 使用固定的坐标,进行绝对定位的元素 画布 | 类似Windows窗体,不适合尺寸可变的元素 |
StacPanel布局容器
StackPanel 会自动铺满他所在的容器,当一个垂直对齐的StackPanel ,其字元素中的VerticalAlignment不会起作用的。 | 属性名称 | 可选值 | 用途 | | —- | —- | —- | | Orientation | Horizontal:水平布局
Vertical:垂直布局 | 控制pannel容器中控件的布局方式 | | HorizontalAlignment | Center/Left/Right/Strectch
Strectch[默认值] 延申铺满 | 当水平方向上有额外空间时,决定在布局容器中如何定位 | | VerticalAlignment | Center/Bottom/Top/Strectch
Strectch[默认值] 延申铺满 | 当垂直方向上有额外空间时,决定在布局容器中如何定位 | ||
|
|
Border控件
- 非布局控件,但是经常与布局容器搭配使用
他是一个装饰元素,类似的装饰元素:ListBoxChrome,ButtonChrome元素 | 属性名称 | 可选值 | 用途 | | —- | —- | —- | | BackGround | 背景布局 |
| | BorderBrush
BorderThickness | 设置边框的颜色和厚度 || | CornerRadius | 使用圆角 |
| | Padding | 边框与内部之间添加的空间 |
|
WrapPanel面板
- 主要用于控制部分窗口的布局
- 当高度或者宽度不够时,会自动掉落到下一行或下一列
- 通过属性Orientation ,来排列相关的元素
DockPanel布局控件
- 顺着一条外边缘来拉伸所包含的控件
- 通过Dock属性来配置相关的数据
- 设置LasChildFill为true 最后一个元素占满剩余的所有空间。
<DockPanel LastChildFill="True">
<DockPanel.Resources>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="Red"></Setter>
<Setter Property="BorderThickness" Value="1"></Setter>
</Style>
<Style TargetType="Label">
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
<Setter Property="VerticalAlignment" Value="Center"></Setter>
</Style>
</DockPanel.Resources>
<Border Background="SkyBlue" DockPanel.Dock="Top" Height="50">
<Label Content="顶部" HorizontalAlignment="Center" VerticalAlignment="Center"></Label>
</Border>
<Border Background="SkyBlue" DockPanel.Dock="Left" Width="200">
<Label Content="左边"></Label>
</Border>
<Border Background="SkyBlue" DockPanel.Dock="Bottom" Height="50">
<Label Content="右边"></Label>
</Border>
<Border Background="Yellow">
<Label Content="居中"></Label>
</Border>
</DockPanel>
Grid布局控件
- 可以对控件进行精细的布局处理
- 通过设置RowDefinitions 和 ColumnDefinition 可以设置Grid为几行几列的表格
- 行列的尺寸调整包括:固定尺寸,自动适应(Auto), 按比例(1*)
- UseLayoutRounding 使用布局舍入,使边界模糊变的清晰【我也没弄懂】
- 跨行,跨列 请使用RowSpan,ColunmSpan来设置
- GridSpliter用来分割单元格,且允许被拖动,动态调整单元格大小
- GridSpliter 必须放在单元格中,可以通过设置RowSpan ColumSpan来进行分割
- 横向和纵向的Spliter需要分别设置 HorizontalAlignment=Stretch width=,VerticalAlignment=Stretch,height 这样Spliter才会显示出来
- 可以设置ResizeDirection,ResizeBehavior 来决定分割的行为
示例代码如下:
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="5"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="5"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border Background="DarkBlue"></Border>
<Border Background="Red" Grid.Row="0" Grid.Column="2"></Border>
<GridSplitter Grid.Row="0" Grid.Column="1" Grid.RowSpan="3" Width="5"
ResizeBehavior="PreviousAndNext"
ResizeDirection="Columns"
Background="SkyBlue"
VerticalAlignment="Stretch">
</GridSplitter>
<GridSplitter Grid.ColumnSpan="3" Grid.Row="1" Grid.Column="0" Height="5"
HorizontalAlignment="Stretch"
Background="Black">
</GridSplitter>
<Border Background="Yellow" Grid.Row="2" Grid.Column="0"></Border>
<Border Background="LightBlue" Grid.Row="2" Grid.Column="2"></Border>
</Grid>
- 共享尺寸组
- 需要在共享的容器里面添加属性 Grid.IsSharedSizeScope=”True”
- 在设置相同的列名中设置 SharedSizeGroup=”分组名称”,即可达到共享尺寸组的效果
<Grid ShowGridLines="False" Grid.IsSharedSizeScope="True">
<Grid Grid.Row="3" Grid.ColumnSpan="3" Grid.Column="0"
Background="LightGoldenrodYellow"
ShowGridLines="True" >
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="TextLable" Width="Auto"/>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="我是一个唱个歌过过过过过过过Label"></Label>
<Label Grid.Column="1" Content="我是一Label"></Label>
<Label Grid.Column="2" Content="我是一个唱个歌过过"></Label>
</Grid>
<Grid Grid.Row="4" Grid.ColumnSpan="3" Grid.Column="0" Background="MediumPurple"
ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" SharedSizeGroup="TextLable"/>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="我是一Label"></Label>
<Label Grid.Column="1" Content="我是一个唱个歌过过"></Label>
</Grid>
</Grid>
UniformGrid布局
- 比较特殊的网格控件,通过设置Rows,Colums来设置网格,每个网格的大小一致
- 非常适合用于监控显示的时候
<ItemsControl ItemsSource="{Binding Path=DataContext,ElementName=wind}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="2" Columns="2">
</UniformGrid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Background="SkyBlue" Margin="5">
<TextBlock Text="{Binding Name,StringFormat=姓名:{0}}"></TextBlock>
<TextBlock Text="{Binding Age,StringFormat=年龄:{0}}"></TextBlock>
<TextBlock Text="{Binding Age,StringFormat=电话:{0}}"></TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Canvas布局容器
- 使用绝对定位(坐标系)来布局容器
- 提供Left,Right,Top ,Bottom 来定位元素,元素不会随容器的变化而变化
- 当元素有重叠时,通过设置ZIndex来设置前后关系
<Canvas>
<Button Content="上左(10,20)" Canvas.Left="10" Canvas.Top="10" Canvas.ZIndex="1"/>
<Button Content="上右(10,20)" Canvas.Right="10" Canvas.Top="20"></Button>
<Button Content="右下(10,20)" Canvas.Right="10" Canvas.Bottom="20"></Button>
<Button Height="100" Width="100" Content="左上(50,100)" Canvas.Left="50" Canvas.Top="20"/>
</Canvas>