Search code examples
wpfxamldata-bindingdatatemplate

Different views / data template based on member variable


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?


Solution

  • 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.