天天看點

WPF之淺談資料模闆(DataTemplate)

作者:破然立

資料模闆有什麼用

簡而言之,資料模闆能讓你更友善、更靈活的顯示你的各類資料。隻有你想不到,沒有它做不到的(感覺有點誇張,實踐之後,你就覺得一點不誇張 )。

直接對比下效果:

無資料模闆

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
       }           
  1. 在準備好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="[email protected]"},
                   new Employee() {Name="葛倩",Department="人事部",Job="招聘專員",Sex=Sex.Female,Email="[email protected]"},
                   new Employee() {Name="王小偉",Department="研發部",Job="進階軟體工程師",Sex=Sex.Male,Email="[email protected]"},
               };
           }
   
       }           

沒有資料模闆

準備好沒有使用資料模闆的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 #34;{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

繼續閱讀