数据模板有什么用

简而言之,数据模板能让你更方便、更灵活的显示你的各类数据。只有你想不到,没有它做不到的(感觉有点夸张,实践之后,你就觉得一点不夸张 )。

直接对比下效果:

无数据模板

应用了数据模板

好了,下面我们一步一步来看看数据模板如何做到化腐朽为神奇的!

一些前置条件

  • 假设你已了解了MVVM设计模式

  • 假设你已了解了一些数据绑定知识

  • 假设你已了解了一些样式知识

代码准备

  1. 首先准备一个Model,代码如下:

    public class Employee
    {
    public string Name { get; set; }
    public Sex Sex { get; set; }
    public string Job { get; set; }
    public string Department { get; set; }
    public string Email { get; set; }
    } public enum Sex
    {
    Male,
    Female
    }
  2. 在准备好ViewModel,代码如下:

    public class MainViewModel: BindableBase
    {
    private IEnumerable<Employee> _employees; public IEnumerable<Employee> Employees
    {
    get => _employees;
    set => SetProperty(ref _employees, value);
    } public MainViewModel()
    {
    Employees = new List<Employee>()
    {
    new Employee() {Name="张明",Department="技术售后部",Job="售后工程师",Sex=Sex.Male,Email="Zhang.San@wpf.com"},
    new Employee() {Name="葛倩",Department="人事部",Job="招聘专员",Sex=Sex.Female,Email="Ge.Qian@wpf.com"},
    new Employee() {Name="王小伟",Department="研发部",Job="高级软件工程师",Sex=Sex.Male,Email="Wang.Xiaowei@wpf.com"},
    };
    } }

没有数据模板

准备好没有使用数据模板的view的xaml代码

<Window x:Class="WpfPractice.DataTemplateDemo.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfPractice.DataTemplateDemo"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ListBox ItemsSource="{Binding Employees}"
HorizontalContentAlignment="Stretch"> </ListBox>
</Grid>
</Window>

运行下程序,就会出现这样的界面

熟悉.Net的同学,应该看出来每一项显示的是对象的ToString方法返回的值。因为我们集合中存放的是复杂类型的对象,如果没有数据模板,ListBox默认就会用ToString去显示。而ToString方法默认返回的就是对象的类型限定名。

既然了解到这个原理,那我们重载实现下ToString方法

public class Employee
{
public string Name { get; set; }
public Sex Sex { get; set; }
public string Job { get; set; }
public string Department { get; set; }
public string Email { get; set; }
public override string ToString()
{
return $"{Name},{Job},{Department}";
}
}

再次运行程序,结果如下

这次算是显示出一些有用信息了,但这样的UI体验,未免太差。如何让我们的数据呈现更加吸引人呢?下面就轮到数据模板大显身手了。

应用数据模板

直接上应用了数据模板的xaml代码

<Window x:Class="WpfPractice.DataTemplateDemo.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfPractice.DataTemplateDemo"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ListBox ItemsSource="{Binding Employees}"
HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:Employee}">
<Border Padding="5" BorderThickness="1" BorderBrush="Gray" CornerRadius="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center" Text="{Binding Name}" FontSize="18" FontWeight="Black"/>
<StackPanel Grid.Column="1">
<TextBlock Text="{Binding Job}"/>
<TextBlock Text="{Binding Department}"/>
<TextBlock Text="{Binding Email}"/>
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>

其实数据模板就是把对象的属性绑定到不同的UI控件上,然后通过合理的布局,就能显示让数据显示的更加美观了。

怎么样?效果完全就不一样了,到这里,相信同学你应该能get到数据模板的作用了!当然这个只是数据模板的最基本用法,其实数据模板还有其他更强大的功能。比如可以通过数据模板让男性员工的名字显示成淡蓝色,女性的名字显示成淡绿色。这个功能下面触发器的部分会介绍。

我们还是接着数据模板定义这部分内容,我们是通过重写了ListBox.ItemTemplate来定义数据模板的,但如果在其他控件我们也要显示这样,岂不是在定义一遍这个数据模板?这样明显不符合我们代码复用的原则。还好,在wpf中,我们可以通过资源的方式来定义通用的数据模板,代码如下

