引言

WPF 数据模板化模型为定义数据的表示形式提供了很大的灵活性。WPF 控件有支持自定义数据表示形式的内置功能。首先介绍下如何定义Datatemplate,然后再介绍其他数据模板化功能,例如根据自定义逻辑选择模板和支持显示分层数据。

 

有关 WPF 样式和模板模型的介绍(例如如何使用 Style 来设置控件的属性),请参见样式设置和模板化主题。

另外,了解Resources也很重要,它实际上是有关使对象(例如,StyleDataTemplate)成为可重用对象的内容。有关资源的更多信息,请参见XAML 资源

 

数据模板基础

本节包含下列子节。

 

  • 没有 DataTemplate
  • 定义简单 DataTemplate
  • 将 DataTemplate 创建为资源
  • DataType 属性

主界面:

<Window x:Class="SDKSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SDKSample"
Title="Introduction to Data Templating Sample">
<Window.Resources>
<local:Tasks x:Key="myTodoList"/> ... </Window.Resources>
<StackPanel>
<TextBlock Name="blah" FontSize="20" Text="My Task List:"/>
<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}"/> ... </StackPanel>
</Window>

 

没有 DataTemplate

如果没有 DataTemplate,我们的 ListBox 当前具有如下外观:

 

 

由于没有任何特定说明,ListBox 在尝试显示集合中的对象时,默认情况下会调用 ToString。因此,如果 Task 对象重写 ToString 方法,则 ListBox 显示基础集合中每个源对象的字符串表示形式。

例如,如果 Task 类以这种方式重写 ToString 方法,其中 name 是 TaskName 属性的字段:

 

public override string ToString()
{
return name.ToString();
}

但这样很不灵活,有很多限制。另外,如果要绑定XML的数据,无法重写TOString方法。

 

定义简单 DataTemplate

这样做的一种方式是将 ListBoxItemTemplate 属性设置为 DataTemplateDataTemplate 中指定的内容变成数据对象的可视结构。 以下DataTemplate 相当简单。 我们要给出的说明是:每项显示为 StackPanel 中的三个 TextBlock 元素。 每个 TextBlock 元素绑定到 Task 类的一个属性。

 

<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=TaskName}" />
<TextBlock Text="{Binding Path=Description}"/>
<TextBlock Text="{Binding Path=Priority}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

 

示例的基础数据是 CLR 对象的一个集合。如果要绑定到 XML 数据,则基本概念相同,但是语法有轻微差异。 例如,不是让 Path=TaskName,而是将 XPath 设置为@TaskName(如果 TaskName 是 XML 节点的特性)。

 

将 DataTemplate 创建为资源

 

<Window.Resources>

...

<DataTemplate x:Key="myTaskTemplate">
<StackPanel>
<TextBlock Text="{Binding Path=TaskName}" />
<TextBlock Text="{Binding Path=Description}"/>
<TextBlock Text="{Binding Path=Priority}"/>
</StackPanel>
</DataTemplate> ... </Window.Resources>

 

现在,您可以将 myTaskTemplate 用作资源,如下面的示例所示:

 

<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}"
ItemTemplate="{StaticResource myTaskTemplate}"/>

 

因为 myTaskTemplate 是资源,所以您现在可以在具有采用 DataTemplate 类型的属性的其他控件中使用它。如上所述,对于 ItemsControl 对象(例如 ListBox),它是 ItemTemplate属性。 对于 ContentControl 对象,它是 ContentTemplate 属性。

 

 

DataType 属性

DataTemplate 类具有 DataType 属性,该属性非常类似于 Style 类的 TargetType 属性。因此,在上述示例中不需要为 DataTemplate 指定 x:Key,您可以执行以下操作:

 

<DataTemplate DataType="{x:Type local:Task}">
<StackPanel>
<TextBlock Text="{Binding Path=TaskName}" />
<TextBlock Text="{Binding Path=Description}"/>
<TextBlock Text="{Binding Path=Priority}"/>
</StackPanel>
</DataTemplate>

此 DataTemplate 自动应用于所有 Task 对象。 请注意,在这种情况下,x:Key 是隐式设置的。 因此,如果要为此 DataTemplate 分配一个 x:Key 值,则要重写隐式 x:Key 并且不会自动应用 DataTemplate。

如果要将 ContentControl绑定到 Task 对象的集合,则 ContentControl不会自动使用以上 DataTemplate。 这是因为在 ContentControl上绑定需要更多的信息来区分是要绑定到整个集合还是要绑定到单个对象。 如果 ContentControl要跟踪对 ItemsControl类型的选择,您可以将 ContentControl 绑定的 Path 属性设置为“/”以表示您对当前项感兴趣。 有关示例,请参见如何:绑定到集合并基于选择显示信息。 否则,需要通过设置 ContentTemplate 属性显式指定 DataTemplate。

DataType 属性在您拥有不同类型数据对象的 CompositeCollection 时尤其有用。 有关示例,请参见如何:实现 CompositeCollection

 

向 DataTemplate 添加更多信息

 

当前,数据显示了必要的信息,但是还可以显示更多信息。让我们通过添加 BorderGrid 和一些用于描述要显示的数据的 TextBlock 来显示更多信息。

<DataTemplate x:Key="myTaskTemplate">
<Border Name="border" BorderBrush="Aqua" BorderThickness="1"
Padding="5" Margin="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Task Name:"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=TaskName}" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="Description:"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=Description}"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="Priority:"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Priority}"/>
</Grid>
</Border> ... </DataTemplate>

 

