WPF 控件的默认 UI 通常由其他控件和形状构造而来。有时控件的默认外观可能与应用程序的整体外观不一致。在这种情况下,您可以使用 ControlTemplate更改控件的 UI 的外观,而无需更改控件的内容和行为。
控件模板使您可以指定控件的外观,数据模板则允许您指定控件内容的外观。数据模板通常用于改进绑定数据的显示方式。例如我们可以通过将时间的字符串形式表示为一个图片。
DataTemplate与ControlTemplate有点相似。它们都是用FrameworkElementFactroy对象定义它们的视觉树属性。ControlTemplate是将视觉树的视觉属性绑定到控件属性(control property),而DataTemplate是将视觉树的视觉属性绑定到数据属性(Data Property)。DataTemplate和ControlTemplate都从FrameworkTemplate继承。
数据模板适用于Content Control类控件与Items Control类控件。
DataTemple有两个构造函数。在public DataTemplate(object dataType)构造函数中,datatype是此模板要应用的数据类对象,在code中可以使用typeof。在XAML中可以使用x:Type。
下面是一个简单的数据类Country,显示国籍和国旗。
Code
namespace Demo
{
public class Country
{
private string name;
private string flag;
public Country(string name, string flag)
{
this.name= name;
this.flag= flag;
}
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
public string Flag
{
get
{
return this.flag;
}
set
{
this.flag= value;
}
}
}
}
下面如果我们想在一个ListBox中显示。就可以自定义ListBox的数据模板。
XAML方式
Code
<Window.Resources>
<!--模板-->
<DataTemplate x:Key="Template" DataType="{x:Type demo:Country}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding Flag}" Width="32" Height="32" Grid.Column="0"/>
<TextBlock Text="{Binding Name}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</Window.Resources>
说明:x:Key表示在资源字典中的Key值,Datatype表示该模板针对的数据类型是Country。
引用自定义名字空间:
xmlns:demo="clr-namespace:Demo"
将此模板应用到ListBox中:
Code
<ListBox x:Name="Lstbox" ItemTemplate="{StaticResource Template}" />
Code方式
通过code的方式也可以实现DataTemplate。主要用到的是FramewrokElementFactroy来创建视觉元素。
如:
Code
//用一个Grid封装两个元素
DataTemplate DemoTemplate = new DataTemplate(typeof(Country));
FrameworkElementFactory factory = new FrameworkElementFactory(typeof(Grid));
//Image元素,显示国旗
FrameworkElementFactory fatctoryImage = new FrameworkElementFactory(typeof(Image));
fatctoryImage.SetBinding(Image.SourceProperty, new Binding("Flag"));
factory.AppendChild(fatctoryImage);
//Name元素,显示国籍
FrameworkElementFactory factoryTextBlock = new FrameworkElementFactory(typeof(TextBlock));
factoryTextBlock.SetBinding(TextBlock.TextProperty, new Binding("Name"));
factory.AppendChild(factoryTextBlock);
DemoTemplate.VisualTree = factory;
//定义ListBox
ListBox lbItems = new ListBox();
lbItmes.ItemTemplate = DemoTemplate;
控件模板的使用与数据模板类似。
msdn:http://msdn.microsoft.com/zh-cn/library/system.windows.controls.controltemplate.aspx
http://msdn.microsoft.com/zh-cn/library/ms742521.aspx