Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is x:key required on ControlTemplate in the ResourceDictionary

Consider the following XAML file:

<Window x:Class="ExpressionVisualizer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sle="clr-namespace:System.Linq.Expressions;assembly=System.Core"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate DataType="{x:Type sle:BinaryExpression}"/>
        <ControlTemplate TargetType="{x:Type ContentControl}"/>
    </Window.Resources>
</Window>

This is giving the following compile error:

All objects added to an IDictionary must have a Key attribute or some other type of key associated with them. Line 10 Position 10.

If I add an x:key attribute to the ControlTemplate, it compiles. However, I should not have to do that. The ControlTemplate is decorated with the DictionaryKeyProperty attribute which specifies TargetType as the key property. So as long as I specify a TargetType for my ControlTemplate, I should not have to specify an explicit key (similar to how I don't have to specify one on the DataTemplate I've defined).

I have a second and tangentially related question. If I define a ControlTemplate in this way (either specifying a key or not) in the XAML, does it get automatically applied to all controls of type ContentControl that don't specify another template, or would I have to embed the ControlTemplate inside a Style for that to occur?

like image 753
luksan Avatar asked Mar 03 '12 20:03

luksan


1 Answers

From MSDN ControlTemplate:

If you have a standalone ControlTemplate in the resources section with the TargetType property set to a type, the ControlTemplate does not get applied to that type automatically. Instead, you need to specify an x:Key and apply the template explicitly.

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

So the ControlTemplate is not automatically applied and you have to always specify the x:Key. So the DictionaryKeyProperty doesn't apply.

I did some research:

Although the DictionaryKeyPropertyAttribute MSDN page states:

WPF Usage Notes

The following list references examples of WPF APIs where this attribute is applied:

ControlTemplate.TargetType

DataTemplate.DataTemplateKey

Style.TargetType

But on the Resources Overview page they only mention Styles, DataTemplates, and Implicit Keys which has implicit keys. This also implies that you need to always specify the x:Key for ControlTemplate despite the DictionaryKeyProperty.

By the way it seems there is something wrong with the DictionaryKeyPropertyAttirubte see this connect issue.

like image 98
nemesv Avatar answered Oct 24 '22 03:10

nemesv