WPF中的aControlTemplate
和a有什么区别?DataTemplate
7 回答
通常,控件是为了自身而呈现的,并且不反映基础数据。例如, aButton
不会绑定到业务对象 - 它纯粹是为了可以单击它。但是,通常会出现AContentControl
或ListBox
,以便它们可以为用户呈现数据。
因此, ADataTemplate
用于为底层数据提供可视化结构,而 aControlTemplate
与底层数据无关,只是为控件本身提供可视化布局。
AControlTemplate
通常只包含TemplateBinding
表达式,绑定回控件本身的属性,而 aDataTemplate
将包含标准的 Binding 表达式,绑定到其属性DataContext
(业务/域对象或视图模型)。
非常基本上ControlTemplate
描述了如何显示控件,而DataTemplate
描述了如何显示数据。
例如:
ALabel
是一个控件,将包含一个ControlTemplate
表示Label
应该使用Border
围绕某些内容(一个DataTemplate
或另一个控件)显示的。
一个Customer
类是数据,将使用一个DataTemplate
来显示,可以说将Customer
类型显示为StackPanel
包含两个TextBlocks
显示名称和另一个显示电话号码的类型。注意所有类都使用 显示可能会有所帮助DataTemplates
,您通常只会使用默认模板,该模板是 a TextBlock
,其Text
属性设置为 ObjectToString
方法的结果。
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");
}
}
ControlTemplate
- 改变元素的外观。例如Button
可以包含图片和文字
DataTemplate
- 使用元素表示基础数据。
ControlTemplate
定义视觉外观,替换DataTemplate
数据项的视觉外观。
示例:我想显示一个从矩形到圆形的按钮 => 控制模板。
如果您对控件有复杂的对象,它只是调用和显示ToString()
,DataTemplate
您可以获得各种成员并显示和更改数据对象的值。
以上所有答案都很棒,但遗漏了一个关键区别。这有助于更好地决定何时使用什么。它是ItemTemplate
财产:
DataTemplate 用于为您提供 ItemTemplate 属性的元素,
DataTemplate
以使用您之前根据通过您提供的选择器绑定的数据定义的 s替换其项目的内容。But if your control does not provide this luxury for you then you still can use a
ContentView
that can display its content from predefinedControlTemplate
. Interestingly, you can change theControlTemplate
property of yourContentView
at runtime. One more thing to note that unlike controls withItemTemplate
property, you cannot have aTemplateSelector
for this (ContentView) control. However, you still can create triggers to change theControlTemplate
at runtime.