Answers:
通常情况下,控件是为自身目的而呈现的,并且不反映基础数据。例如,a Button
不会绑定到业务对象-纯粹是在那里,因此可以单击它。甲ContentControl
或者ListBox
,然而,一般出现,使他们能够对用户显示数据。
DataTemplate
因此,A 用于为基础数据提供可视化结构,而A ControlTemplate
与基础数据无关,仅为控件本身提供可视化布局。
A ControlTemplate
将通常只包含TemplateBinding
表达式,并绑定到控件本身的属性,而A DataTemplate
将包含标准Binding表达式,并绑定到控件DataContext
(业务/域对象或视图模型)的属性。
基本上,a ControlTemplate
描述了如何显示控件,而a DataTemplate
描述了如何显示数据。
例如:
A Label
是一个控件,将包含一个ControlTemplate
,其中表示Label
应该使用Border
某些Content(一个DataTemplate
或另一个控件)周围的来显示。
一个Customer
类是Data,将使用来显示DataTemplate
,可以说将其显示Customer
为一个StackPanel
包含两个的类型,TextBlocks
一个显示名称,另一个显示电话号码。注意,所有类都使用来显示DataTemplates
,您可能会有所帮助,您通常只会使用默认模板,该模板TextBlock
的Text
属性设置为Object ToString
方法的结果。
Troels Larsen在MSDN论坛上有一个很好的解释
<Window x:Class="WpfApplication7.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <DataTemplate x:Key="ButtonContentTemplate"> <StackPanel Orientation="Horizontal"> <Grid Height="8" Width="8"> <Path HorizontalAlignment="Stretch" Margin="0,0,1.8,1.8" VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" Data="M0.5,5.7 L0.5,0.5 L5.7,0.5"/> <Path HorizontalAlignment="Stretch" Margin="2,3,0,0" VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" Data="M3.2,7.5 L7.5,7.5 L7.5,3.5"/> <Path HorizontalAlignment="Stretch" Margin="1.2,1.4,0.7,0.7" VerticalAlignment="Stretch" Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FF000000" Data="M2.5,2.5 L7.5,7.5"/> <Path HorizontalAlignment="Stretch" Margin="1.7,2.0,1,1" VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" Data="M3,7.5 L7.5,7.5 L7.5,3.5"/> <Path HorizontalAlignment="Stretch" Margin="1,1,1,1" VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" Data="M1.5,6.5 L1.5,1 L6.5,1.5"/> </Grid> <ContentPresenter Content="{Binding}"/> </StackPanel> </DataTemplate> <ControlTemplate TargetType="Button" x:Key="ButtonControlTemplate"> <Grid> <Ellipse Fill="{TemplateBinding Background}"/> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> </Grid> </ControlTemplate> </Window.Resources> <StackPanel> <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="1"/> <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="2"/> <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="3"/> </StackPanel> </Window>
(模板从 http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx 和 http://msdn.microsoft.com/en-us/library/system.windows .controls.contentcontrol.contenttemplate%28VS.95%29.aspx 分别)
无论如何,ControlTemplate决定按钮本身的外观,而ContentTemplate决定按钮内容的外观。因此,您可以将内容绑定到其中一个数据类,并根据需要显示它本身。
ControlTemplate
:表示控件样式。
DataTemplate
:表示数据样式(您希望如何显示数据)。
所有控件都使用默认控件模板,您可以通过模板属性覆盖它。
例如,
Button
模板是控制模板。
Button
内容模板是数据模板
<Button VerticalAlignment="Top" >
<Button.Template>
<ControlTemplate >
<Grid>
<Rectangle Fill="Blue" RadiusX="20" RadiusY="20"/>
<Ellipse Fill="Red" />
<ContentPresenter Content="{Binding}">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="50">
<TextBlock Text="Name" Margin="5"/>
<TextBox Text="{Binding UserName, Mode=TwoWay}" Margin="5" Width="100"/>
<Button Content="Show Name" Click="OnClickShowName" />
</StackPanel>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
public String UserName
{
get { return userName; }
set
{
userName = value;
this.NotifyPropertyChanged("UserName");
}
}
以上所有答案都很不错,但是有一个关键的区别被遗漏了。这有助于更好地决定何时使用什么。它是ItemTemplate
属性:
DataTemplate用于为元素提供ItemTemplate属性,以便您DataTemplate
通过提供的选择器根据绑定数据使用先前定义的s 替换其项目的内容。
但是,如果您的控件没有为您提供这种奢侈,那么您仍然可以使用ContentView
可以显示预定义内容的控件ControlTemplate
。有趣的是,您可以在运行时更改ControlTemplate
属性ContentView
。需要注意的另一点是,与具有ItemTemplate
属性的控件不同,您不能TemplateSelector
为此(ContentView)控件使用。但是,您仍然可以创建触发器以ControlTemplate
在运行时更改。