WPF之浅谈数据模板(DataTemplate)

  • WPF之浅谈数据模板(DataTemplate)已关闭评论
  • 245 次浏览
  • A+
所属分类:.NET技术
摘要

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


数据模板有什么用

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

直接对比下效果:

无数据模板

WPF之浅谈数据模板(DataTemplate)

应用了数据模板

WPF之浅谈数据模板(DataTemplate)

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

一些前置条件

  • 假设你已了解了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> 

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

WPF之浅谈数据模板(DataTemplate)

熟悉.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}";         }     } 

再次运行程序,结果如下

WPF之浅谈数据模板(DataTemplate)

这次算是显示出一些有用信息了,但这样的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控件上,然后通过合理的布局,就能显示让数据显示的更加美观了。

WPF之浅谈数据模板(DataTemplate)

怎么样?效果完全就不一样了,到这里,相信同学你应该能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> 

运行结果
WPF之浅谈数据模板(DataTemplate)

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

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

最后

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