<Window x:Class="WpfPractice.DataTemplateDemo.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfPractice.DataTemplateDemo"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<DataTemplate DataType="{x:Type local:Employee}">
<Border Padding="5" BorderThickness="1" BorderBrush="Gray" CornerRadius="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center" Text="{Binding Name}" FontSize="18" FontWeight="Black"/>
<StackPanel Grid.Column="1">
<TextBlock Text="{Binding Job}"/>
<TextBlock Text="{Binding Department}"/>
<TextBlock Text="{Binding Email}"/>
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Employees}"
HorizontalContentAlignment="Stretch">
</ListBox>
</Grid>
</Window>

此时我们发现,并不需要重新定义ListBox.ItemTemplate,但运行结果和上面保持一致!

数据触发器

前面我们提到可以通过数据模板让男性员工的名字显示成淡蓝色,女性的名字显示成淡绿色,其实就可以通过数据触发器来实现这样的功能。

这里简单说下触发器的作用,更详细的去看[微软的官方文档](DataTrigger Class (System.Windows) | Microsoft Learn)。触发器就是当绑定的数据满足某个条件时,可以去设置一些控件的属性值,或者执行一些动作(例如动画)。

基于触发器原理,实现的代码如下

<Window.Resources>
<DataTemplate DataType="{x:Type local:Employee}">
<Border Padding="5" BorderThickness="1" BorderBrush="Gray" CornerRadius="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="txtName" VerticalAlignment="Center" Text="{Binding Name}" FontSize="18" FontWeight="Black"/>
<StackPanel Grid.Column="1">
<TextBlock Text="{Binding Job}"/>
<TextBlock Text="{Binding Department}"/>
<TextBlock Text="{Binding Email}"/>
</StackPanel>
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Sex}" Value="Male">
<Setter TargetName="txtName" Property="Foreground" Value="LightBlue"/>
</DataTrigger>
<DataTrigger Binding="{Binding Sex}" Value="Female">
<Setter TargetName="txtName" Property="Foreground" Value="LightGreen"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>

运行结果

我们可以看到是通过修改显示名字的TextBlock的字体颜色来实现我们需求的,其实我们可以同时设置多个控件的属性来满足更复杂的需求的。

到这里,浅谈数据模板就接近尾声了,所谓浅谈,其实把数据模板的核心用法都覆盖到了,在实际项目开发中,都是基于这些知识的灵活应用!

最后

奉上源代码 https://gitee.com/liuww06/wpfpractice/tree/master/src/WpfPractice.DataTemplateDemo

