控件模板在以前的文章中总结过:
https://blog.csdn.net/jfyy/article/details/80620327
数据模板跟控件模板的区别:Difference
Typically a control is rendered for its own sake, and doesn't reflect underlying data. For example, a Button
wouldn't be bound to a business object - it's there purely so it can be clicked on. A ContentControl
or ListBox
, however, generally appear so that they can present data for the user.
A DataTemplate
, therefore, is used to provide visual structure for underlying data, while a ControlTemplate
has nothing to do with underlying data and simply provides visual layout for the control itself.
A ControlTemplate
will generally only contain TemplateBinding
expressions, binding back to the properties on the control itself, while a DataTemplate
will contain standard Binding expressions, binding to the properties of its DataContext
(the business/domain object or view model).
翻译:
通常情况下,控件模板只是为了自己而呈现的,并不反映基础数据。 例如,一个Button不会被绑定到一个业务对象 - 它只是可以被点击。 而ContentControl或ListBox通常显示为可以为用户呈现数据。因此,DataTemplate用于为底层数据提供可视结构,而ControlTemplate与底层数据无关,仅为控件本身提供可视化布局。
ControlTemplate通常只包含TemplateBinding表达式,绑定回控件本身的属性,而DataTemplate将包含标准绑定表达式,并绑定到其DataContext(业务/域对象或视图模型)的属性。
下面是两个按钮的模板,分别是控件模板和数据模板,可以看看它们之间的区别:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfBook"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" x:Class="WpfBook.ImageButton"
Title="ImageButton" Height="300" Width="300" Activated="Window_Activated">
<Window.Resources>
<ControlTemplate x:Key="ImageButton-ControlTemplate" TargetType="{x:Type Button}">
<Grid>
<Ellipse Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Fill="{TemplateBinding Background}"/>
<TextBlock Margin="{TemplateBinding Padding}" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{TemplateBinding Content}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<DataTemplate x:Key="ImageButton-DataTemplate" DataType="{x:Type local:Person}">
<TextBlock x:Name="tb" Text="{Binding Name}" Margin="1" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsOnline}" Value="False">
<Setter TargetName="tb" Property="Foreground" Value="Gray" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<DataTemplate x:Key="Item-DataTemplate" DataType="{x:Type local:Person}">
<TextBlock x:Name="tb" Text="{Binding Name}" Margin="1" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsOnline}" Value="False">
<Setter TargetName="tb" Property="Foreground" Value="Red" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
<StackPanel Orientation="Vertical">
<Button Template="{StaticResource ImageButton-ControlTemplate}" Content="abcde"/>
<Button x:Name="ddd" ContentTemplate="{StaticResource ImageButton-DataTemplate}" Content="{Binding APerson}"/>
<ListBox x:Name="list1" ItemTemplate="{StaticResource Item-DataTemplate}" ItemsSource="{Binding Persons}"/>
</StackPanel>
</Window>
注意点:
- Button是content control,两个模板对应的模板分别是Template和ContentTemplate, 数据模板还需要将数据先绑定到Content属性上。
- 数据模板中设定属性,必须要使用指定TargetName,而控件模板不需要。
- 数据模板中除了给ContentTemplate,例子中还可以设定给ItemsControl的ItemTemplate属性。除此以外还可以设定给GridViewColumn的CellTemplate属性。