How to dynamically change the ControlTemplate based on a property in a ViewModel?

Viewed 1226

I want to select dynamically a ControlTemplate based on a Property of a ViewModel. How do I achieve it.

I have 2 ControlTemplates in the View, and a boolean property on a ViewModel. Based on that property, I have to select and display one of my ControlTempale in the View.

<Window.Resources>
        <ControlTemplate x:Key="simpleErrorTemplate">
            <TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T1" />
        </ControlTemplate>
        <ControlTemplate x:Key="detailedErrorTemplate">
            <StackPanel>
                <TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T2" />
                <TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T3" />
                <TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T4" />
            </StackPanel>
        </ControlTemplate>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="50" />
        </Grid.RowDefinitions>
        <ContentControl Grid.Row="0" DataContext="{Binding Report}">
            <ContentControl.Style>
                <Style TargetType="ContentControl">
                    <Setter Property="Template" Value="{StaticResource simpleErrorTemplate}"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsTyping}" Value="True">
                            <Setter Property="Template" Value="{StaticResource detailedErrorTemplate}"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
        <CheckBox Margin="10,0,0,0" Grid.Row="1" x:Name="ChkShowDetails" IsChecked="{Binding IsTyping, Mode=TwoWay,    UpdateSourceTrigger=PropertyChanged}">Show Details</CheckBox>
    </Grid>

So based on the value of IsTyping, I want to display my ControlTemplate. If I directly bind the element to the Control template, it will work, but this is not my requirement.

2 Answers

Bind the data trigger to the correct DataContext, i.e. the same that the CheckBox is bound to:

<DataTrigger Binding="{Binding DataContext.IsTyping, RelativeSource={RelativeSource AncestorType=ContentControl}}" Value="True">
    <Setter Property="Template" Value="{StaticResource detailedErrorTemplate}"/>
</DataTrigger>

I think you can do something much simpler

What you need it to use the ContentControl's ContentTemplateSelector to achieve what you want.

The ContentTemplateSelector is a custom class that will switch the template depending on your data.

This will give you the idea : http://www.wpftutorial.net/datatemplates.html

Related