Search code examples
c#wpfdatatemplatedatatriggertemplating

Changing DataTemplates at runtime using DataTriggers


I'm trying to change a DataTemplate for objects in my WPF application according to a specific boolean value. When the value is "True" I want the DataTemplate to be something and when the value is "False" I want the DataTemplate to be something else.

I've tried writing this code, but so far I end up with an annoying "Out of Memory exception".

<DataTemplate DataType="{x:Type vm:MyObjectViewModel}">
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Visible}" Value="False">
            <Setter TargetName="MainTemplateGrid" Property="Content">
                <Setter.Value>
                    <Ellipse Width="50" Height="50" Fill="Red" />
                </Setter.Value>
            </Setter>
        </DataTrigger>
        <DataTrigger Binding="{Binding Visible}" Value="True">
            <Setter TargetName="MainTemplateGrid" Property="Content">
                <Setter.Value>
                    <Image Source="{Binding Icon}" Opacity="{Binding Visible, Converter={StaticResource VisibilityConverter}}" />
                </Setter.Value>
            </Setter>
        </DataTrigger>
    </DataTemplate.Triggers>
    <ContentControl x:Name="MainTemplateGrid" />
</DataTemplate>

If anyone has a clue on how to fix this, please let me know.


Solution

  • I figured it out.

    I did this using a ContentControl and by setting its Style using the DataTriggers, here's the code:

     <DataTemplate DataType="{x:Type vm:MyControlViewModel}">
        <ContentControl>
            <ContentControl.ToolTip>
               <!-- TOOLTIP CODE GOES HERE -->
            </ContentControl.ToolTip>
            <ContentControl.InputBindings>
                <!-- INPUT BINDINGS CODE GOES HERE -->
            </ContentControl.InputBindings>
            <ContentControl.ContextMenu>
                <!-- CONTEXT MENU CODE GOES HERE -->
            </ContentControl.ContextMenu>
            <ContentControl.Style>
                <Style>
                    <Style.Triggers>
                        <DataTrigger Binding="Visibility" Value="0">
                            <Setter Property="ContentControl.Content">
                                <Setter.Value>
                                    <Ellipse Width="50" Height="50" Opacity="0.5">
                                        <Ellipse.Fill>
                                            <LinearGradientBrush>
                                                <GradientStopCollection>
                                                    <GradientStop Color="Red" Offset="0" />
                                                    <GradientStop Color="DarkRed" Offset="0.8" />
                                                </GradientStopCollection>
                                            </LinearGradientBrush>
                                        </Ellipse.Fill>
                                    </Ellipse>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                        <DataTrigger Binding="Visibility" Value="100">
                            <Setter Property="ContentControl.Content">
                                <Setter.Value>
                                    <Image Source="{Binding Icon}" Opacity="{Binding Visible, Converter={StaticResource VisibilityConverter}}" />
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </DataTemplate>