《深入浅出WPF》5.0 控件与布局
5.1控件
控件:能够显示数据,并且响应用户操作的UI元素。
控件分类:
- 布局控件:容纳其他控件或其他布局控件,用于在UI上组织和排列控件,Grid、Stackpanel、DockPanel等,他们拥有共同的父类Panel。
- 内容控件:只能容纳一个其他控件或布局控件作为他的内容。如Window、Button等,他们的共同父类是ContentControl。
- 带标题内容控件:相当于内容控件,但是可以添加一个标题。如:GroupBox、TabItem等。共同的父类是HeaderContentControl
- 条目控件:可以显示一列数据。如Listbox、Combox等。
- 带标题条目控件:相当于一个条目控件加上一个标题显示区。如TreeViewTiem、MenuItem等。共同基类HeaderItemsControl
- 特殊内容控件:如TextBox容纳字符串、TextBlock容纳可自由控制格式的文本、Image容纳图片类型数据
5.2 WPF的内容模型
名称 | 注释 |
---|---|
ContentControl | 单一内容控件 |
HeaderedControl | 带标题的单一内容控件 |
ItemsControl | 以条目集合为内容的控件 |
HeadredItemsControl | 带标题的以条目集合为内容的控件 |
Decorator | 控件装饰元素 |
Panel | 面板类元素 |
Adorner | 文字点缀元素 |
Flow Text | 流式文本元素 |
Textbox | 文本输入框 |
TextBlock | 静态文字 |
Shape | 图形元素 |
控件的三种书写方式:
<Button Content="OK"/>
<Button>
<Button.Content>
<sys:String>OK</sys:String>
</Button.Content>
</Button>
<Button>
<sys:String>OK</sys:String>
</Button>
5.3 各种内容模型详解
5.3.1 ContentControl
特点:派生自ContentControl类,都是控件,内容属性名称为Content,只能由单一元素充当内容。
单一元素充当内容正确示例:
<Button>
<TextBox Text="Hello"/>
</Button>
单一元素充当内容错误示例:会导致编译不通过
<Button>
<TextBox Text="Hello"/>
<TextBox Text="Hello1"/>
</Button>
修正:
<Button>
<StackPanel>
<TextBox Text="Hello"/>
<TextBox Text="Hello1"/>
</StackPanel>
</Button>
包含的控件
ButtonBase | Button | CheckBox | ListBoxItem |
---|---|---|---|
RepeatButton | Frame | ConboxItem | ToggleButton |
GridViewColumnHeader | Label | ListViewItm | ConentControl |
NavigationWindow | Window | ScorollViewer | GroupItem |
StatusBarItem | ToolTip | UserControl | RadioButton |
5.3.2 HeaderedContentControl
特点:
-
派生自HeaderedContentControl类,HeaderedContentControl是派生自ContentControl
-
都是控件,用于显示带标题的数据
-
包含带标题的数据外还具有一个显示标题的区域
-
内容属性为Content和Header
-
Content和Header都只能接受一个元素作为内容
包含的控件
Expander |
---|
Groupbox |
HeaderedContentControl |
TabItem |
<GroupBox Header="Group1" Content="Test1、Test2" Margin="5"/>
5.3.3 ItemsControl
特点:
- 派生自ItemsControl
- 都是控件,用于显示列表化的数据
- 内容属性为Items或ItemsSource
- 每种ItemsControl都对应由自己的条目容器(Items Container)
包含的控件:
Menu | MenuBase | ContentMenu | ComBox |
---|---|---|---|
ItemsControls | ListBox | ListView | TabControl |
TreeView | Slector | StatusBar |
<ListBox>
<Button Height="20" Width="50" Content="OK"/>
<TextBox Text="AAA"/>
<TextBox Text="AAA1"/>
<CheckBox Content="Setva"/>
</ListBox>
定义Listbox数据源:
public class Employee
{
public string Name { set; get; }
public int ID { set; get; }
public int Age { set; get; }
}
List<Employee> employees = new List<Employee>()
{
new Employee(){ ID=1,Name="Tom",Age=5 },
new Employee(){ ID=2,Name="Tim",Age=6},
new Employee(){ID=3,Name = "bOB",Age=56},
};
填充到LstBox中
Listbox1.DisplayMemberPath = "Name";
Listbox1.SelectedValuePath = "ID";
Listbox1.ItemsSource = employees;
DisplayMemberPath告诉Listbox显示哪一个属性
SelectedValuePath告诉ListBocx返回选中的哪一个属性的值
5.3.4 HeaderedItemsControl
特点:
- 派生自 HeaderedItemsControl
- 都是控件,用于显示列表化的数据,同时可以显示一个标题
- 内容属性为Items、ItemsSource和Header
包含的控件有:MenuItem、Treeiew、ToolBar
5.3.5 Decorator
作用:在Ui上起装饰效果,如使用Border元素添加边框
特点
- 派生自Decorator 类
- 起UI装饰作用
- 内容属性为Child
- 只能由单一元素充当内容
ButtonChrome | BulletDecorator | Boder |
---|---|---|
ClassicBorderDecorator | AdornerDecorator | InkPresenter |
SystemDropShadowChrome | ListboxChrome | Viewbox |
5.3.6 TextBlock和TextBox
TextBlock:只能显示文本不能编辑,能够进行格式控制。内容属性是Inlines或Text
TextBox:允许用户编辑,格式默认。内容属性是Text
5.3.7 Shape
作用:视觉元素,用来在UI上绘制图形。用Fill属性设置填充效果,Stroke属性设置边线
特点:
- 派生自Shape类
- 用于2D图形绘制
- 无内容属性
- 使用Fill属性设置填充,使用Stroke实行设置边线
5.3.8 Panel
作用:用于UI布局
特点:
- 派生自Panel抽象类
- 主要功能是UI布局
- 内容属性为Children
- 内容可以是多个元素,Panel元素将控制他们的布局
Canvas | TollBarOverflowPanel | StackPanel | TabPanel |
---|---|---|---|
DockPanel | VirtualizingPanel | ToolBarPanel | UniformGrid |
Grid | VirtualizingStackPanel | WrapPanel |
5.4 UI布局
WPF设计两大部分:UI布局和动画
5.4.1 布局元素
控件与控件之间的关系:相邻、叠压、包含
主要布局元素:
- Grid:网格,自定义行列数量,调整行高列宽进行布局
- Stackpanel:栈式面板,按照竖直或水平方向排列为直线,移除元素自动填充补齐。
- Canvas:画布。以像素单位绝对坐标定位
- DockPanel:泊靠式面板,内部元素选择泊靠面板。
- WrapPanel:自动折行面板,元素排满一行后,自动折行
5.4.2 Grid
特点:
-
定义任意数量的行和列
-
行高和列宽可以使用绝对值、比例、自动调整方式进行设置,并可设置最大和最小
-
内部元素可设置所在行列,还可设置跨行跨列
-
可设置对齐方向
适用场景:
- UI布局大框架
- 大量UI元素需要行列对齐
- UI元素整体尺寸改变,元素需要保持固有的高度和宽度比
- UI后期有较大的变更或扩展时
高度宽度单位
英文名称 | 中文名称 | 简写 | 换算 |
---|---|---|---|
Pixel | 像素 | px | 图形基本单位 |
Inch | 英寸 | in | 1cm=(96/2.54)pixel |
Centimeter | 厘米 | cm | 1cm=(96/2.54)pixel |
Point | 点 | pt | 1pt=(96/72)pixel |
应用场景:
只是作为显示在屏幕上,使用像素即可。
用于打印,选择厘米和英寸
<Grid x:Name="UIGrid" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30px"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="1in"/>
<ColumnDefinition Width="1cm"/>
<ColumnDefinition Width="30pt"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50*"/>
<RowDefinition Height="50*"/>
</Grid.RowDefinitions>
</Grid>
UIGrid.ColumnDefinitions.Add(new ColumnDefinition());
UIGrid.ColumnDefinitions.Add(new ColumnDefinition());
UIGrid.RowDefinitions.Add(new RowDefinition());
UIGrid.RowDefinitions.Add(new RowDefinition());
## 行高列宽
* 使用绝对值
* 使用比例值,设置数值后添加*
* 使用字符串Auto,自动
<Grid Margin="10" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="120"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="80"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="4"/>
<RowDefinition Height="*"/>
<RowDefinition Height="4"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<TextBlock Text="请选择你的部门留言" Grid.Column="0" Grid.Row="0" VerticalAlignment="Center"/>
<ComboBox Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="4"/>
<TextBox Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="5" BorderBrush="Black"/>
<Button Content="提交" Grid.Column="2" Grid.Row="4"/>
<Button Content="清除" Grid.Column="4" Grid.Row="4"/>
</Grid>
5.4.3 StackPanel
特点:按照横向纵向排列,移除元素后自动补齐。
应用场景:同类元素需要紧凑排列、移除其中的元素后自动补缺
属性:
- Orientation 决定是横向还是纵向累积
- HorizontalAlignment 决定水平方向对齐方式
- VerticalAlignment 决定竖直方向对齐
<GroupBox Header="选择正确的答案" BorderBrush="Black">
<StackPanel>
<CheckBox Content="A 选择A"/>
<CheckBox Content="B 选择B"/>
<CheckBox Content="C 选择C"/>
<CheckBox Content="D 选择D"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="选择" Margin="5"/>
<Button Content="清除" Margin="5"/>
</StackPanel>
</StackPanel>
</GroupBox>
5.4.4 Canvas
特点:使用绝对位置定位
适用场景:
- 设计后基本不改动的布局
- 艺术性较强的布局
- 需要大量使用绝对坐标进行的布局
- 依赖于横纵坐标的动画
属性:Canvas.Left、Canvas.Top,Canvas.X,Canvas.Y
<Canvas>
<TextBlock Text="用户名" Canvas.Left="12" Canvas.Top="12"/>
<TextBox Height="23" Width="200" BorderBrush="Black" Canvas.Left="66" Canvas.Top="9"/>
<TextBlock Text="密码" Canvas.Left="12" Canvas.Top="40.72" Height="16" Width="36"/>
<TextBox Height="23" Width="200" BorderBrush="Black" Canvas.Left="66" Canvas.Top="38"/>
<Button Content="确定" Width="80" Height="22" Canvas.Left="100" Canvas.Top="67"/>
<Button Content="清除" Width="80" Height="22" Canvas.Left="186" Canvas.Top="67"/>
</Canvas>
5.4.5 Dockpanel
特点:Dockpanel内的元素会被附加上DockPanel.Dock属性,可取 Left、Top、Right、Bottom四个值。内部元素按照指定方向累积。
Bool类型的LastChildFill默认值是True,代表DockPanel的最后一个元素会填充剩余的空间。
<DockPanel >
<TextBox DockPanel.Dock="Top" Height="25" BorderBrush="Black"/>
<TextBox DockPanel.Dock="Left" Width="150" BorderBrush="Black"/>
<TextBox BorderBrush="Black"/>
</DockPanel>
GridSplitter
分割区域
设置 VerticalAlignment 、HorizontalAlignment即可确定上下还是左右移动分割线
ShowsPreview属性
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Grid.ColumnSpan="3" BorderBrush="Black"/>
<TextBox Grid.Row="1" BorderBrush="Black"/>
<GridSplitter Grid.Row="1" Grid.Column="1"
VerticalAlignment="Stretch"
HorizontalAlignment="Center"
Width="50"
Background="Gray"
ShowsPreview="True"/>
<TextBox Grid.Row="1" Grid.Column="2" BorderBrush="Black"/>
</Grid>
5.4.6 WrapPanel
流式布局,采用Orientation控制延伸方向,使用VerticalAlignment、HorizontalAlignment设置控件对齐
<WrapPanel>
<Button Width="100" Height="100" Content="OK"/>
<Button Width="100" Height="100" Content="OK"/>
<Button Width="100" Height="100" Content="OK"/>
<Button Width="100" Height="100" Content="OK"/>
<Button Width="100" Height="100" Content="OK"/>
</WrapPanel>