Different views / data template based on member variable

Josh Mulholland picture Josh Mulholland · Apr 17, 2012 · Viewed 19.9k times · Source

I have a view model called

 ViewModelClass 

which contains a boolean.

I have another view model which contains

ObservableCollection<ViewModelClass> m_allProjects;

Then I have this in my view:

<DataTemplate>
   <views:ProjectInfoView x:Key="ProjectInfoDetailTemplate"/>
</DataTemplate>

<ItemsControl Grid.Row="1" Grid.Column="0"
              ItemsSource="{Binding AllProjects}"
              ItemTemplate="{StaticResource ProjectInfoDetailTemplate}"
              Margin="10,28.977,10,10">
</ItemsControl >

I want, based on the boolean in the AllProjects-collection, to use a different datatemplate. What is the best way to do this?

I know I can do this with different ViewModels and use a kind of ViewModel-base object, but I prefer just to use 1 view model.

EDIT:

I want to do this with data triggers. Can someone provide me with some code please?

Answer

Rachel picture Rachel · Apr 17, 2012

I usually use a ContentControl to display the data, and swap out the ContentTemplate in a trigger based on the property that changes.

Here's an example I have posted on my blog that swaps a template based on a bound property

<DataTemplate x:Key="PersonTemplate" DataType="{x:Type local:ConsumerViewModel}">
     <TextBlock Text="I'm a Person" />
</DataTemplate> 

<DataTemplate x:Key="BusinessTemplate" DataType="{x:Type local:ConsumerViewModel}">
     <TextBlock Text="I'm a Business" />
 </DataTemplate>

<DataTemplate DataType="{x:Type local:ConsumerViewModel}">
     <ContentControl Content="{Binding }">
         <ContentControl.Style>
             <Style TargetType="{x:Type ContentControl}">
                 <Setter Property="ContentTemplate" Value="{StaticResource PersonTemplate}" />
                 <Style.Triggers>
                     <DataTrigger Binding="{Binding ConsumerType}" Value="Business">
                         <Setter Property="ContentTemplate" Value="{StaticResource BusinessTemplate}" />
                     </DataTrigger>
                 </Style.Triggers>
             </Style>
         </ContentControl.Style>
     </ContentControl>
 </DataTemplate>

A DataTemplateSelector will also work, but only if the property that determines which template to show doesn't change since DataTemplateSelectors don't respond to change notifications. I usually avoid them if possible since I also prefer my view selection logic in my view so I can see whats going on.