數(shù)據(jù)模板有什么用
簡而言之,數(shù)據(jù)模板能讓你更方便、更靈活的顯示你的各類數(shù)據(jù)。只有你想不到,沒有它做不到的(感覺有點(diǎn)夸張,實(shí)踐之后,你就覺得一點(diǎn)不夸張 :sunglasses:)。
直接對比下效果:
無數(shù)據(jù)模板

應(yīng)用了數(shù)據(jù)模板

好了,下面我們一步一步來看看數(shù)據(jù)模板如何做到化腐朽為神奇的!
一些前置條件
假設(shè)你已了解了MVVM設(shè)計(jì)模式
假設(shè)你已了解了一些數(shù)據(jù)綁定知識
假設(shè)你已了解了一些樣式知識
代碼準(zhǔn)備
-
首先準(zhǔn)備一個(gè)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 } -
在準(zhǔn)備好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="技術(shù)售后部",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="研發(fā)部",Job="高級軟件工程師",Sex=Sex.Male,Email="Wang.Xiaowei@wpf.com"}, }; } }
沒有數(shù)據(jù)模板
準(zhǔn)備好沒有使用數(shù)據(jù)模板的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>
運(yùn)行下程序,就會出現(xiàn)這樣的界面

熟悉.Net的同學(xué),應(yīng)該看出來每一項(xiàng)顯示的是對象的ToString方法返回的值。因?yàn)槲覀兗现写娣诺氖菑?fù)雜類型的對象,如果沒有數(shù)據(jù)模板,ListBox默認(rèn)就會用ToString去顯示。而ToString方法默認(rèn)返回的就是對象的類型限定名。
既然了解到這個(gè)原理,那我們重載實(shí)現(xiàn)下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}";
}
}
再次運(yùn)行程序,結(jié)果如下

這次算是顯示出一些有用信息了,但這樣的UI體驗(yàn),未免太差。如何讓我們的數(shù)據(jù)呈現(xiàn)更加吸引人呢?下面就輪到數(shù)據(jù)模板大顯身手了。
應(yīng)用數(shù)據(jù)模板
直接上應(yīng)用了數(shù)據(jù)模板的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>
其實(shí)數(shù)據(jù)模板就是把對象的屬性綁定到不同的UI控件上,然后通過合理的布局,就能顯示讓數(shù)據(jù)顯示的更加美觀了。

怎么樣?效果完全就不一樣了,到這里,相信同學(xué)你應(yīng)該能get到數(shù)據(jù)模板的作用了!當(dāng)然這個(gè)只是數(shù)據(jù)模板的最基本用法,其實(shí)數(shù)據(jù)模板還有其他更強(qiáng)大的功能。比如可以通過數(shù)據(jù)模板讓男性員工的名字顯示成淡藍(lán)色,女性的名字顯示成淡綠色。這個(gè)功能下面觸發(fā)器的部分會介紹。
我們還是接著數(shù)據(jù)模板定義這部分內(nèi)容,我們是通過重寫了ListBox.ItemTemplate來定義數(shù)據(jù)模板的,但如果在其他控件我們也要顯示這樣,豈不是在定義一遍這個(gè)數(shù)據(jù)模板?這樣明顯不符合我們代碼復(fù)用的原則。還好,在wpf中,我們可以通過資源的方式來定義通用的數(shù)據(jù)模板,代碼如下
<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>
此時(shí)我們發(fā)現(xiàn),并不需要重新定義ListBox.ItemTemplate,但運(yùn)行結(jié)果和上面保持一致!
數(shù)據(jù)觸發(fā)器
前面我們提到可以通過數(shù)據(jù)模板讓男性員工的名字顯示成淡藍(lán)色,女性的名字顯示成淡綠色,其實(shí)就可以通過數(shù)據(jù)觸發(fā)器來實(shí)現(xiàn)這樣的功能。
這里簡單說下觸發(fā)器的作用,更詳細(xì)的去看[微軟的官方文檔](DataTrigger Class (System.Windows) | Microsoft Learn)。觸發(fā)器就是當(dāng)綁定的數(shù)據(jù)滿足某個(gè)條件時(shí),可以去設(shè)置一些控件的屬性值,或者執(zhí)行一些動作(例如動畫)。
基于觸發(fā)器原理,實(shí)現(xiàn)的代碼如下
<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>
運(yùn)行結(jié)果

我們可以看到是通過修改顯示名字的TextBlock的字體顏色來實(shí)現(xiàn)我們需求的,其實(shí)我們可以同時(shí)設(shè)置多個(gè)控件的屬性來滿足更復(fù)雜的需求的。
到這里,淺談數(shù)據(jù)模板就接近尾聲了,所謂淺談,其實(shí)把數(shù)據(jù)模板的核心用法都覆蓋到了,在實(shí)際項(xiàng)目開發(fā)中,都是基于這些知識的靈活應(yīng)用!
最后
奉上源代碼 https://gitee.com/liuww06/wpfpractice/tree/master/src/WpfPractice.DataTemplateDemo