WPF ControlTemplates必须有TargetType吗?

dex*_*703 10 .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>
Run Code Online (Sandbox Code Playgroud)

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

Joh*_*wen 15

There isn't a requirement for a TargetType, but if you don't specify one it will behave the same as if you specify a TargetType of Control. The main advantage that specifying a type gives you is access to all of that type's Dependency Properties in things like TemplateBindings and Triggers without having to qualify the property with the owner type. Without a TargetType you can also lose implicit bindings, like ContentPresenter to the ContentControl.Content property. Once you do specify a TargetType that template can only be applied to controls of that type or derived from that type. To share between different types just specify a common base class - ContentControl in this case.

The following simple templates will give the same basic result but the first is preferable and more common:

<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>
Run Code Online (Sandbox Code Playgroud)

Without the type all of the Content properties need to be wired up manually:

<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>
Run Code Online (Sandbox Code Playgroud)