开发者

Highlight TextBlock only in TreeViewItem with Image

开发者 https://www.devze.com 2022-12-11 03:24 出处:网络
So I have a TreeViewItem that has the following style: <Style TargetType=\"{x:Type TreeViewItem}\">

So I have a TreeViewItem that has the following style:

                   <Style TargetType="{x:Type TreeViewItem}">
                        <Setter Property="HeaderTemplate">
           开发者_StackOverflow社区                 <Setter.Value>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal">
                                        <Image Name="img" Width="20" Height="16" Stretch="Uniform" Source="Images/Folder.png"/>
                                        <TextBlock Text="{Binding}" Margin="5,0" />
                                    </StackPanel>
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>

When selected, the TextBlock AND Image are highlighted. I'm trying to just highlight the TextBlock so it functions like the folders tree in file explorer.


I've found a (somewhat hacky) but lightweight solution to this problem. I see that this question is pretty old, but nonetheless, I'll post the solution here for others to find.

In my TreeView, I override the two brushes used for setting the background of the TreeViewItem when its selection changes. I also create copies of the brushes so I can restore them later in my data template:

<TreeView ItemsSource="{Binding Path=SomeDataSource}">
    <TreeView.Resources>
         <SolidColorBrush x:Key="_CustomHighlightBrushKey" Color="{Binding Source={StaticResource {x:Static SystemColors.HighlightBrushKey}}, Path=Color}" />
         <SolidColorBrush x:Key="_CustomControlBrushKey" Color="{Binding Source={StaticResource {x:Static SystemColors.ControlBrushKey}}, Path=Color}" />
         <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
         <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
    </TreeView.Resources>
</TreeView>

Note that I couldn't get this to work with a DynamicResource binding, so this solution probably won't work with theme changes. I would be very interested to know if there is a way to do this.

I then use the following hierarchical data template for formatting tree nodes:

<HierarchicalDataTemplate DataType="{x:Type SomeViewModelType}" ItemsSource="{Binding Path=Children}">
    <StackPanel Orientation="Horizontal">
        <StackPanel.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{Binding Source={StaticResource {x:Static SystemColors.HighlightBrushKey}}, Path=Color}" />
            <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{Binding Source={StaticResource {x:Static SystemColors.ControlBrushKey}}, Path=Color}" />
        </StackPanel.Resources>
        <Image SnapsToDevicePixels="True" Source="...">
        </Image>
        <TextBlock Text="{Binding Path=DisplayName}" Margin="5,0">
            <TextBlock.Resources>
                <Style TargetType="{x:Type TextBlock}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}, Path=IsSelected}" Value="True">
                            <Setter Property="Background" Value="{DynamicResource _CustomHighlightBrushKey}" />
                        </DataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}, Path=IsSelected}" Value="True" />
                                <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}, Path=IsSelectionActive}" Value="False" />
                            </MultiDataTrigger.Conditions>
                            <Setter Property="Background" Value="{DynamicResource _CustomControlBrushKey}" />
                        </MultiDataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Resources>
        </TextBlock>
    </StackPanel>
</HierarchicalDataTemplate>

Note that I restore the system brushes to their original (static) values so context menus can be rendered correctly.


You will need to roll your own highlight mark up, so instead of letting the control painting the entire panel background blue, you set your own highlight formatting based on a trigger when TreeViewItem.IsSelected is True.

In your case this would be setting the text container background to blue (when set, white normally) and leaving the image container background as white, whilst setting the overall container background to white.

The method is described here: link text

0

精彩评论

暂无评论...
验证码 换一张
取 消