WPF ControlTemplates必须有TargetType吗?

时间:2010-09-03 00:06:23

标签: .net wpf templates controltemplate targettype

WPF中的ControlTemplates是否需要TargetType?我正在重新设置一些控件,并注意到comboboxitem,listiviewitem和listboxitem都具有相同的模板:

    <ControlTemplate x:Key="ListBoxItemCT" TargetType="{x:Type ListBoxItem}">

    <Border x:Name="Bd" 
        SnapsToDevicePixels="true" 
        Background="{TemplateBinding Background}" 
        BorderBrush="{TemplateBinding BorderBrush}" 
        BorderThickness="{TemplateBinding BorderThickness}" 
        Padding="{TemplateBinding Padding}"
        CornerRadius="1">
        <ContentPresenter x:Name="cpItemContent"
            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
            VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
            />
    </Border>

</ControlTemplate>

是否可以删除TargetType并为所有三个模板设置一个模板?我试图这样做,但得到奇怪的错误和问题。我找不到ControlTemplates必须具有类型的任何特定参考。

3 个答案:

答案 0 :(得分:15)

不需要TargetType,但如果不指定TargetType,则其行为与指定TargetType为Control的行为相同。指定类型的主要优点是,您可以访问诸如TemplateBindings和Triggers之类的所有类型的依赖项属性,而无需使用所有者类型限定属性。如果没有TargetType,您还可能会丢失隐式绑定,例如ContentPresenter到ContentControl.Content属性。指定TargetType后,该模板只能应用于该类型的控件或从该类型派生。要在不同类型之间共享,只需指定一个公共基类 - 在这种情况下为ContentControl。

以下简单模板将给出相同的基本结果,但第一个是更好和更常见的:

<ControlTemplate x:Key="CommonContentTemplate" TargetType="{x:Type ContentControl}">
    <Border x:Name="Bd" 
            SnapsToDevicePixels="true" 
            Background="{TemplateBinding Background}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}" 
            Padding="{TemplateBinding Padding}"
            CornerRadius="1">
        <ContentPresenter x:Name="cpItemContent"
                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
    </Border>
</ControlTemplate>

如果没有该类型,则需要手动连接所有内容属性:

<ControlTemplate x:Key="CommonTemplate">
    <Border x:Name="Bd" 
            SnapsToDevicePixels="true" 
            Background="{TemplateBinding Background}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}" 
            Padding="{TemplateBinding Padding}"
            CornerRadius="1">
        <ContentPresenter x:Name="cpItemContent"
                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                          Content="{TemplateBinding ContentControl.Content}"
                          ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                          ContentTemplateSelector="{TemplateBinding ContentControl.ContentTemplateSelector}"
                          ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"/>
    </Border>
</ControlTemplate>

答案 1 :(得分:2)

它们都来自System.Windows.Controls.ContentControl,因此您可以将其作为目标。

答案 2 :(得分:1)

为完整起见,请注意the documentation声明:

如果ControlTemplate上

TargetType属性是必需的 模板定义包含ContentPresenter。

尽管没有对此要求进行解释,但很有可能是John Bowen's answer给出的理由,您将必须手动指定基本属性,例如Content,否则这些属性将自动连接。