WPF中如何根据数据类型使用不同的数据模板

我们在将一个数据集合绑定到列表控件时,有时候想根据不同的数据类型,显示为不同的效果。

例如将一个文件夹集合绑定到ListBox时,系统文件夹和普通文件夹分别显示为不同的效果,就可以使用模板选择器功能。

WPF提供了一个模板选择器类型DataTemplateSelector,它可以根据数据对象和数据绑定元素来选择 DataTemplate

使用方法

创建一个类,继承自DataTemplateSelector,并重写SelectTemplate方法。

类似下面这样

 1 using System.Windows;
 2 using System.Windows.Controls;
 3 
 4 namespace SDKSample
 5 {
 6     public class TaskListDataTemplateSelector : DataTemplateSelector
 7     {
 8         public override DataTemplate
 9             SelectTemplate(object item, DependencyObject container)
10         {
11             FrameworkElement element = container as FrameworkElement;
12 
13             if (element != null && item != null && item is Task)
14             {
15                 Task taskitem = item as Task;
16 
17                 if (taskitem.Priority == 1)
18                     return
19                         element.FindResource("importantTaskTemplate") as DataTemplate;
20                 else
21                     return
22                         element.FindResource("myTaskTemplate") as DataTemplate;
23             }
24 
25             return null;
26         }
27     }
28 }

下面我们使用ListBoxTreeView进行演示

ListBox的使用示例

我们先定义如下的数据模型

 1  public class FileData
 2  {
 3      public string FileName { get; set; }
 4  }
 5 
 6  public class FileData1 : FileData
 7  {
 8      public string FileData1Property { get; set; }
 9  }
10 
11  public class FileData2:FileData
12  {
13      public string FileData2Property { get; set; }
14  }

然后定义一个资源字典,分别在里面定义两种数据的数据模板

 1 <DataTemplate x:Key="FileData1Datatemplate">
 2     <Grid>
 3         <Grid.ColumnDefinitions>
 4             <ColumnDefinition/>
 5             <ColumnDefinition/>
 6         </Grid.ColumnDefinitions>
 7         <Label Content="{Binding FileName}" FontSize="20" Foreground="Green"></Label>
 8         <Label Content="{Binding FileData1Property}" Grid.Column="1" VerticalAlignment="Center"></Label>
 9     </Grid>
10 </DataTemplate>
11 
12 <DataTemplate x:Key="FileData2Datatemplate">
13     <Grid>
14         <Grid.ColumnDefinitions>
15             <ColumnDefinition/>
16             <ColumnDefinition/>
17         </Grid.ColumnDefinitions>
18         <Label Content="{Binding FileName}" FontSize="16" Foreground="Red"></Label>
19         <Label Content="{Binding FileData2Property}" Grid.Column="1" VerticalAlignment="Center"></Label>
20     </Grid>
21 </DataTemplate>

添加测试数据

 1  List<FileData> fileDatas = new List<FileData>();
 2  FileData1 fileData1 = new FileData1();
 3  fileData1.FileName = "1.jpg";
 4  fileData1.FileData1Property = "1.jpg property";
 5  FileData2 fileData2 = new FileData2();
 6  fileData2.FileName = "2.jpg";
 7  fileData2.FileData2Property = "2.jpg property";
 8  fileDatas.Add(fileData1);
 9  fileDatas.Add(fileData2);
10  this.listbox.ItemsSource = fileDatas;

然后再为ListBox设置DataTemplateSelector

1  this.listbox.ItemTemplateSelector = new ItemDataTemplateSelector();

运行效果如下:

TreeView的使用示例

这里我们定义一个磁盘和文件夹的数据类型,一个磁盘对象可以包含多个文件夹

 1  public class Disk
 2  {
 3      public string DiskName { get; set; }
 4 
 5      public List<Folder> Folders { get; set; } = new List<Folder>();
 6  }
 7 
 8  public class Folder
 9  {
10      public string FullPath { get; set; }
11 
12      public long Size { get; set; }
13  }

使用使用HierarchicalDataTemplateTreeView设置层级的数据模板

针对DiskHierarchicalDataTemplate

 1 <HierarchicalDataTemplate x:Key="DiskDatatemplate" ItemsSource="{Binding Folders}" DataType="{x:Type local:Disk}">
 2     <Grid>
 3         <Grid.ColumnDefinitions>
 4             <ColumnDefinition Width="25"/>
 5             <ColumnDefinition/>
 6         </Grid.ColumnDefinitions>
 7 
 8         <Image Source="disk.png" Height="25"></Image>
 9         <Label Content="{Binding DiskName}" Grid.Column="1"></Label>
10     </Grid>
11 </HierarchicalDataTemplate>

针对FolderHierarchicalDataTemplate

 1  <HierarchicalDataTemplate x:Key="FolderDatatemplate" DataType="{x:Type local:Folder}">
 2      <Grid>
 3          <Grid.ColumnDefinitions>
 4              <ColumnDefinition Width="25"/>
 5              <ColumnDefinition Width="auto"/>
 6              <ColumnDefinition/>
 7          </Grid.ColumnDefinitions>
 8 
 9          <Image Source="folder.png" Height="25"></Image>
10          <Label Content="{Binding FullPath}" Grid.Column="1"></Label>
11          <Label Content="{Binding Size}" Grid.Column="2"></Label>
12      </Grid>
13  </HierarchicalDataTemplate>

然后我们创建一个DataTemplateSelector,根据不同的数据类型返回不同的HierarchicalDataTemplate

这里仅做演示,实际使用时推荐使用switch并增加错误检测。

 1  public class NodeDataTemplateSelector : DataTemplateSelector
 2  {
 3      public override DataTemplate SelectTemplate(object item, DependencyObject container)
 4      {
 5          if (item is Disk)
 6              return Application.Current.FindResource("DiskDatatemplate") as DataTemplate;
 7          else
 8              return Application.Current.FindResource("FolderDatatemplate") as DataTemplate;
 9      }
10  }

添加测试数据

 1 Disk disk = new Disk();
 2 disk.DiskName = "D:\\";
 3 
 4 Folder folder = new Folder();
 5 folder.FullPath = "D:\\Software";
 6 folder.Size = 1024;
 7 disk.Folders.Add(folder);
 8 
 9 Disk disk2 = new Disk();
10 disk2.DiskName = "E:\\";
11 
12 Folder folder2 = new Folder();
13 folder2.FullPath = "E:\\Documents";
14 folder2.Size = 2048;
15 disk2.Folders.Add(folder2);
16 
17 List<Disk> disks = new List<Disk>();
18 disks.Add(disk);
19 disks.Add(disk2);
20 
21 this.treeview.ItemsSource = disks;

TreeView设置DataTemplateSelector

1   this.treeview.ItemTemplateSelector = new NodeDataTemplateSelector();

运行效果

示例代码

github

参考资料:

DataTemplateSelector 类 (System.Windows.Controls) | Microsoft Learn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值