Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataTemplate without Keys in ResourceDictionary in WPF

I have several DataTemplates in a ResourceDictionary:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:z="clr-namespace:ZoomPan">
    <DataTemplate DataType="{x:Type z:Circle}">
        <z:Circle Center="{Binding Center}" Radius="{Binding Radius}" x:Name="circle"/>
        <DataTemplate.Triggers>
            <DataTrigger ... />
        </DataTemplate.Triggers>
    </DataTemplate>
    .... etc.
</ResourceDictionary>

I use it in a Window:

<z:MyUserControl>
    <z:MyUserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </z:MyUserControl.Resources>
</z:MyUserControl>

And the DataTemplates and triggers work ok.

I have two questions:

  • Why do DataTemplates in a ResourceDictionary not need a x:Key?

  • Can I divide the ResourceDictionary somehow in sections with a Key and then point to the DataTemplates in a section?

like image 453
Gerard Avatar asked Mar 07 '14 22:03

Gerard


2 Answers

Why do DataTemplates in a ResourceDictionary not need a x:Key?

When you're missing a key for Style or DataTemplate, this construction:

<DataTemplate TargetType="{x:Type local:MyType}">

automatically converted to this:

<DataTemplate x:Key="{x:Type local:MyType}" TargetType="{x:Type local:MyType}">

This means that the Style/DataTemplate will be used explicitly for all controls of this type because in ResourceDictionaries can not be elements without keys, rather this is done to simplify the structure. Quote from MSDN:

Setting the TargetType property to the TextBlock type without setting an x:Key implicitly sets the x:Key to {x:Type TextBlock}. This also means that if you give the above Style an x:Key value of anything other than {x:Type TextBlock}, the Style would not be applied to all TextBlock elements automatically. Instead, you need to apply the style to the TextBlock elements explicitly.


When I give the DataTemplates a Key they stop to work

When you specify a key for DataTemplate, it should be used for this key, such as:

<ContentControl Name="MyContent"
                ContentTemplate="{StaticResource MainView}"> // here set the key

    <MainWindowViewModels:MainViewModel />
</ContentControl>

Can I divide the ResourceDictionary somehow in sections with a Key and then point to the DataTemplates in a section?

Unfortunately no, ResourceDictionary is Quote:

class is not derived from DictionaryBase. Instead, the ResourceDictionary class implements IDictionary but relies on a Hashtable internally.

In this case, it is not ordered dictionary in which each element is assigned to the hash. For the separation of dictionaries regions used ResourceDictionary.MergedDictionaries.

like image 195
Anatoliy Nikolaev Avatar answered Oct 27 '22 18:10

Anatoliy Nikolaev


To answer your first question, you can put an x:Key on them, but the x:Type allows them to affect all of that type in the children of the control they are a resource for. It also sets an implicit x:Key on the item. The remarks in this MSDN documentation explain this very well.

To answer the second, it would be very difficult. You could define each in a separate resource dictionary and use clever merging. As far as an easy way, I believe the answer is no.

like image 31
BradleyDotNET Avatar answered Oct 27 '22 18:10

BradleyDotNET