user1492051
user1492051

Reputation: 906

Applying DataTemplate based on type

when i do the following and set the content of a Control to my ViewModel the Template gets applied automatically.

 <DataTemplate DataType="{x:Type ViewModels:ViewModel}">
        <StackPanel Orientation="Vertical">
              <ControlX ....>
              <ControlY ....>
        </StackPanel>
 </DataTemplate>

however i want to use FindResource to get the DataTemplate in the code behind so i had to add an x:key

<DataTemplate DataType="{x:Type ViewModels:ViewModel}" x:Key="{x:Type ViewModels:ViewModel}">
<DataTemplate DataType="{x:Type ViewModels:ViewModel}" x:Key="ViewModelTemplate">

But when i add an x:key the FindResource() works but the DataTemplate stops being applied automatically based on the type, any workaround available for this?

Upvotes: 1

Views: 272

Answers (2)

Leon Zhou
Leon Zhou

Reputation: 635

As a bad looking work around, you may try creating 2 DataTemplates that share the same content:

This ControlTemplate defines the shared content:

<ControlTemplate TargetType="{x:Type ContentControl}"
                 x:Key="MyControlTemplate">
    <TextBlock Text="Some content" />
</ControlTemplate>

Then 2 DataTemplates as a workaround:

<DataTemplate x:Key="MyDataTemplate">
    <ContentControl Template="{StaticResource MyControlTemplate}" />
</DataTemplate>
<DataTemplate DataType="{x:Type system:String}">
    <ContentControl Template="{StaticResource MyControlTemplate}" />
</DataTemplate>

Edit:

I know that this answer came a year too late after I've provided a bad looking work around above, but it's better than never.

The implicit key set for an implicit data template is the data type itself wrapped in a DataTemplateKey.

You can either use:

FindResource(new DataTemplateKey(typeof (MainViewModel))

or

Resource[new DataTemplateKey(typeof (MainViewModel)]

to get your data template in code behind.

Upvotes: 2

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73502

<DataTemplate DataType="{x:Type local:Task}">
  <StackPanel>
    <TextBlock Text="{Binding Path=TaskName}" />
    <TextBlock Text="{Binding Path=Description}"/>
    <TextBlock Text="{Binding Path=Priority}"/>
  </StackPanel>
</DataTemplate>

This DataTemplate gets applied automatically to all Task objects. Note that in this case the x:Key is set implicitly. Therefore, if you assign this DataTemplate an x:Key value, you are overriding the implicit x:Key and the DataTemplate would not be applied automatically.

It works as documented. AFAIK you can either use Key or DataType not both, there may be workarounds which I wasn't aware of.

Upvotes: 1

Related Questions