[WPF系列]-数据邦定之DataTemplate 根据对象属性切换模板
引言
书接上回[WPF系列-数据邦定之DataTemplate],本篇介绍如何根据属性切换模板(DataTemplate)
切换模板的两种方式:
- 使用DataTemplateSelector来切换模板
- 使用DataTrigger来实现模板切换。
- 使用Style来是实现模板切换
A
DataTemplateSelector
does not respond toPropertyChange
notifications, so it doesn't get re-evaluated when your properties change.The alternative I use is
DataTriggers
that changes theTemplate
based on a property.For example, this will draw all
TaskModel
objects using aContentControl
, and theContentControl.Template
is based on theTaskStatus
property 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 ...
随机推荐
- openfire 初始密码
openfire 初始密码 mssql2014 进入数据库,找到 ofUser 表 ,将密码字段对应的密文替换为下面的内容,则密码就是 admin ecbd03623cd819c48718db1b27 ...
- [Excel] Worksheet.PasteSpecial
PasteSpecial(Format, Link, DisplayAsIcon, IconFileName, IconIndex, IconLabel, NoHTMLFormatting) 1. F ...
- 【C#公共帮助类】枚举独特类
这个是枚举类,可能大家根据个人需求不同,不是很需要,但是跟着做那个项目的朋友会用到 我在这贴一下代码 using System; using System.Collections.Generic; u ...
- file_get_contents()/file_put_contents()
PHP file_get_contents() 函数 定义和用法 file_get_contents() 把整个文件读入一个字符串中. 该函数是用于把文件的内容读入到一个字符串中的首选方法.如果服务器 ...
- php 使用htmlspecialchars() 和strip_tags函数过滤HTML标签的区别
原文地址:http://www.manongjc.com/article/1103.html 先来看一下htmlspecialchars函数和strip_tags函数的使用实例: <?php $ ...
- Code First :使用Entity. Framework编程(7) ----转发 收藏
第7章 高级概念 The Code First modeling functionality that you have seen so far should be enough to get you ...
- 使用 jQuery 和 CSS3 制作滑动导航菜单
这个下拉菜单可以让你的网站非常优雅,滑动框导航效果令人印象深刻.此外,子菜单框也可以与此集成起来以使其更具吸引力.导航是网站成功的关键之一,有吸引力的导航能够引导用户浏览网站中的更多内容. 效果演示 ...
- 【单页应用巨坑之History】细数History带给单页应用的噩梦
前言 在我们日常的网页浏览中,我们非常喜欢做一个操作:点击浏览器的前进后退在Ajax技术出现后,有些时候前进后退就会给开发者带来困扰,甚至一些开发者试图去干掉History随着Html5的发展,移动端 ...
- css(一)
CSS CSS是Cascading Style Sheets的简称,中文称为层叠样式表,用来控制网页数据的表现,可以使网页的表现与数据内容分离. 一 css的四种引入方式 1.行内式 ...
- 发布有礼!2015 Autodesk程序商店有奖发布活动拉开序幕
您是不是有希望您的 Autodesk 产品应用程序有更多的用户?您是不是正在寻求更广阔的市场机会?您是不是在激荡人心的云时代大潮中有许多奇思妙想没有小试身手? 来吧,来参加Autodesk应用程序发布 ...