[WPF系列]-数据邦定之DataTemplate 根据对象属性切换模板
引言
书接上回[WPF系列-数据邦定之DataTemplate],本篇介绍如何根据属性切换模板(DataTemplate)
切换模板的两种方式:
- 使用DataTemplateSelector来切换模板
- 使用DataTrigger来实现模板切换。
- 使用Style来是实现模板切换
A
DataTemplateSelectordoes not respond toPropertyChangenotifications, so it doesn't get re-evaluated when your properties change.The alternative I use is
DataTriggersthat changes theTemplatebased on a property.For example, this will draw all
TaskModelobjects using aContentControl, and theContentControl.Templateis based on theTaskStatusproperty of theTaskModel
使用DataTemplateSelector切换模板
在 DataType 属性一节中,我们讨论了您可以针对不同的数据对象定义不同的数据模板。 这在您拥有不同类型的 CompositeCollection 或不同类型的项集合时尤其有用。 在使用 DataTrigger 来应用属性值一节中,我们演示了如果您拥有相同类型的数据对象集合,您可以创建 DataTemplate,然后根据每个数据对象的属性值使用触发器来应用更改。 虽然触发器允许您应用属性值或启动动画,但是它们无法让您灵活重构数据对象的结构。 在某些情况下,可能需要您为类型相同但属性不同的数据对象创建其他 DataTemplate。
例如,当 Task 对象的 Priority 值为 1 时,您可能需要为它指定完全不同的外观,以给予您自己一个提醒。 在这种情况下,您需要创建 DataTemplate 来显示高优先级的 Task 对象。 让我们将以下 DataTemplate 添加到资源部分:
<DataTemplate x:Key="importantTaskTemplate">
<DataTemplate.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="20"/>
</Style>
</DataTemplate.Resources>
<Border Name="border" BorderBrush="Red" BorderThickness="1"
Padding="5" Margin="5">
<DockPanel HorizontalAlignment="Center">
<TextBlock Text="{Binding Path=Description}" />
<TextBlock>!</TextBlock>
</DockPanel>
</Border>
</DataTemplate>
请注意,此示例使用 DataTemplate.Resources 属性。 DataTemplate 中的元素共享该部分中定义的资源。
若要提供逻辑以根据数据对象的 Priority 值选择要使用的 DataTemplate,需要创建 DataTemplateSelector 的子类并重写 SelectTemplate 方法。 在下面的示例中,SelectTemplate 方法提供逻辑以根据 Priority 属性的值返回适当的模板。 可以在封装 Window 元素的资源中找到要返回的模板。
using System.Windows;
using System.Windows.Controls; namespace SDKSample
{
public class TaskListDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate
SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement; if (element != null && item != null && item is Task)
{
Task taskitem = item as Task; if (taskitem.Priority == 1)
return
element.FindResource("importantTaskTemplate") as DataTemplate;
else
return
element.FindResource("myTaskTemplate") as DataTemplate;
} return null;
}
}
}
然后,我们可以将 TaskListDataTemplateSelector 声明为资源:
<Window.Resources> ... <local:TaskListDataTemplateSelector x:Key="myDataTemplateSelector"/> ... </Window.Resources>
若要使用模板选择器资源,请将其分配到 ListBox 的 ItemTemplateSelector 属性。 ListBox 为基础集合中的每一项调用 TaskListDataTemplateSelector 的 SelectTemplate 方法。 该调用会将数据对象作为项参数来传递。 然后,将由该方法返回的 DataTemplate 应用于该数据对象。
<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}"
ItemTemplateSelector="{StaticResource myDataTemplateSelector}"
HorizontalContentAlignment="Stretch"/>
使用模板选择器后,ListBox 现在如下所示:

