WPF学习笔记(11)数据模板DataTemplate与数据模板选择器DataTemplateSelector

数据模板DataTemplate与数据模板选择器DataTemplateSelector

  • 一、DataTemplate
    • 1. DataTemplate概述
    • 2. DataTemplate详解
  • 二、DataTemplateSelector
    • 1. DataTemplateSelector概述
    • 2. DataTemplateSelector详解
  • 总结


一、DataTemplate

1. DataTemplate概述

DataTemplate 表示数据模板、定义如何显示一些复杂的数据,决定了数据展示的外观
官方文档:https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.datatemplate?view=netframework-4.8
在这里插入图片描述
DataTemplate 的属性如下:

属性说 明
DataType获取或设置此DataTemplate所针对的数据类型。

2. DataTemplate详解

在MainWindow.xaml.cs中自定义Teacher、Student类,在MainWindow.xaml中定义他们的对象如下:

    public class Teacher{public String Name { get; set; }public String Desc { get; set; }}public class Student{public String Name { get; set; }public String Age { get; set; }}
    <Grid><ContentControl Margin="220,70,345,303"><local:Teacher Name="张三老师" Desc="擅长高等数学"></local:Teacher></ContentControl><ContentControl Margin="220,151,345,217"><local:Student Name="学生" Age="20"/></ContentControl><ContentControl Margin="220,249,345,123"><local:Student Name="学生" Age="20" /></ContentControl></Grid>

如果不提供 DataTemplate,对于复杂数据,控件显示数据会默认调用对象的 Tostring()方法转为字符串来显示
在这里插入图片描述
数据模板有三种用法:

  1. 在资源中描述 Teacher类型数据显示的数据模板资源
    <Window.Resources><!--在资源中描述 Teacher类型数据显示的数据模板资源--><DataTemplate DataType="{x:Type local:Teacher}"><Border BorderBrush="red" BorderThickness="3"><StackPanel><TextBlock Text="{Binding Name}" /><TextBlock Text="{Binding Desc}" /></StackPanel></Border></DataTemplate></Window.Resources>

根据显示内容的类型自动使用数据模板
在这里插入图片描述
2. 可以在控件中定义数据模板,将第二项的对象Student扩展如下:

        <ContentControl Margin="220,151,345,217"><ContentControl.ContentTemplate><DataTemplate><Border BorderBrush="Green" Background="Yellow" BorderThickness="3"><StackPanel><Button Content="{Binding Name}" /><Button Content="{Binding Age}" /></StackPanel></Border></DataTemplate></ContentControl.ContentTemplate><local:Student Name="学生" Age="20" /></ContentControl>
  1. 还可以在资源中的数据模板定义Key:
<Window.Resources><!--在资源中的数据模板定义Key--><DataTemplate x:Key="myDataTemplate"><Border BorderBrush="Gray" BorderThickness="3"><StackPanel ><TextBlock Text="{Binding Name}" /><ProgressBar Height="10" Value="{Binding Age}" /></StackPanel></Border></DataTemplate>
</Window.Resources><Grid><ContentControl ContentTemplate="{StaticResource myDataTemplate}" Margin="220,249,345,123"><local:Student Name="王五" Age="28" /></ContentControl>
</Grid>

代码汇总:

<Window.Resources><!--在资源中描述 Teacher类型数据显示的数据模板资源--><DataTemplate DataType="{x:Type local:Teacher}"><Border BorderBrush="red" BorderThickness="3"><StackPanel><TextBlock Text="{Binding Name}" /><TextBlock Text="{Binding Desc}" /></StackPanel></Border></DataTemplate><!--在资源中的数据模板定义Key--><DataTemplate x:Key="myDataTemplate"><Border BorderBrush="Gray" BorderThickness="3"><StackPanel ><TextBlock Text="{Binding Name}" /><ProgressBar Height="10" Value="{Binding Age}" /></StackPanel></Border></DataTemplate>
</Window.Resources>
<Grid><ContentControl Margin="220,70,345,303"><local:Teacher Name="张三" Desc="擅长高等数学"></local:Teacher></ContentControl><!--在控件中定义数据模板--><ContentControl Margin="220,151,345,217"><ContentControl.ContentTemplate><DataTemplate><Border BorderBrush="Green" Background="Yellow" BorderThickness="3"><StackPanel><Button Content="{Binding Name}" /><Button Content="{Binding Age}" /></StackPanel></Border></DataTemplate></ContentControl.ContentTemplate><local:Student Name="李四" Age="20" /></ContentControl><ContentControl ContentTemplate="{StaticResource myDataTemplate}" Margin="220,249,345,123"><local:Student Name="王五" Age="28" /></ContentControl>
</Grid>

在这里插入图片描述

二、DataTemplateSelector

1. DataTemplateSelector概述

DataTemplateSelector提供一种方法来根据绑定的数据选择数据模板。
官方文档:https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.controls.datatemplateselector?view=netframework-4.8

在这里插入图片描述

可重写方法
public virtual DataTemplate SelectTemplate(object item, DependencyObject container)
当在派生类中重写时,根据数据返回基于自定义逻辑的 DataTemplate。
参数:
item 要为其选择模板的数据对象,
container 数据绑定对象。

2. DataTemplateSelector详解

在这里插入图片描述
在MainWindow.xaml中定义数据模板:

<Window.Resources><DataTemplate x:Key="smallTemplate"><Grid><Rectangle Stroke="Black" /><TextBlock Margin="5" Text="{Binding}" FontSize="18"/></Grid></DataTemplate><DataTemplate x:Key="largeTemplate"><Grid><Ellipse Stroke="Green" StrokeThickness="4" Width="100" Height="100"/><TextBlock Margin="20" Text="{Binding}" FontSize="50" Foreground="Red"/></Grid></DataTemplate>
</Window.Resources>

新建类MyTemplateSelector.cs,自定义模板选择器

public class MyTemplateSelector : DataTemplateSelector
{public DataTemplate SmallTemplate { get; set; }public DataTemplate LargeTemplate { get; set; }public override DataTemplate SelectTemplate(object item, DependencyObject container){if (item == null){return null; // Null value can be passed by lDE designer}double num = (double)item;return num <= 10 ? SmallTemplate : LargeTemplate;}
}

在MainWindow.xaml中为Label设置模板选择器属性

    <StackPanel><Label Content="{Binding Value, ElementName=slider}"><Label.ContentTemplateSelector><local:MyTemplateSelector SmallTemplate="{StaticResource smallTemplate}" LargeTemplate="{StaticResource largeTemplate}"/></Label.ContentTemplateSelector></Label><Slider x:Name="slider" Minimum="0" Maximum="100" IsSnapToTickEnabled="True"/></StackPanel>

运行结果如下:
在这里插入图片描述


总结

  • DataTemplate的三种用法:①在资源中直接描述 类的数据显示的数据模板,②在资源中的数据模板定义Key,③在控件ContentControl 中定义数据模板。
  • 虚函数DataTemplateSelector在使用时需重写