摘要
WPF布局原则
- 一个窗口中只能包含一个元素
- 屏幕适应程序,不要显示设置的元素(控件)的尺寸,可以设置最小或者最大尺寸
- 不应使用坐标设置元素的位置
- 可以嵌套布局容器
正文
Grid面板
通过Grid.RowDefinitions和Grid.CoulmDefinitions去配置和设置网格的行和列,Grid.Row和Grid.Column设置控件在网格的位置,类似于Web开发的Table表格。
- RowSpan 行合并
- ColumnSpan 列合并
- GridSplitter 分隔窗口
- SharedSizeGroup 共享尺寸组
- ShowGridLines 显示布局线
- UseLayoutRounding获取或设置一个值,该值确定对象及其可视化子树的呈现是否应使用将呈现与整像素对齐的舍入行为。
- SnapsToDevicePixels 获取或设置一个值,该值决定呈现元素期间是否应使用设备特定的像素设置。这是一个依赖项属性。
<Grid ShowGridLines="True" UseLayoutRounding="True">
<!--布局舍入-->
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="50"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<!--比例-->
<ColumnDefinition Width="2*" MinWidth="50"></ColumnDefinition>
<ColumnDefinition Width="4*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Content="B1" Grid.Row="0" Grid.Column="2" Margin="10">
<!--跨列-->
</Button>
<Button Content="B2" Grid.Row="1" Grid.Column="3" Margin="10"></Button>
<Button Content="B3" Grid.Column="0" Margin="10" Grid.RowSpan="2" />
<GridSplitter Grid.Column="1" HorizontalAlignment="Center" Width="5" Grid.RowSpan="2" VerticalAlignment="Stretch"/>
<!--跨行-->
</Grid>
SharedSizeGroup
<Grid ShowGridLines="True" IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="TextGroup1"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition SharedSizeGroup="G2" ></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Content="不应使用屏幕坐标元素位置,由容器决定" Grid.Column="0"/>
<Label Content="不应使用屏幕坐标元素位置,由容器决定" Grid.Column="2"/>
</Grid>
<Grid Grid.Row="1" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="TextGroup1"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition SharedSizeGroup="G2" ></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Content="由容器决定 " Grid.Column="0"></Label>
<Label Content="不应使用屏幕由容器决定" Grid.Column="2"/>
</Grid>
</Grid>
StackPanel面板
StackPanel主要用于垂直或水平排列元素、在容器的可用尺寸内放置有限个元素,元素的尺寸总和(长/高)不允许超过StackPanel的尺寸, 否则超出的部分不可见。
- Orientation 内容对齐方式
<Grid Margin="10,0,10,0">
<!--左上右下-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="8*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border BorderBrush="DarkBlue" BorderThickness="1,1,1,1" Grid.Column="0" CornerRadius="10" Padding="5">
<StackPanel Orientation="Vertical">
<Label Content="菜单A" BorderBrush="DarkBlue" BorderThickness="0,0,0,1" ></Label>
<Label Content="菜单B" BorderBrush="DarkBlue" BorderThickness="0,0,0,1" ></Label>
<Label Content="菜单C" BorderBrush="DarkBlue" BorderThickness="0,0,0,1" ></Label>
</StackPanel>
</Border>
</Grid>
WrapPanel面板
WrapPanel默认排列方向与StackPanel相反、WrapPanel的Orientation默认为Horizontal。WrapPanel具备StackPanel的功能基础上具备在尺寸变更后自动适应容器的宽高进行换行换列处理。
- WrapPanel布局面板将各个控件从左至右按照行或列的顺序罗列,当长度或高度不够时就会自动调整进行换行,后续排序按照从上至下或从右至左的顺序进行。
- Orientation——根据内容自动换行。当Orientation属性的值设置为 Horizontal:元素是从左向右排列的,然后自上至下自动换行。当Orientation属性的值设置为Vertical:元素是从上向下排列的,然后从左至右自动换行。
- ItemHeight——所有子元素都一致的高度。每个子元素填充高度的方式取决于它的VerticalAlignment属性、Height属性等。任何比ItemHeight高的元素都将被截断。
- ItemWidth——所有子元素都一致的宽度。每个子元素填充高度的方式取决于它的VerticalAlignment属性、Width属性等。任何比ItemWidth高的元素都将被截断。
<Grid>
<WrapPanel Orientation="Horizontal">
<Button Content="Button1" Height="100" VerticalAlignment="Top"/>
<Button Content="Button2" Height="200" />
<Button Content="Button3" VerticalAlignment="Bottom" />
</WrapPanel>
</Grid>
DockPanel面板
默认DockPanel中的元素具备DockPanel.Dock属性, 该属性为枚举具备: Top、Left、Right、Bottom。默认情况下, DockPanel中的元素不添加DockPanel.Dock属性, 则系统则会默认添加 Left。
<Grid>
<DockPanel>
<Button Content="Button1" DockPanel.Dock="Left"/>
<Button Content="Button2" DockPanel.Dock="Right"/>
<Button Content="Button3" DockPanel.Dock="Top"/>
<Button Content="Button4"/>
</DockPanel>
</Grid>
一个对话框
<Grid>
<DockPanel>
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="OK" Margin="10,2,0,2"></Button>
<Button Content="Cancel" Margin="10,2,10,2"></Button>
</StackPanel>
<TextBlock TextWrapping="Wrap" Text="This is a test!" />
</DockPanel>
</Grid>
Canvas面板
可以把Canvas比作一个坐标系,所有的元素通过设置坐标来决定其在坐标系中的位置。这个坐标系的原点并不是在中央。
Inkcanvas 主要用手写笔的输入
EraseByPoint 5 表示當畫筆與筆劃相交時,畫筆會擦掉部分筆劃。
EraseByStroke 6 表示當畫筆與筆劃相交時,畫筆會擦掉整個筆劃。
GestureOnly 2 表示 InkCanvas 只回應筆勢,但不接收筆墨。
Ink 1 表示 InkCanvas 在收到畫筆傳送的資料時顯示筆墨。
InkAndGesture 3 表示 InkCanvas 回應筆勢且接收筆墨。
None 0 表示當畫筆傳送資料至 InkCanvas 時,不採取任何動作。
Select 4 表示畫筆在 InkCanvas 上選取筆劃和項目。
<Canvas>
<Button Content="Button1" Canvas.Left="10" Canvas.Top="10"/>
<Button Content="Button2" Canvas.Right="10" Canvas.Bottom="10"/>
<Button Content="Button" Canvas.Left="179" Canvas.Top="197"/>
<Rectangle Canvas.ZIndex="2" Width="100" Height="100" Canvas.Top="100" Canvas.Left="100" Fill="blue"/>
<Rectangle Canvas.ZIndex="1" Width="100" Height="100" Canvas.Top="150" Canvas.Left="150" Fill="yellow"/>
<Rectangle Canvas.ZIndex="2" Width="100" Height="100" Canvas.Top="200" Canvas.Left="200" Fill="green"/>
</Canvas>
InkCanvas 面板
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<ComboBox Name="editMode" Margin="2" SelectionChanged="editMode_SelectionChanged">
</ComboBox>
</StackPanel>
<InkCanvas EditingMode="Select" Name="cav" Grid.Row="1">
</InkCanvas>
</Grid>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
foreach (var item in Enum.GetValues(typeof(InkCanvasEditingMode)))
{
editMode.Items.Add(item);
}
editMode.SelectedIndex = 0;
cav.EditingMode = (InkCanvasEditingMode)editMode.SelectedValue;
}
private void editMode_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
cav.EditingMode = (InkCanvasEditingMode)editMode.SelectedValue;
}