布局控件
- 通过内置的容器控件灵活地组织用户界面
WPF 常用的布局控件有
Grid
- 通过定义行列组织布局
-
可设置
RowDefinition
、ColumnDefinition
-
定义为
auto
的行列自适应子元素 -
定义为
n*
的元素按照 n 定义的比率缩放 -
子元素拖过设置
Grid.Row
、Gird.Column
、Grid.RowSpan
、Grid.ColumnSpan
四个属性设置元素位置
DockPanel
- 将元素按四个方向进行顺序排布
-
LastChildFill
决定默认的元素是否填充剩余空间
StackPanel
- 通过按横向或纵向堆叠元素进行布局
-
可设置
Orientation
决定排布方向
WarpPanel
- 将控件按照顺序进行布局,如果行位置不够,自动换行
-
使用
ItemHeight
、ItemWidth
设置元素的宽高 -
可设置
Orientation
决定排布方向 -
UniformGrid
按照定义的行列数量自动
UniformGrid
- 按照定义的行列数量自动填充相应的格子
-
设置
Rows
及Columns
样式(Style)
- 样式负责修饰元素的外观及行为,是组织和重用元素外观的工具
-
所有控件继承于
FrameworkElement
类型
<!-- 无 Key 名称意为对全局应用此样式 -->
<!-- 需要定义好样式的目标类型 -->
<Style TargetType="Button">
<Setter Property="FontSize" Value="18"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="Red"/>
</Style>
<!-- 有 Key 名称可以通过资源调用,可继承与其他的样式资源 -->
<Style x:Key="ButtonStyle" TargetType="Button" BaseOn="MyBtnBaseStyle" >
<Setter Property="FontSize" Value="18"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="Red"/>
</Style>
<!-- 控件属性的优先级比样式高 -->
<Button Foreground="Green" Style="{StaticResource ButtonStyle}"/>
-
WPF 中所有控件继承于
FreamworkElement
类型 -
ContentPresenter
可以接收所有Content
类型的控件 -
所有
Content
类型控件继承于ContentControl
资源字典(ResourceDictionary)
- 静态资源(StaticResource) 仅引用资源一次,当源发生改变时,不会跟随改变
- 动态资源(DynamicResource) 当源发生改变时,会跟随改变
控件模板(ControlTemplate)
实例化树的文档大纲窗口,创建控件的副本,可以看到默认控件样式实现
操作:在文档大纲 -> 元素 -> 编辑样式 -> 创建副本
Style
中定义与该类型有关的属性集合
详解
ControlTemplete
标签下的
ContentPresenter
-
ContentPresenter
的特点- 作为复杂内容的呈现器
-
控件带有
Content
属性的控件均继承于ContentControl
-
Content
为Object
的类型,可以承载复杂对象 - 用来呈现控件中承载的内容
-
TemplateBindding
将外部定义属性与内部控件模板建立关系TemplateBindding
只能使用该控件带有的属性
触发器(Tigeer)
- 触发器可以理解为,当达到某个触发的条件后,执行预期内的响应
- 触发器的响应可以是样式变化、数据变化、动画等
-
常用的
Trigger
类型为
Trigger | 说明 |
---|---|
Trigger
|
监测依赖属性的变化,触发器生效 |
MultiTrigger
|
通过多个条件的设置,达到满足条件,使触发器生效 |
DataTrigger
|
通过数据变化,使得触发器生效 |
MultiDataTrigger
|
多个数据条件定义的触发器 |
EventTrigger
|
事件触发器 |
-
触发器一般声明在样式
Style
当中,也可以定义在 控件的资源 中如:<Button.Resources>
-
==如果要自定义样式,使用样式模板定义到
ControlTemplate.Triggers
(要根据你的需求,如果重写了ControlTemplate
,需要写到这里面)==
例:
Trigger
单一条件触发器
<!-- 鼠标进入Button,改变前景颜色及文字大小 -->
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="FontSize" Value="18"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Green"/>
<Setter Property="FontSize" Value="12"/>
</Trigger>
</Style.Triggers>
</Style>
例:
MultiTrigger
多触发器
<!-- 当满足多个条件,执行多个 Setter 参数 -->
<Style.Triggers>
<MultiTrigger>
<!-- 条件列表 -->
<MultiTrigger.Conditions>
<Condition Property="HasItems" Value="false" />
<Condition Property="Height" Value="Auto" />
</MultiTrigger.Conditions>
<!-- Setter 集合-->
<MultiTrigger.Setters>
<Setter Property="MinHeight" Value="95"/>
<Setter Property="MinWidth" Value="120"/>
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>
例:
DataTrigger
数据触发器
<!-- TextBox 输入"sucker"时候,更改前景色和背景色 -->
<!-- 注意 Binding 的写法 -->
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=Self},Path=Text}" Value="sucker">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Background" Value="Black"/>
</DataTrigger>
</Style.Triggers>
</Style>
数据模板(DataTemplate)初识
传统使用后台代码为前台控件增加数据
ComboBox.ItemSource = List<T>;
将类型直接赋给
ItemSource
这样使用
teachers.Add(new Teacher { Name = "Jack", Gender = "Male" });
teachers.Add(new Teacher { Name = "Tom", Gender = "Male" });
teachers.Add(new Teacher { Name = "Rose", Gender = "Female" });
comboxList.ItemsSource = teachers;
//出现以上类型无法直接被 ItemSource 解析的问题
所以我们要引入
DataTemplate
数据模板
如
CombBox.ItemTemplate
中设置
DataTemplate
CombBox
使用数据模板
DataTemplate
不是一个简单类型,而是一个容器
==
DataTemplate
中容器可以自定义数据的展现形式==
将内容通过
Binding
自动对应并展示出来
例:ComboBox 中使用数据模板
//定义自己的数据类型
public class Teacher
public string Name { get; set; }
public string Gender { get; set; }
<!-- 在前台设置绑定,注意数据类型 -->
<ComboBox x:Name="comboxList">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Margin="10,0,0,0" Text="{Binding Gender}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
也可以将模板定义到资源文件中,
ComboBox
使用静态资源使用定义好的数据模板
//将模板定义到资源文件中
<Grid.Resources>
<DataTemplate x:Key="defaultListTemp">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Margin="10,0,0,0" Text="{Binding Gender}" />
</StackPanel>
</DataTemplate>
</Grid.Resources>
<!-- ItemsTemplate 使用静态资源使用定义好的数据模板 -->
<ListBox x:Name="myListBox" ItemsTemplate="{StaticResource defaultListTemp}" />
<CombBox x:Name="myCombBox" ItemsTemplate="{StaticResource defaultListTemp}" />
//在后台代码为 myListBox、myCombBox 的 ItemsSource 中添加数据
Teacher t1 = new Teacher();
t1.Name = "Tim";
t1.Gender = Male;
Teacher t2 = new Teacher);
t2.Name = "Jane";
t2.Gender = Female;
IList<Teacher> teacherList = new List<Teacher>();
teacherList.Add(t1);
teacherList.Add(t2);
myListBox.ItemsSource = teacherList;
myCombBox.ItemsSource = teacherList;
DataGrid
中使用数据模板及
ICommand
接口
-
ICommand
接口可以将委托事件绑定到DataGrid
的元素事件上 -
你可以在表格中使用放入类似
Button
控件
<DataGrid AutoGenerateColumns="False" CanUserAddRows="False" ItemsSource="Binding ColorDefinations}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding CaptionSet}" Header="Solid Color Name" />
<DataGridTextColumn Binding="{Binding ColorSet}" Header="Color HEX Code" />
<DataGridTemplateColumn Width="200" Header="Operation">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button Margin="2" Command="{Binding ShowChineseCommand}" Content="显示中文" />
<Button Margin="2" Command="{Binding ChangeCodeCommand}" Content="变更代码" />
<Button Margin="2" Command="{Binding DeleteCommand}" Content="删除此条" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Binding
绑定初识
-
控件元素绑定
<TextBox x:Name="targetTextBox" Text="一个内容"/>
<TextBox Text="{Binding ElementName=targetTextBox,Path=Text,Mode=Default}"/>
-
使用数据上下文(DataContext)沟通业务类
准备
MainViewModel
业务类,设置DataContext
,使界面可以访问类中的 资源(属性,方法等)例子中MainViewModel
有一个TitleName
属性
<!-- 方法1、使用 XAML 绑定至 ViewModel -->
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
//方法2、使用后台代码绑定到 `ViewModel`
this.DataContext = new MainViewModel();