如果把控件的功能视为内容,则可以使用控件模板 ControlTemplate 来控制它的展现;

如果把数据视为内容,则可以使用数据模板 DataTemplate 把数据展示出来;

ControlTemplate 是算法内容的表现形式,一个控件怎样组织其内部结构才让它更符合业务逻辑、让用户操作起来更舒服就是由它来控制的;

DataTemplate 是数据内容的表现形式,一条数据是简单的文本还是图形动画还是其他,由它决定。

1. DataTemplate

1.1 一条柱状图的 DataTemplate 举例

<DataTemplate x:Key="dt">
<Grid>
<StackPanel Orientation="Horizontal">
<Grid>
<Rectangle Width="{Binding Price}" Fill="LightSalmon"/>
<TextBlock Text="{Binding Year}"></TextBlock>
</Grid>
<TextBlock Text="{Binding Price}"></TextBlock>
</StackPanel>
</Grid>
</DataTemplate>

1.2 常用 DataTemplate 的 3 处地方

ContentControl 的 ContentTemplate 属性,给 ContentControl 的内容穿衣服;

ItemsControl 的 ItemTemplate 属性,给 ItemsControl 的数据条目穿衣服;

GridViewColumn 的 CellTemplate 属性,给 GridViewColumn 单元格里的数据穿衣服。

1.3 使用 DataTemplate 实现一个汽车列表和详情

<Window x:Class="WpfAppTemplate.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfAppTemplate"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="623">
<Window.Resources>
<local:NameToPhotoPathConverter x:Key="nameToPhotoPathConverter"/> <!--集合条目的内容模板-->
<DataTemplate x:Key="carListItemViewTemplate">
<Grid Margin="2">
<StackPanel Orientation="Horizontal">
<Image Height="60" Width="64"
Source="{Binding Name, Converter={StaticResource nameToPhotoPathConverter}}" />
<StackPanel Margin="5 12">
<TextBlock Text="Name" FontWeight="Bold"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</StackPanel>
</Grid>
</DataTemplate> <!--详情的内容模板-->
<DataTemplate x:Key="carDetailViewTemplate">
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="6" Margin="2">
<StackPanel Margin="5">
<Image Height="250" Width="400"
Source="{Binding Name, Converter={StaticResource nameToPhotoPathConverter}}" />
<StackPanel Orientation="Horizontal" Margin="5,0">
<TextBlock Text="Name:" FontWeight="Bold" FontSize="19"/>
<TextBlock Text="{Binding Name}" FontSize="19"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="5 0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Year:" FontWeight="Bold"/>
<TextBlock Text="{Binding Year}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="5 0">
<TextBlock Text="TopSpeed:" FontWeight="Bold"/>
<TextBlock Text="{Binding TopSpeed}"/>
</StackPanel>
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</Window.Resources> <Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions> <UserControl x:Name="carDetailControl"
ContentTemplate="{StaticResource carDetailViewTemplate}"
Content="{Binding ElementName=listBoxCar, Path=SelectedItem}" /> <ListBox Grid.Column="1" x:Name="listBoxCar" Margin="2"
ItemTemplate="{StaticResource carListItemViewTemplate}" />
</Grid>
</Window> public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
InitializeList();
} /// <summary>
/// 添加汽车种类
/// </summary>
void InitializeList()
{
List<Car> carList = new List<Car>();
carList.Add(new Car() { Name = "BMW", TopSpeed = "260", Year = "1997" });
carList.Add(new Car() { Name = "Audi", TopSpeed = "240", Year = "1999" });
carList.Add(new Car() { Name = "Toyota", TopSpeed = "120", Year = "2016" });
carList.Add(new Car() { Name = "Volkswagen", TopSpeed = "150", Year = "2000" }); this.listBoxCar.ItemsSource = carList;
}
}

1.4 而如果不用 DataTemplate ,就会显得比较繁琐且冗长

使用 winform 的 Usercontrol 实现一个汽车列表和详情

