WPF的中模板有三种:ControlTemplate、ItemsPanelTemplate、DataTemplate,他们继承抽象类FrameworkTemplate,下面是它们的继承关系:
Windows Presentation Foundation (WPF) 中的控件具有 ControlTemplate,它包含该控件的可视化树,当在模板中查找指定控件时,会用到可视化树。 可以通过修改某个控件的 ControlTemplate 来更改该控件的结构和外观。 不能仅替换控件的可视化树的一部分;若要更改控件的可视化树,必须将该控件的 Template 属性设置为新的完整 ControlTemplate。
通常使用 ContentControl 的 ControlTemplate 中的 ContentPresenter 来指定要将内容添加到的位置。 每种 ContentControl 类型都在其默认 ControlTemplate 内有一个 ContentPresenter。
当 ContentPresenter 对象位于 ContentControl 的 ControlTemplate 中时, Content、 ContentTemplate 和 ContentTemplateSelector 属性会从 ContentControl 的同名属性获取其值。 通过设置 ContentSource 属性或绑定到模板化父级的其他属性,可以使 ContentPresenter 属性获得这些属性的值。通过下面例子理解
<Style TargetType="HeaderedContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type HeaderedContentControl}">
<StackPanel>
<Grid>
<Rectangle Stroke="{TemplateBinding Background}"/>
<ContentPresenter ContentSource="Header"/>
</Grid>
<Grid>
<Rectangle Fill="{TemplateBinding Background}"/>
<ContentPresenter ContentSource="Content"/>
</Grid>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
HeaderedContentControl 应用了上面的样式,在样式中,通过设置ContentSource="Header",ContentPresenter 的Content属性与HeaderedContentControl 控件的Header的属性显示一致,如果样式中去掉这一设置,则会获取同名属性的值,即HeaderedContentControl 的Content
<HeaderedContentControl Name="hcontCtrl" Background="Beige"
Header="This is the header."
Content="This is the content."/>
使用 DataTemplate 可以定义数据的可视表示形式。
ControlTemplate中使用ContentPresenter时,可以设置ContentPresenter的ContentTemplate属性,该属性是DataTemplate类型,可以控制内容的呈现方式。ControlTemplate中可能不止一个ContentPresenter,如GroupBox有两个ContentPresenter,分别用于展示标题和内容。不必在ControlTemplate中修改ContentPresenter的DataTemplate,控件直接将DataTemplate类型的属性公开给用户,用户可以直接为该属性设置一个新模板,如可以直接设置GroupBox的HeaderTemplate和ContentTemplate分别控制标题和内容面板中的数据展示方式。
DataTemplate类型的对象在不同的控件叫法不一,在Button中称为ContentTemplate,在ListBox中称为ItemTemplate,而在GroupBox中称为HeaderTemplate和ContentTemplate。其实,是通过控件间接引用了相应ContentPresenter中的ControlTemplate。