下面的屏幕快照使用此已修改的 DataTemplate 来显示 ListBox

 

我们可以在 ListBox 上将 HorizontalContentAlignment 设置为 Stretch 来确保项的宽度占据整个空间:

 

<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}"
ItemTemplate="{StaticResource myTaskTemplate}"
HorizontalContentAlignment="Stretch"/>

 

 

参考

原文见:http://msdn.microsoft.com/zh-cn/library/ms742521(v=vs.110).aspx

[WPF系列]-数据邦定之DataTemplate简介的更多相关文章

  1. [WPF系列]-数据邦定之DataTemplate 根据对象属性切换模板

      引言 书接上回[WPF系列-数据邦定之DataTemplate],本篇介绍如何根据属性切换模板(DataTemplate)   切换模板的两种方式:   使用DataTemplateSelecto ...

  2. [WPF系列]-数据邦定之DataTemplate 对分层数据的支持

    到目前为止,我们仅讨论如何绑定和显示单个集合. 某些时候,您要绑定的集合包含其他集合. HierarchicalDataTemplate 类专用于 HeaderedItemsControl 类型以显示 ...

  3. [WPF系列]-数据邦定之DataTemplate 使用 DataTrigger 来应用属性值

    使用 DataTrigger 来应用属性值 当前表示不会告诉我们某个 Task 是家庭任务还是办公室任务.记住 Task 对象拥有类型为 TaskType 的 TaskType 属性,该类型是一个枚举 ...

  4. [WPF系列]-数据邦定之DataTemplate 对 ItemsControl 进行样式和模板处理

    引言   即使 ItemsControl 不是 DataTemplate 所用于的唯一控件类型,将 ItemsControl 绑定到集合仍然很常见. 在 DataTemplate 中有哪些内容一节中, ...

  5. ASP.NET中数据邦定效率问题的一点看法 - 转载(自由的天空)

    在 做Asp.NET开发的时候经常用到DataList.Repeater等,用这些控件的时候经常用到数据邦定,很多程序员都是按照MS提供的方 法<%#DataBinder.Eval(Contai ...

  6. fastreport for .net 数据邦定

    C# Code: private void button4_Click(object sender, EventArgs e){   //打印主从表数据    string file = Applic ...

  7. [WPF系列]-TreeView的常用事项

    引言 项目经常会用Treeview来组织一些具有层级结构的数据,本节就将项目使用Treeview常见的问题作一个总结. DataBinding数据绑定 DataTemplate自定义 <Hier ...

  8. [WPF系列]-ListBox

    引言 本文就WPF中的ListBox常用项给以实例代码演示,包括隐蔽属性的设置,Style设置,以及ControlTemplate的自定义.   Listbox平滑滚动 <ListBox Ite ...

  9. WPF系列教程——(二)使用Prism实现MVVM设计模式 - 简书

    原文:WPF系列教程--(二)使用Prism实现MVVM设计模式 - 简书 本文假设你已经知道MVVM设计模式是什么,所以直接进入正题,今天我们就用Prism来实现WPF的MVVM设计模式,百度上关于 ...

随机推荐

  1. WebApi设置SessionState为Required

    public override void Init() { //在注册管道事件中 require session state //只能在引发“HttpApplication.AcquireReques ...

  2. 【Win10开发】处理PC上的后退键

    我们知道在win10手机上和平板上都会有后退键,那么PC上该怎么办呢?没关系我们慢慢揭晓. 如果你已经是UWP的忠实用户,那么肯定会见到如下的后退键. 那么我们如何来做出来呢?, 我们首先打开App. ...

  3. javascript 百度地图API - demo

    <!DOCTYPE html> <html> <head> <meta name="viewport" content="ini ...

  4. python学习笔记11 ----网络编程

    网络编程 网络编程需要知道的概念 网络体系结构就是使用这些用不同媒介连接起来的不同设备和网络系统在不同的应用环境下实现互操作性,并满足各种业务需求的一种粘合剂.网络体系结构解决互质性问题彩是分层方法. ...

  5. 更新整理本人所有博文中提供的代码与工具(Java,2013.11)

    为了更方便地管理博文中涉及的各种代码与工具资源,现在把这些资源迁移到 Google Code 中,有兴趣者可前往下载. Java 1.<高效 Java Web 应用开发框架 JessMA v3. ...

  6. 使用java操作MongoDB

    1.环境准备 下载mongoDB对Java支持的驱动包 驱动包下载地址:https://github.com/mongodb/mongo-java-driver/downloads 2.查询集合中所有 ...

  7. 基于SSH框架的学生公寓管理系统的质量属性

    系统名称:学生公寓管理系统 首先介绍一下学生公寓管理系统,在学生公寓管理方面,针对学生有关住宿信息问题进行管理,学生公寓管理系统主要包含了1)学生信息记录:包括学号.姓名.性别.院系.班级:2)住宿信 ...

  8. jQuery获取Table-Input控件值封装

  9. javascript DOM操作

    看到一个好的dom树.

  10. Objective-C 排序

    在Objective-C中,排序分为: 1.Foundation框架中的对象排序 2.自定义对象排序 例子:每个学生都有一个成绩score属性,根据成绩score对学生排序 自定义对象 Student ...