WPF之浅谈数据模板(DataTemplate)的更多相关文章

  1. WPF中的数据模板(DataTemplate)(转)

    原文地址 http://www.cnblogs.com/zhouyinhui/archive/2007/03/30/694388.html WPF中的数据模板(DataTemplate)        ...

  2. WPF中的数据模板(DataTemplate)

    原文:WPF中的数据模板(DataTemplate) WPF中的数据模板(DataTemplate)                                                   ...

  3. 【ASP.NET MVC系列】浅谈数据注解和验证

    [ASP.NET MVC系列]浅谈数据注解和验证   [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google C ...

  4. 浅谈dedecms模板引擎工作原理及其自定义标签

    浅谈dedecms模板引擎工作原理: 理解织梦模板引擎有什么意思? 可以更好地自定义标签.更多在于了解织梦系统,理解模板引擎是理解织梦工作原理的第一步. 理解织梦会使我们写PHP代码是更顺手,同时能学 ...

  5. Python Web 基础向(四) 浅谈数据层

    数据层一般会给人带来一些困扰,在于其定位不准确.聚合Model的工作也可以放在逻辑层做,但会导致逻辑层变重,经常出现大段晦涩代码.因此我的建议是保留Model聚合层,尽管会导致工作量的略微增加,但却可 ...

  6. (转)浅谈dedecms模板引擎工作原理及自定义标签

    理解织梦模板引擎有什么意义?一方面可以更好地自定义标签.更多在于了解织梦系统,理解模板引擎是理解织梦工作原理的第一步.理解织梦会使我们写php代码时更顺手,同时能学习一些php代码的组织方式. 这似乎 ...

  7. 浅谈Vue模板的那些事儿

    接触过vue的童鞋都知道,组件的模板一般都是在template选项内定义的,如 Vue.component('child-component', { template: '<h3>我是闰土 ...

  8. 【Thymeleaf】浅谈Java模板引擎(带更新...)

    什么是模板引擎 模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档. 为什么要用模板 ...

  9. 数据模板--DataTemplate

    DataTemplate 的 "DataType" 通常就是 “ViewModel” ——视图模型(亦可不恰当称之为:数据模型) <DataTemplate DataType ...

  10. 企业应用:浅谈 “数据权限” 和 查询 API 设计

    背景 多数企业应用都需要对数据权限进行控制,如:某个用户只能看到某个范围的数据(数据行).某个用户只能看到某几列数据(数据列).本文以数据行级别的权限控制为范例,谈谈如何设计权限模型和查询 API. ...

随机推荐

  1. 用python的pylab画wave波形之sampwidth问题

    问题 网上找了好多地方,核心代码都是一样的,比如这句. wavedata=np.fromstring(bindata,dtype=np.short) 效果也还行. 可一次随机加载了一个Office里的 ...

  2. C#中抽象方法与虚方法的区别详解及示例

    1. 抽象方法与虚方法的区别   先说两者最大的区别:抽象方法是需要子类去实现的.虚方法是已经实现了的,可以被子类覆盖,也可以不覆盖,取决于需求.因为抽象类无法实例化,所以抽象方法没有办法被调用,也就 ...

  3. XXL-Job与Elastic-Job详细对比

    1. 失败处理策略 失败处理策略 XXL-Job Elastic-Job 失败重试 支持,最多重试三次.重试时间间隔可配置. 支持,最多重试十次.重试时间间隔可配置. 失败告警 支持,可配置告警接收人 ...

  4. EF Core从TPH迁移到TPT

    Intro EF Core支持多种方式处理具有继承关系的表,现在支持TPH.TPC(EF Core 7).TPT,具体的实现方式可以参考官方文档和这篇文章. 大致总结一下不同的方式的区别: TPH:所 ...

  5. 开发轻量级REST API样板 基于Node.js、MongoDB 通过Mongoose驱动

    ZY.Node.Mongodb https://gitee.com/Z568_568/node.mongodb.git https://github.com/ZHYI-source/ZY.Node.M ...

  6. 活字格性能优化技巧(3):如何巧用CDN提升含页面的访问速度

    本文由葡萄城技术团队于博客园原创并首发转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 上两篇中我们分享了如何利用数据库主键和表格设置默认不加载数据来提升应用 ...

  7. stm32报错

    1. declaration may not appear after executable statement in block 关于编译错误的小伙伴:error: #268: declaratio ...

  8. 带你揭开神秘的Javascript AST面纱之Babel AST 四件套的使用方法

    作者:京东零售 周明亮 写在前面 这里我们初步提到了一些基础概念和应用: 分析器 抽象语法树 AST AST 在 JS 中的用途 AST 的应用实践 有了初步的认识,还有常规的代码改造应用实践,现在我 ...

  9. 【树莓派】Docker安装calibre-web搭建在线书城

    一.下载docker镜像 sudo docker pull johngong/calibre-web 二.创建calibre-web镜像的映射目录,存放配置文件&书籍 mkdir /home/ ...

  10. 《爆肝整理》保姆级系列教程-玩转Charles抓包神器教程(14)-Charles过滤网络请求

    1.简介 在日常工作测试中,经常要抓包看请求的request,response是不是传的对,返回的字段值对不对,众多的请求中看得眼花缭乱,如何找到自己想要的请求,那么我们就需要过滤请求.Charles ...