首页 > 其他分享 >WPF中如何根据数据类型使用不同的数据模板

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

时间:2024-08-31 22:21:40浏览次数:13  
标签:10 get 数据类型 DataTemplate DataTemplateSelector new WPF public 模板

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

例如将一个文件夹集合绑定到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,get,数据类型,DataTemplate,DataTemplateSelector,new,WPF,public,模板
From: https://blog.csdn.net/zhaotianff/article/details/141569434

相关文章

  • 设计模式之模板模式和策略模式-----------超级超级详细!超级全面!
    1.模板模式的定义一个抽象类,公开定义了执行自己的方法/模板。它的子类可以按需重写方法实现,但调用需要按照抽象类中的定义的方式/模板进行。这种类型的设计模式属于行为性模式之一。用于定义一个操作中的算法的框架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个......
  • 用模板30分钟完成人力资源网站,制作到上线的全流程
    疫情对线下企业的冲击非常大,2023年疫情基本结束,线下行业开始复苏,我们成立了自己的人力资源公司。由于企业刚起步,也没有太多的预算来进行网络方面的投入,但在疫情期间我们见识了互联网的重要性,因此计划给自己公司做一个简单的官网,这样可以让客户直接可以在百度搜到我们公司信息,......
  • Markdown通用模板
    要使用好AI工具,写好prompt(提示词)是非常重要的,提示词至少要有角色、上下文、任务。专家们提供了很多结构化提示词的框架,比如ICDO,BROKE,CRISP等,你知道哪些提示词框架?如果不知道,通过搜索工具或者AI工具学习一个。Markdown是结构化prompt的好方法,请为你学习的prompt框架使用Markdown......
  • python基础三之基本数据类型
    1.数字类型及操作1.1整数类型  可正可负,没有取值范围限制pow(x,y) 计算x的y次方,想算多大算多大4种进制表示形式十进制:如:1019,8,-8二进制:由0b或0B开头,只由0,1组成,如:0b0110,-0B101010101八进制:由0O或0o开头:0O123,-0O445十六进制:又0X或0x开头:0X89,-0x9a1.2......
  • 模板方法模式:如何实现同一模板框架下的算法扩展?
    模板方法模式的原理和代码实现都比较简单,在软件开发中也被广泛应用,但是因为使用继承机制,副作用往往盖过了主要作用,所以在使用时尤其要小心谨慎。一、模式原理分析模板方法模式原始定义是:在操作中定义算法的框架,将一些步骤推迟到子类中。模板方法让子类在不改变算法结构的......
  • PHP数据类型
    PHP变量存储不同的类型的数据,不同的数据类型可以做不一样的事情。PHP支持以下几种数据类型:String(字符串)Integer(整型)Float(浮点型)Boolean(布尔型)Array(数组)Object(对象)NULL(空值)Resource(资源类型)字符串一个字符串是一串字符的序列,就像"Helloworld!"。你可以将任何文本......
  • 3.从对变量的理解到数据类型的一种解释
    1变量1.1变量在使用过程中有三点注意事项1.变量必须是字母数字和下划线组成2.变量的命名开头不能是数字,数字会与python中的数字重复,导致错误3.变量不能使用内置的字,如print1.2变量的规范1.一般情况下需要进行分割,就是用_2.变量在使用的过程中也要注意,不要乱命名,会导致后续......
  • 常用背包dp模板(未完待续)
    部分板子优化中...你好哇,我是flypig114代码里有各部分及变量数组的注释,so...不多废话,直接上正题!01背包无优化#include<bits/stdc++.h>usingnamespacestd;#definellint//为了方便修改类型constllN=1000;//辅助定义数组lln,m;//n是背包容量m是物品数量llv[N],......
  • .NET|--WPF|--笔记合集|--依赖项属性|--2.注册依赖项属性
    前言使用一个实例,其实分2步骤定义,实例化.但是依赖项属性为不能直接实例化,因为DependencyProperty类没有公开的构造函数,只能使用静态的DependencyProperty.Register方法创建DependencyProperty实例.DependencyProperty.Register源码//System.Windows.DependencyP......
  • .NET|--WPF|--笔记合集|--依赖项属性|--1.定义依赖项属性
    前言一般情况下,我们是不用定义依赖项属性的,更多的是直接使用即可.那么何时需要我们定义依赖项属性呢?1.设计自定义的WPF元素;2.为原本不支持数据绑定,动画等WPF功能的代码中,需要添加数据绑定,动画等WPF功能时.定义依赖项属性一般的类型来说,如果想要使用的......