布局控件

  • 通过内置的容器控件灵活地组织用户界面

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();