WPF DataTemplate 数据模板

DataTemplate 顾名思义,数据模板,在 wpf 中使用非常频繁。

它一般用在带有 DataTemplate 依赖属性的控件中,如 ContentControl、集合控件 ListBox、ItemsControl 、TabControls 等。

1. 非集合控件中使用

xml 复制代码
<UserControl.Resources>
    <DataTemplate x:Key="MyDataTemplate">
        <Grid
            Width="100"
            Height="40"
            Background="DeepPink" />
    </DataTemplate>
</UserControl.Resources>

在前端代码中,应用这个数据模板,

xml 复制代码
<ContentControl ContentTemplate="{StaticResource MyDataTemplate}" />

显示如下:

2. 集合控件中使用

以 ListBox 为例,

假设 ListBox 绑定数据源为下面的 MyItems ,

csharp 复制代码
public class DataTemplateViewModel
{
    public IList<string> MyItems { get; }
    
    public DataTemplateViewModel()
    {
        MyItems = new List<string>() { "Tom~", "Jerry~"};
    }
}
xml 复制代码
<ListBox
    Grid.Column="1"
    ItemsSource="{Binding MyItems}" />

在不设置数据模板的情况下,默认就是显示字符串,

新增一个数据模板,

xml 复制代码
<UserControl.Resources>
    <DataTemplate x:Key="MyDataTemplate">
        <Grid
            Width="100"
            Height="40"
            Background="DeepPink">
            <TextBlock Text="{Binding .}" Foreground="Yellow" />
        </Grid>
    </DataTemplate>
</UserControl.Resources>

并应用该模板后,

xml 复制代码
<ListBox
    Grid.Column="1"
    ItemTemplate="{StaticResource MyDataTemplate}"
    ItemsSource="{Binding MyItems}" />

显示为,

通过上面的例子,我们可以知道,数据模板,可以用来自定义数据展示的方式,包括:格式、效果、样式等。

3. DataTempate 其它用法

3.1 自动匹配数据类型

上面演示的集合中使用 DataTemplate 的方式,数据类型相对简单。实际开发中经常要根据不同数据类型,展示不同数据样式。

假设申明一个图形接口,

csharp 复制代码
public interface IShape
{
    string Color { get; }
}

一个圆、矩形类各自实现该接口,

csharp 复制代码
public class Circle : IShape
{
    public string Color { get; }

    public Circle(string color)
    {
        Color = color;
    }
}

public class Rectange : IShape
{
    public string Color { get; }

    public Rectange(string color)
    {
        Color = color;
    }
}

集合 Shapes 中包含这些图形实例,

csharp 复制代码
public class DataTemplateViewModel
{
    public IList<IShape> Shapes { get; }

    public DataTemplateViewModel()
    {
        Shapes = new List<IShape>()
        {
            new Circle("#CC0066"),
            new Rectange("#009900"),
        };
    }
}

设置 DataTemplate 的 DataType 属性(不设置 x:key),就可以根据图形类型,自动应用对应数据模板,

xml 复制代码
<ListBox
    Grid.Column="1"
    ItemsSource="{Binding Shapes}">
    <ListBox.Resources>
        <DataTemplate DataType="{x:Type views:Circle}">
            <Ellipse Width="60" Height="60" Fill="{Binding Color}" />
        </DataTemplate>
        <DataTemplate DataType="{x:Type views:Rectange}">
            <Rectangle Width="60" Height="60" Fill="{Binding Color}" />
        </DataTemplate>
    </ListBox.Resources>
</ListBox>

效果如下,

3.2 DataTemplateSelector

使用 DataTemplateSelector (模板选择器)也可以同样实现上面的效果。

我们只需要继承 DataTemplateSelector 类,并重载其 SelectTemplate 方法,

csharp 复制代码
public class MyDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate CircleTemplate { get; set; }
    public DataTemplate RectTemplate { get; set; }
    public DataTemplate EmptyTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is Circle)
        {
            return CircleTemplate;
        }
        else if (item is Rectange)
        {
            return RectTemplate;
        }

        return EmptyTemplate;
    }
}

数据模板 + 选择器 前端定义,这时就要设置 DataTemplate 的 x:key 了,

xml 复制代码
<UserControl.Resources>
    <DataTemplate x:Key="Circle.DataTemplate">
        <Ellipse Width="60" Height="60" Fill="{Binding Color}" />
    </DataTemplate>

    <DataTemplate x:Key="Rectangle.DataTemplate">
        <Rectangle Width="60" Height="60" Fill="{Binding Color}" />
    </DataTemplate>

    <DataTemplate x:Key="Empty.DataTemplate">
        <Grid Width="60" Height="60" Background="Black" />
    </DataTemplate>

    <views:MyDataTemplateSelector x:Key="MyDataTemplateSelector" 
                                  CircleTemplate="{StaticResource Circle.DataTemplate}"
                                  RectTemplate="{StaticResource Rectangle.DataTemplate}" 
                                  EmptyTemplate="{StaticResource Empty.DataTemplate}" />
</UserControl.Resources>

应用选择器,

xml 复制代码
<ListBox
    Grid.Column="1"
    ItemTemplateSelector="{StaticResource MyDataTemplateSelector}"
    ItemsSource="{Binding Shapes}">
</ListBox>

新增一个 null 元素配合实验,

csharp 复制代码
Shapes = new List<IShape>()
{
    new Circle("#CC0066"),
    new Rectange("#009900"),
    null,
};

显示效果,

相关推荐
LcVong15 小时前
WPF MediaPlayer获取网络视频流当前帧并展示图片完整范例
网络·wpf
bugcome_com16 小时前
WPF数据绑定入门:从传统事件到5种绑定模式
wpf
LateFrames18 小时前
我用 WPF 做了一个 “苍蝇飞舞” 的屏保
ui·wpf
wuty0071 天前
完善基于WPF开发的标尺控件(含实例代码)
wpf·wpf标尺·支持横向竖向标尺·ruler
浩浩测试一下2 天前
洪水猛兽攻击 Ddos Dos cc Drdos floods区别
安全·web安全·网络安全·系统安全·wpf·可信计算技术·安全架构
无心水2 天前
分布式环境下定时任务与SELECT FOR UPDATE的陷阱与解决方案
分布式·后端·wpf·xxl-job·quartz·定时任务·selectforupdate
xdpcxq10292 天前
Spring AOP + Guava RateLimiter 用注解实现优雅限流
spring·wpf·guava
Aevget2 天前
界面控件DevExpress WPF v25.2新版亮点:模板工具包全新升级
wpf·界面控件·devexpress·ui开发·.net 10
czhc11400756632 天前
wpf 129
wpf
码界奇点4 天前
基于eBPF技术的高性能网络防火墙系统设计与实现
开发语言·网络·毕业设计·php·wpf·go语言·源代码管理