20

I have a item control which is bound to Tasks. Each task has task state. I have defined different data templates for each task state, and also data template selector.

Problem is that I am not able to figure out how to trigger data template selector when task state is changed dynamically.

I want to know how to use data triggers together with data templates.

If this will not work out, i will explore other alternatives such as
1. Attached Property bound to task state. Any change will dynamically set data template.
2. Visual State Manager

Tilak
  • 30,108
  • 19
  • 83
  • 131
  • maybe this answer will fit also for you http://stackoverflow.com/questions/8715315/how-to-trigger-datatemplateselector-when-property-changes – michele Oct 30 '12 at 10:42
  • Looked at this answer already. This may work, but looks a bit complex. Looking for simpler solution. – Tilak Oct 30 '12 at 10:55
  • The question maybe duplicated with [how-to-trigger-datatemplateselector-when-property-changes](https://stackoverflow.com/questions/8715315/how-to-trigger-datatemplateselector-when-property-changes) and [ControlTemplate with DataTrigger Vs. DataTemplate with DataTemplateSelector](https://stackoverflow.com/questions/8926024/controltemplate-with-datatrigger-vs-datatemplate-with-datatemplateselector) – huoxudong125 Oct 15 '14 at 01:22

2 Answers2

55

A DataTemplateSelector does not respond to PropertyChange notifications, so it doesn't get re-evaluated when your properties change.

The alternative I use is DataTriggers that changes the Template based on a property.

For example, this will draw all TaskModel objects using a ContentControl, and the ContentControl.Template is based on the TaskStatus property of the TaskModel

<DataTemplate x:Key="OpenTaskTemplate" TargetType="{x:Type local:TaskModel}">
     <TextBlock Text="I'm an Open Task" />
</DataTemplate> 

<DataTemplate x:Key="ClosedTaskTemplate" TargetType="{x:Type local:TaskModel}">
     <TextBlock Text="I'm a Closed Task" />
 </DataTemplate>

<DataTemplate DataType="{x:Type local:TaskModel}">
     <ContentControl Content="{Binding }">
         <ContentControl.Style>
             <Style TargetType="{x:Type ContentControl}">

                 <!-- Default Template -->
                 <Setter Property="ContentTemplate" Value="{StaticResource OpenTaskTemplate}" />

                 <!-- Triggers to change Template -->
                 <Style.Triggers>
                     <DataTrigger Binding="{Binding TaskStatus}" Value="Closed">
                         <Setter Property="ContentTemplate" Value="{StaticResource ClosedTaskTemplate}" />
                     </DataTrigger>
                 </Style.Triggers>
             </Style>
         </ContentControl.Style>
     </ContentControl>
 </DataTemplate>
Rachel
  • 130,264
  • 66
  • 304
  • 490
  • hmm, DataTemplate doesn't seem have a targetType member. Am I missing something? – Jake Gaston Jul 18 '14 at 16:19
  • @JakeGaston Are you using Silverlight? I don't think implicit DataTemplates (ones with only TargetType set) are implemented in Silverlight until 4.5. – Rachel Jul 18 '14 at 18:08
8

Just a quick note for anyone that found this incredibly helpful as I did -

Currently with WPF, it looks like you'll want to use DataType rather than TargetType on your DataTemplate definitions:

<DataTemplate x:Key="OpenTaskTemplate" DataType="{x:Type local:TaskModel}">
     <TextBlock Text="I'm an Open Task" />
</DataTemplate> 

<DataTemplate x:Key="ClosedTaskTemplate" DataType="{x:Type local:TaskModel}">
     <TextBlock Text="I'm a Closed Task" />
 </DataTemplate>
Noth
  • 115
  • 1
  • 2
  • 5