这正是此示例要得到的结果。有关完整示例,请参见 Introduction to Data Templating Sample(数据模板化简介示例)
使用Style切换模板
<DataTemplate x:Key="personTemplate" TargetType="{x:Type local:TaskModel}">
<TextBlock Text="I'm an Open Task" />
</DataTemplate>
<DataTemplate x:Key="companyTemplate" TargetType="{x:Type local:TaskModel}">
<TextBlock Text="I'm a Closed Task" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:TaskModel}"><ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding AccountType}" Value="Person">
<Setter Property="ContentTemplate" Value="{StaticResource personTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding AccountType}" Value="Company">
<Setter Property="ContentTemplate" Value="{StaticResource companyTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
上面这个例子没有给一个默认的ContentTemplate,我们可以改为:
<DataTemplate x:Key="OpenTaskTemplate" TargetType="{x:Type local:TaskModel}">
<TextBlock Text="I'm an Open Task" />
</DataTemplate>
<DataTemplate x:Key="ClosedTaskTemplate" TargetType="{x:Type local:TaskModel}">
<TextBlock Text="I'm a Closed Task" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:TaskModel}">
<ContentControl Content="{Binding }">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<!-- Default Template -->
<Setter Property="ContentTemplate" Value="{StaticResource OpenTaskTemplate}" />
<!-- Triggers to change Template -->
<Style.Triggers>
<DataTrigger Binding="{Binding TaskStatus}" Value="Closed">
<Setter Property="ContentTemplate" Value="{StaticResource ClosedTaskTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
使用DataTrigger切换模板
<DataTemplate DataType="{x:Type viewModels:CorePlugViewModel}">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ShowGridLines="True" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Name}" Margin="4"></TextBlock>
<ContentControl x:Name="viewBox" Grid.Row="1" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Image Source="{Binding MapThumbnail}" />
</ContentControl>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding HasMap}" Value="True">
<Setter Property="Template" TargetName="viewBox">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContentControl}">
<views:CorePlugWithMap VerticalAlignment="Stretch" HorizontalAlignment="Stretch" MinHeight="10"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
如果您的 Setters 相关属性不是当前 DataTemplate 中元素的属性,则使用 Style(用于 ListBoxItem 类)设置属性更合适(如果您要绑定的控件是 ListBox)。
比较
| 方式 | 注意事项 | 适用 |
| DataTemplateSelector | 无法相应propertyChanged事件 | 静态更改模板 |
| StyleTriger | 能够动态更改绑定模板 | |
| DataTriger | Setters 相关属性不是当前 DataTemplate 中元素的属性,则使用 Style | 能够动态更改绑定模板 |
参考
Change Data template dynamically
[WPF系列]-数据邦定之DataTemplate 根据对象属性切换模板的更多相关文章
- [WPF系列]-数据邦定之DataTemplate 对分层数据的支持
到目前为止,我们仅讨论如何绑定和显示单个集合. 某些时候,您要绑定的集合包含其他集合. HierarchicalDataTemplate 类专用于 HeaderedItemsControl 类型以显示 ...
- [WPF系列]-数据邦定之DataTemplate简介
引言 WPF 数据模板化模型为定义数据的表示形式提供了很大的灵活性.WPF 控件有支持自定义数据表示形式的内置功能.首先介绍下如何定义Datatemplate,然后再介绍其他数据模板化功能,例如根据自 ...
- [WPF系列]-数据邦定之DataTemplate 使用 DataTrigger 来应用属性值
使用 DataTrigger 来应用属性值 当前表示不会告诉我们某个 Task 是家庭任务还是办公室任务.记住 Task 对象拥有类型为 TaskType 的 TaskType 属性,该类型是一个枚举 ...
- [WPF系列]-数据邦定之DataTemplate 对 ItemsControl 进行样式和模板处理
引言 即使 ItemsControl 不是 DataTemplate 所用于的唯一控件类型,将 ItemsControl 绑定到集合仍然很常见. 在 DataTemplate 中有哪些内容一节中, ...
- ASP.NET中数据邦定效率问题的一点看法 - 转载(自由的天空)
在 做Asp.NET开发的时候经常用到DataList.Repeater等,用这些控件的时候经常用到数据邦定,很多程序员都是按照MS提供的方 法<%#DataBinder.Eval(Contai ...
- js系列教程2-对象、构造函数、对象属性全解
全栈工程师开发手册 (作者:栾鹏) 快捷链接: js系列教程1-数组操作全解 js系列教程2-对象和属性全解 js系列教程3-字符串和正则全解 js系列教程4-函数与参数全解 js系列教程5-容器和算 ...
- fastreport for .net 数据邦定
C# Code: private void button4_Click(object sender, EventArgs e){ //打印主从表数据 string file = Applic ...
- [WPF系列]-ListBox
引言 本文就WPF中的ListBox常用项给以实例代码演示,包括隐蔽属性的设置,Style设置,以及ControlTemplate的自定义. Listbox平滑滚动 <ListBox Ite ...
- [WPF系列]-TreeView的常用事项
引言 项目经常会用Treeview来组织一些具有层级结构的数据,本节就将项目使用Treeview常见的问题作一个总结. DataBinding数据绑定 DataTemplate自定义 <Hier ...
随机推荐
- 在c#中get同步访问http
参照文章:http://blog.csdn.net/qianmenfei/article/details/37974767 public static string SendMessage(strin ...
- Extjs.Button 按钮
Extjs Button 的简单使用 ,同时调用Ajax服务 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xh ...
- html5数字和颜色输入框
html5功能强大,数字和颜色输入框例子 效果:http://hovertree.com/code/html5/rxujb6g8.htm <!DOCTYPE html> <html& ...
- Asp.net mvc自定义Filter简单使用
自定义Filter的基本思路是继承基类ActionFilterAttribute,并根据实际需要重写OnActionExecuting,OnActionExecuted,OnResultExecuti ...
- 学习.NET是因为热爱 or 兴趣 or 挣钱?
看到最近园子里掀起了“.NET快不行了”.“.NET工资太低了”.“转行做XX”等一系列之风,不由得想说点什么,我只是基于自己的观点,你认同或者不认同,我就是这样认为,无所谓对与错,写文章就是为了交流 ...
- 前端工程师如何快速的开发一个微信JSSDK应用
亲们,订阅号出来已经很久了,作为一个前端工程师或者全栈工程师,你是不是错过了什么?大概许多攻城狮同砚还没有反应过来订阅号怎么回事,就马上要被微信的应用号秀一脸了.在应用号还没有正式出来之前,我们赶紧一 ...
- PHP
* PHP语言1.基本内容 * PHP语言 - 类似于javascript语言的 * javascript是客户端(HTML)的脚本语言 * PHP是服务器端的脚本语言 * PHP文件的扩展名为&qu ...
- AO安装需要Microsoft Visual Studio 2013?
从接触ArcGIS9.2到 10.4,在不断升级的 过程中,既给我们带来了很多惊喜,也带来一些麻烦,因为ArcGIS版本不兼容.出于体验,安装了ArcGIS Desktop10.4,AO也得升到10. ...
- [深入学习Web安全](5)详解MySQL注射
[深入学习Web安全](5)详解MySQL注射 0x00 目录 0x00 目录 0x01 MySQL注射的简单介绍 0x02 对于information_schema库的研究 0x03 注射第一步—— ...
- SharePoint 2013 扩展查阅项功能
SharePoint 2013的查阅项功能,就是可以扩展其他列表字段为当前列表选项,但是选项太多的时候,会造成选择起来非常麻烦,所以,我们采取JS+Ajax的方式,改善一下这个展示,使操作更加方便. ...