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

发布于:2025-07-01 ⋅ 阅读:(22) ⋅ 点赞:(0)


一、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在使用时需重写

网站公告

今日签到

点亮在社区的每一天
去签到