<!--汽车详情-->
<UserControl x:Class="WpfAppTemplate.UserControls.CarDetailUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfAppTemplate.UserControls"
mc:Ignorable="d" >
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="6" Margin="2">
<StackPanel Margin="5">
<Image x:Name="img" Height="250" Width="400"/> <StackPanel Orientation="Horizontal" Margin="5,0">
<TextBlock Text="Name:" FontWeight="Bold" FontSize="19"/>
<TextBlock x:Name="textBlockName" FontSize="19"/>
</StackPanel> <StackPanel Orientation="Horizontal" Margin="5 0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Year:" FontWeight="Bold"/>
<TextBlock x:Name="textBlockYear"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="5 0">
<TextBlock Text="TopSpeed:" FontWeight="Bold"/>
<TextBlock x:Name="textBlockTopSpeed"/>
</StackPanel>
</StackPanel> </StackPanel>
</Border>
</UserControl> public partial class CarDetailUserControl : UserControl
{
public CarDetailUserControl()
{
InitializeComponent();
} Car _currentCar;
public Car CurrentCar
{
get { return _currentCar; }
set
{
if (value == null) return;
_currentCar = value;
this.textBlockName.Text = value.Name;
this.textBlockTopSpeed.Text = value.TopSpeed;
this.textBlockYear.Text = value.Year;
string uriStr = string.Format(@"/Resources/Images/Cars/{0}.jpg", value.Name);
this.img.Source = new BitmapImage(new Uri(uriStr, UriKind.Relative));
}
}
} <!--汽车条目-->
<UserControl x:Class="WpfAppTemplate.UserControls.CarListItemUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfAppTemplate.UserControls"
mc:Ignorable="d">
<Grid Margin="2">
<StackPanel Orientation="Horizontal">
<Image x:Name="img" Height="60" Width="64"/>
<StackPanel Margin="5 12">
<TextBlock Text="Name" FontWeight="Bold"/>
<TextBlock x:Name="textBlockName" />
</StackPanel>
</StackPanel>
</Grid>
</UserControl> public partial class CarListItemUserControl : UserControl
{
public CarListItemUserControl()
{
InitializeComponent();
} Car _currentCar;
public Car CurrentCar
{
get { return _currentCar; }
set
{
if (value == null) return; _currentCar = value;
this.textBlockName.Text = value.Name;
string uriStr = string.Format(@"/Resources/Images/Cars/{0}.jpg", value.Name);
this.img.Source = new BitmapImage(new Uri(uriStr, UriKind.Relative));
}
}
} <!--主窗体-->
<Window x:Class="WpfAppTemplate.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfAppTemplate"
xmlns:localUserControls="clr-namespace:WpfAppTemplate.UserControls"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="623">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions> <localUserControls:CarDetailUserControl x:Name="carDetailControl"/> <ListBox Grid.Column="1" x:Name="listBoxCar" SelectionChanged="listBoxCar_SelectionChanged" Margin="2"/>
</Grid>
</Window> public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
InitializeList();
} /// <summary>
/// 添加汽车种类
/// </summary>
void InitializeList()
{
List<Car> carList = new List<Car>();
carList.Add(new Car() { Name = "BMW", TopSpeed = "260", Year = "1997" });
carList.Add(new Car() { Name = "Audi", TopSpeed = "240", Year = "1999" });
carList.Add(new Car() { Name = "Toyota", TopSpeed = "120", Year = "2016" });
carList.Add(new Car() { Name = "Volkswagen", TopSpeed = "150", Year = "2000" }); // 给每种汽车生成一个 汽车条目控件,作为一条内容添加到汽车列表控件的内容集合
foreach (Car car in carList)
{
CarListItemUserControl control = new CarListItemUserControl();
control.CurrentCar = car;
this.listBoxCar.Items.Add(control);
}
} /// <summary>
/// 当切换汽车时
/// </summary>
/// <param name="sender">listbox</param>
/// <param name="e">SelectionChangedEventArgs, 可以通过 AddedItems 参数取到新选择的项</param>
private void listBoxCar_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
CarListItemUserControl control = e.AddedItems[0] as CarListItemUserControl;
if (control != null)
{
this.carDetailControl.CurrentCar = control.CurrentCar;
}
}
}

