是的,最近在看WPF,也算是加深下c#的知识,毕竟winform的界面有的时候真的不是很美观。WPF中模板与Style不同,Style只能改变控件的已有属性值(比如颜色字体)来定制控件,形同HTML中的CSS,但控件模板可以改变控件的内部结构(VisualTree,视觉树)来完成更为复杂的定制,其实WPF的每一个控件都有一个默认的模板。
数据模板跟控件模板的区别主要体现在,通常情况下,控件模板只是为了自己而呈现的,并不反映基础数据。 例如,一个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>
这里补充点:
参考数据绑定思维,数据模板通过Content属性指定数据源,将数据先绑定到Content属性上,通过ContentTemplate指定数据处理方式。Button是数据content 对应的模板是ContentTemplate,Button是control对应的模板是Template。
数据模板中设定属性,必须要使用指定TargetName,而控件模板不需要。
数据模板中除了给ContentTemplate,例子中还可以设定给ItemsControl的ItemTemplate属性。除此以外还可以设定给GridViewColumn的CellTemplate属性。数据模板在页面xaml内部定义,而控件模板通常放到样式文件中。