教程:微软文档
1.定义
数据模版就是数据的外衣,这个外衣的颜色,展示的内容和形式,可以由用户自定义。即数据的表象形式。
2.常用知识
2.1 数据模版的定义
- 指明Key的定义
<DataTemplate x:Key="taskDataTemplate">
<StackPanel Margin="5" Orientation="Horizontal">
<CheckBox Margin="5,0,10,0" IsChecked="{Binding IsDone}" />
<TextBlock VerticalAlignment="Center" FontSize="16" Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
- 指明类的定义
<DataTemplate DataType="{x:Type local:Task}">
<StackPanel Margin="5" Orientation="Horizontal">
<CheckBox Margin="5,0,10,0" IsChecked="{Binding IsDone}" />
<Border x:Name="border" BorderBrush="Yellow" BorderThickness="3">
<TextBlock VerticalAlignment="Center" FontSize="16" Text="{Binding Description}" />
</Border>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding TaskType}">
<DataTrigger.Value>
<local:TaskType>home</local:TaskType>
</DataTrigger.Value>
<Setter TargetName="border" Property="Background" Value="LightGreen" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
注意: 此 DataTemplate 会自动应用于所有 Task 对象。 请注意,在这种情况下,x:Key 是隐式设置的。 因此,如果为此 DataTemplate 分配 x:Key 值,你将替代隐式 x:Key,并且不会自动应用 DataTemplate。
2.2 数据模版的DataTrigger
同上
2.3 为数据选择数据模版
- 写一类继承自 DataTemplateSelector 并重写方法 SelectTemplate
public class TaskListDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
if (element != null && item != null && item is Task)
{
Task taskitem = item as Task;
if (taskitem.Priority == 1)
return
element.FindResource("importantTaskTemplate") as DataTemplate;
else
return
element.FindResource("taskDataTemplate") as DataTemplate;
}
return null;
}
}
- 在资源里面引用这个数据模版选择器
<local:TaskListDataTemplateSelector x:Key="taskSelector"/>
- 在使用数据模版的控件里面使用属性:ItemTemplateSelector
<ListBox ItemsSource="{Binding Source={StaticResource myTodoList}}" ItemTemplateSelector="{StaticResource taskSelector}" />
符完整实例
<Window
x:Class="Study04_数据模版.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Study04_数据模版"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<Window.Resources>
<local:Tasks x:Key="myTodoList" />
<DataTemplate x:Key="taskDataTemplate">
<StackPanel Margin="5" Orientation="Horizontal">
<CheckBox Margin="5,0,10,0" IsChecked="{Binding IsDone}" />
<TextBlock VerticalAlignment="Center" FontSize="16" Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="importantTaskTemplate">
<StackPanel Margin="5" Orientation="Vertical">
<CheckBox Margin="5,0,10,0" IsChecked="{Binding IsDone}" />
<Border BorderBrush="Red" BorderThickness="2" >
<TextBlock VerticalAlignment="Center" FontSize="16" Text="{Binding Name}" />
</Border>
<TextBlock VerticalAlignment="Center" FontSize="16" Text="{Binding Description}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Task}">
<StackPanel Margin="5" Orientation="Horizontal">
<CheckBox Margin="5,0,10,0" IsChecked="{Binding IsDone}" />
<Border x:Name="border" BorderBrush="Yellow" BorderThickness="3">
<TextBlock VerticalAlignment="Center" FontSize="16" Text="{Binding Description}" />
</Border>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding TaskType}">
<DataTrigger.Value>
<local:TaskType>home</local:TaskType>
</DataTrigger.Value>
<Setter TargetName="border" Property="Background" Value="LightGreen" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<local:TaskListDataTemplateSelector x:Key="taskSelector"/>
</Window.Resources>
<Grid>
<!--<ListBox Margin="10,10,10,10" ItemTemplate="{Binding Source={StaticResource taskDataTemplate}}" ItemsSource="{Binding Source={StaticResource myTodoList}}" />-->
<!--<ListBox Margin="10,10,10,10" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Source={StaticResource myTodoList}}" />-->
<ListBox ItemsSource="{Binding Source={StaticResource myTodoList}}" ItemTemplateSelector="{StaticResource taskSelector}" />
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace Study04_数据模版
{
public class Tasks : ObservableCollection<Task>
{
public Tasks()
{
Add(new Task { Name = "Task 1", Description = "Description for Task 1", Priority = 1, TaskType = TaskType.work });
Add(new Task { Name = "Task 2", Description = "Description for Task 2", Priority = 2, TaskType = TaskType.home });
Add(new Task { Name = "Task 3", Description = "Description for Task 3", Priority = 3, TaskType = TaskType.work });
}
}
public class Task
{
public string Name { get; set; }
public string Description { get; set; }
public int Priority { get; set; }
public TaskType TaskType { get; set; }
public override string ToString()
{
return Description.ToString();
}
}
public enum TaskType
{
home,
work,
}
public class TaskListDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
if (element != null && item != null && item is Task)
{
Task taskitem = item as Task;
if (taskitem.Priority == 1)
return
element.FindResource("importantTaskTemplate") as DataTemplate;
else
return
element.FindResource("taskDataTemplate") as DataTemplate;
}
return null;
}
}
}
3 其它示例
3.1 示例一
- 定义数据模版
<DataTemplate x:Key="ControlATemplate">
<local:RecipeInfoUC DataContext="{Binding DataContext.Parameter, RelativeSource={RelativeSource AncestorType=ContentControl}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
<!-- 控件B的模板 - 当IsRework为True时使用 -->
<DataTemplate x:Key="ControlBTemplate">
<local:RecipeReworkUC DataContext="{Binding DataContext.Parameter, RelativeSource={RelativeSource AncestorType=ContentControl}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
- 定义数据模版选择器
/// <summary>
/// 模板选择器 - 根据IsRework的值选择对应的模板
/// </summary>
public class ReworkTemplateSelector : DataTemplateSelector
{
/// <summary>
/// 控件A的模板属性
/// </summary>
public DataTemplate ControlATemplate { get; set; }
/// <summary>
/// 控件B的模板属性
/// </summary>
public DataTemplate ControlBTemplate { get; set; }
/// <summary>
/// 模版选择方法
/// </summary>
/// <param name="item"></param>
/// <param name="container"></param>
/// <returns>模版</returns>
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
// 检查item是否为bool类型
if (item is bool isRework)
{
// 根据IsRework的值返回对应的模板
return isRework ? ControlBTemplate : ControlATemplate;
}
// 默认返回控件B的模板
return ControlBTemplate;
}
}
- 在资源中引用数据模版
<local:ReworkTemplateSelector x:Key="ReworkTemplateSelector" ControlATemplate="{StaticResource ControlATemplate}" ControlBTemplate="{StaticResource ControlBTemplate}" />
- 使用数据模版选择器
<ContentControl Content="{Binding HasReWorkCamera}" ContentTemplateSelector="{StaticResource ReworkTemplateSelector}" />