Search code examples
c#wpfxamldynamicdatatemplate

How to update a DataTemplate dynamically based on a object property?


I have a collection of objects that have different rendering options: They can be simple text, editable text, comboboxes, or event a mixed bag (like a comboBox where items are usually text but with images for specific values).

I managed to show everything correctly by using ContentTemplateSelector inside a ContentPresenter node inside the DataTemplate of the ListViewItem.ItemTemplate:

<ContentPresenter 
    Grid.Row="1"
    Grid.Column="1"
    Content="{Binding .}"
    ContentTemplateSelector="{DynamicResource ResourceKey=RenderTemplateSelector}"/>

(note that everything is inside the DataTemplate of a ListView.ItemTemplate)

All is good until I change the value of said property and need to change the template, for instance going from a image to a text. The VM does update correctly the values, but nothing happens in the GUI.

Looking around here there are a few methods (using a Converter (bound to which property??), defining a Style (i think is not relevant, since i must show different controls, not change properties of the same one), using an AttachedProperty (I don 't understand really well how attached properties work, but from what I saw I should have a ContentControl node, which I don't...) but nothing seems what I need.

So, a recap: I have a ListView that has a DataTemplate definded for each ListViewItem that contains another DataTemplate that needs to change based on a properti of the ListViewItem object. I managed to achieve this with a ContentTemplateSelector, but that is assigned at the beginning and then never changed.


Solution

  • You could try to replace the ContentPresenter with a ContentControl that has a Style with data triggers that sets the ContentTemplate, .e.g.:

    <ContentControl Content="{Binding}">
        <ContentControl.Style>
            <Style TargetType="ContentControl">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding YourProperty}" Value="Type1">
                        <Setter Property="ContentTemplate" Value="{StaticResource template1}" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding YourProperty}" Value="Type2">
                        <Setter Property="ContentTemplate" Value="{StaticResource template2}" />
                    </DataTrigger>
                    <!-- ... -->
                </Style.Triggers>
            </Style>
        </ContentControl.Style>
    </ContentControl>