Page 1 of 1

XAML - How can I reduce code duplication?

Posted: Mon Jan 30, 2023 12:35 pm
by IXix
I have four HierarchicalDataTemplates which are almost but not quite the same. The main difference is the classes they represent and then the last one for CPropertyStateVM has an additional text block in the content presenter. The context menus are the same, the content providers are mostly the same. Is there a way for me to just define the bulk of this somewhere and then override the bits that are different?

This whole mess is duplicated for each of the three treeviews in my machine GUI :roll: and I'm about to add more stuff to the context menus, so any advice would be much appreciated!

Code: Select all

<TreeView x:Name="MachineList" Grid.Row="0" ItemContainerStyle="{StaticResource tvi_main}" ItemsSource="{Binding States, UpdateSourceTrigger=Property
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:CMachineStateVM}" ItemsSource="{Binding Children}">
            <StackPanel Orientation="Horizontal">
                <StackPanel.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="Capture" Command="{Binding CmdCapture}" CommandParameter="{Binding MachineProperties}" Style="{StaticResour
                        <MenuItem Header="Restore" Command="{Binding CmdRestore}" CommandParameter="{Binding MachineProperties}" Style="{StaticResour
                        <Separator />
                        <MenuItem Header="Clear" Command="{Binding CmdClear}" CommandParameter="{Binding MachineProperties}" Style="{StaticResource p
                        <Separator />
                        <MenuItem Header="Remove from all slots" Command="{Binding CmdClearAll}" CommandParameter="{Binding MachineProperties}" Style
                    </ContextMenu>
                </StackPanel.ContextMenu>
                <CheckBox IsThreeState="True" Focusable="False" IsChecked="{Binding IsChecked}" Click="OnThreeStateClick" VerticalAlignment="Center" 
                <ContentPresenter>
                    <ContentPresenter.Content>
                        <TextBlock Style="{StaticResource tvi_text}" Text="{Binding Name}" />
                    </ContentPresenter.Content>
                </ContentPresenter>
            </StackPanel>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type local:CPropertyStateGroupVM}" ItemsSource="{Binding Children}">
            <StackPanel Orientation="Horizontal">
                <StackPanel.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="Capture" Command="{Binding CmdCapture}" CommandParameter="{Binding MachineProperties}" Style="{StaticResour
                        <MenuItem Header="Restore" Command="{Binding CmdRestore}" CommandParameter="{Binding MachineProperties}" Style="{StaticResour
                        <Separator />
                        <MenuItem Header="Clear" Command="{Binding CmdClear}" CommandParameter="{Binding MachineProperties}" Style="{StaticResource p
                        <Separator />
                        <MenuItem Header="Remove from all slots" Command="{Binding CmdClearAll}" CommandParameter="{Binding MachineProperties}" Style
                    </ContextMenu>
                </StackPanel.ContextMenu>
                <CheckBox IsThreeState="True" Focusable="False" IsChecked="{Binding IsChecked}" Click="OnThreeStateClick" VerticalAlignment="Center" 
                <ContentPresenter>
                    <ContentPresenter.Content>
                        <TextBlock Style="{StaticResource tvi_text}" Text="{Binding Name}" />
                    </ContentPresenter.Content>
                </ContentPresenter>
            </StackPanel>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type local:CTrackPropertyStateGroupVM}" ItemsSource="{Binding Children}">
            <StackPanel Orientation="Horizontal">
                <StackPanel.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="Capture" Command="{Binding CmdCapture}" CommandParameter="{Binding MachineProperties}" Style="{StaticResour
                        <MenuItem Header="Restore" Command="{Binding CmdRestore}" CommandParameter="{Binding MachineProperties}" Style="{StaticResour
                        <Separator />
                        <MenuItem Header="Clear" Command="{Binding CmdClear}" CommandParameter="{Binding MachineProperties}" Style="{StaticResource p
                        <Separator />
                        <MenuItem Header="Remove from all slots" Command="{Binding CmdClearAll}" CommandParameter="{Binding MachineProperties}" Style
                    </ContextMenu>
                </StackPanel.ContextMenu>
                <CheckBox IsThreeState="True" Focusable="False" IsChecked="{Binding IsChecked}" Click="OnThreeStateClick" VerticalAlignment="Center" 
                <ContentPresenter>
                    <ContentPresenter.Content>
                        <TextBlock Style="{StaticResource tvi_text}" Text="{Binding Name}" />
                    </ContentPresenter.Content>
                </ContentPresenter>
            </StackPanel>
        </HierarchicalDataTemplate>

        <DataTemplate DataType="{x:Type local:CPropertyStateVM}">
            <StackPanel Orientation="Horizontal">
                <StackPanel.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="Capture" Command="{Binding CmdCapture}" CommandParameter="{Binding MachineProperties}" Style="{StaticResour
                        <MenuItem Header="Restore" Command="{Binding CmdRestore}" CommandParameter="{Binding MachineProperties}" Style="{StaticResour
                        <Separator />
                        <MenuItem Header="Clear" Command="{Binding CmdClear}" CommandParameter="{Binding MachineProperties}" Style="{StaticResource p
                        <Separator />
                        <MenuItem Header="Remove from all slots" Command="{Binding CmdClearAll}" CommandParameter="{Binding MachineProperties}" Style
                    </ContextMenu>
                </StackPanel.ContextMenu>
                <CheckBox Focusable="False" IsChecked="{Binding IsChecked}" VerticalAlignment="Center" Margin="0,0,5,0" />
                <ContentPresenter>
                    <ContentPresenter.Content>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Style="{StaticResource tvi_text}" Text="{Binding DisplayName}" />
                            <TextBlock Style="{StaticResource tvi_value}" Text="{Binding DisplayValue}" />
                        </StackPanel>
                    </ContentPresenter.Content>
                </ContentPresenter>
            </StackPanel>
        </DataTemplate>
    </TreeView.Resources>