Search code examples
c#wpftreeviewitem

Share certain resources among TreeViewItem.Resources


I have several TreeView controls in my application, and they are all similar to this:

<TreeView SelectedItemChanged="TreeView_OnSelectedItemChanged" x:Name="AccountsTree" >
    <TreeView.Resources>
        <!-- styles -->
    </TreeView.Resources>
    <TreeViewItem Header="Things" >
        <TreeViewItem.Resources>

            <!--From: https://stackoverflow.com/a/17814749/107037-->
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightBlue" />
            <!--<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />-->
            <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="Transparent" />
            <!--<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}" Color="Black" />-->

            <HierarchicalDataTemplate DataType="{x:Type local:ThingEntity}" ItemsSource="{Binding Children, Mode=OneWay}">
                <HierarchicalDataTemplate.Resources>
                    <!-- styles -->
                </HierarchicalDataTemplate.Resources>
                <StackPanel Orientation="Horizontal">
                    <i:Interaction.Behaviors>
                        <!-- drag 'n drop -->
                    </i:Interaction.Behaviors>
                    <Image x:Name="ThingIcon" />
                    <TextBlock Text="{Binding ThingName}" Margin="6,0,6,0" />
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeViewItem.Resources>
    </TreeViewItem>
</TreeView>

I found the simple way to change the SelectedItem color in this answer: TreeView shows blue for selected item

Is there a way to somehow encapsulate the collection of SolidColorBrush definitions to make them easy to re-use in all the TreeViews that need them?

Alternatively, is there a way to apply that collection of Brushes to all TreeViewItem controls, much like

<Style TargetType="{x:Type TreeViewItem}">  
    <!-- style stuff -->  
</Style>  

Applies the defined Style to all TreeViewItem controls?

Thanks --


Solution

  • Styles can have Resources. Easy.

    <Style TargetType="{x:Type TreeViewItem}">  
        <Style.Resources>
    
            <!--From: https://stackoverflow.com/a/17814749/107037-->
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightBlue" />
            <!--<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />-->
            <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="Transparent" />
            <!--<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}" Color="Black" />-->
    
            <HierarchicalDataTemplate DataType="{x:Type local:ThingEntity}" ItemsSource="{Binding Children, Mode=OneWay}">
                <HierarchicalDataTemplate.Resources>
                    <!-- styles -->
                </HierarchicalDataTemplate.Resources>
                <StackPanel Orientation="Horizontal">
                    <i:Interaction.Behaviors>
                        <!-- drag 'n drop -->
                    </i:Interaction.Behaviors>
                    <Image x:Name="ThingIcon" />
                    <TextBlock Text="{Binding ThingName}" Margin="6,0,6,0" />
                </StackPanel>
            </HierarchicalDataTemplate>
        </Style.Resources>
    </Style>
    

    You can nest these as well. A Style's resources can contain another Style, which can use the resources of the parent style:

    <Style x:Key="RedBlueTreeView" TargetType="TreeView">
        <Style.Resources>
            <SolidColorBrush x:Key="BlueBrush" Color="Red" />
    
            <Style TargetType="TreeViewItem">
                <Style.Resources>
                    <HierarchicalDataTemplate 
                        DataType="{x:Type local:ThingEntity}"
                        ItemsSource="{Binding Children}"
                        >
                        <Label
                            Foreground="{StaticResource BlueBrush}"
                            Content="{Binding Stuff}"
                            />
                    </HierarchicalDataTemplate>
                </Style.Resources>
            </Style>
        </Style.Resources>
    </Style>