WPF 基础 - DataTemplate的更多相关文章

  1. WPF 基础 - DataTemplate 和 ControlTemplate 的关系和应用

    1. 关系 凡是 Template,最后都得作用到 控件 上,这个控件就是 Template 的目标控件(也称模板化控件): DataTemplate 一般是落实在一个 ContentPresente ...

  2. WPF基础到企业应用系列6——布局全接触

    本文转自:http://knightswarrior.blog.51cto.com/1792698/365351 一. 摘要 首先很高兴这个系列能得到大家的关注和支持,这段时间一直在研究Windows ...

  3. WPF 基础到企业应用系列索引

    转自:http://www.cnblogs.com/zenghongliang/archive/2010/07/09/1774141.html WPF 基础到企业应用系列索引 WPF 基础到企业应用系 ...

  4. WPF笔记(1.1 WPF基础)——Hello,WPF!

    原文:WPF笔记(1.1 WPF基础)--Hello,WPF! Example 1-1. Minimal C# WPF application// MyApp.csusing System;using ...

  5. WPF 遍历DataTemplate(获取所有控件)

    原文:WPF 遍历DataTemplate(获取所有控件) 情况1:在设定DataTemplate的Name,并且他是在前台表示时,获取DataTemplate里的指定控件. 方法: http://b ...

  6. C# WPF基础巩固

    时间如流水,只能流去不流回. 学历代表你的过去,能力代表你的现在,学习能力代表你的将来. 学无止境,精益求精. 一.写作目的 做C# WPF开发,无论是工作中即将使用,还是只应付跳槽面试,开发基础是非 ...

  7. WPF基础知识、界面布局及控件Binding(转)

    WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...

  8. WPF基础知识、界面布局及控件Binding

    WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...

  9. wpf ListView DataTemplate方式的鼠标悬停和选中更改背景色

    今天使用wpf技术弄一个ListView的时候,由于需求需要,需要ListView显示不同的数据模板,很自然的使用了DataTemplate方式来定义多个数据模板,并在ListView中使用ItemT ...

随机推荐

  1. 关于TCP状态TIME_WAIT的理解

    1.TIME_WAIT的作用: TIME_WAIT状态存在的理由:1)可靠地实现TCP全双工连接的终止 在进行关闭连接四次挥手协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器 ...

  2. dll的注册与反注册

    regsvr32.exe是32位系统下使用的DLL注册和反注册工具,使用它必须通过命令行的方式使用,格式是:regsvr32 [/i[:cmdline]] DLL文件名命令可以在"开始→运行 ...

  3. HDU - 5115 Dire Wolf (非原创)

    Dire wolves, also known as Dark wolves, are extraordinarily large and powerful wolves. Many, if not ...

  4. Git使用指南(下)

    9 初识分支 把每一次的提交,都用线连起来,你会发现,很连贯. C/C++    指针的概念 git reset --hard commitid HEAD    如果说内容已经add到暂存区,此时要想 ...

  5. we have a problem with promise

    we have a problem with promise Q: What is the difference between these four promises? doSomething() ...

  6. SwiftUI error All In One

    SwiftUI error All In One Instance member xxx cannot be used on type yyy Instance member 'game' canno ...

  7. Error: Cannot find module 'koa-router'

    Error: Cannot find module 'koa-router' koa-router !== koa-route # install OK $ yarn add koa-router h ...

  8. taro css 转换 bug

    taro css 转换 bug https://nervjs.github.io/taro/docs/size.html https://nervjs.github.io/taro/docs/comp ...

  9. JUC学习

    JUC是java.util.concurrent包 并发编程的工具包 并发.并行 并发:多线程操作一个资源 并行:多人一起走 并发编程的本质:充分利用cpu的资源 线程的几个状态 新建 运行 堵塞 等 ...

  10. windows下的python环境安装

    windows下python开发环境的搭建还是很方便的 python本体的下载可以通过官方渠道,也可以通过windows应用商店,这里推荐后者,因为前者还要设置环境变量,而且我设置了之后cmd下也没有 ...