WPF ControlTemplates must have TargetType or not?

They all derive from System.Windows.Controls.ContentControl, so you could target that instead.


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>

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>

The documentation states this:

the TargetType property is required on a ControlTemplate if the template definition contains a ContentPresenter.

Although it gives no explanation for this requirement, most likely it is the reasoning given by John Bowen's answer, that you will have to manually specify basic properties like Content that would otherwise be wired automatically.