Search code examples
wpfxaml

Set style of child of TreeViewItem on mouse hover


I have a tree view:

<Window.Resources>
    <VisualBrush x:Key="HighlightBrush">LightBlue</VisualBrush>
    <Style x:Key="RectangleStyle" TargetType="Rectangle">
        <Setter Property="Fill" Value="{StaticResource HighlightBrush}"/>
    </Style>
</Window.Resources>
<TreeView Grid.Column ="0" Name="MyTreeView">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="Green" />
                    <!-- Set property "Visibility" of child Rectangle "Hb" to "visible -->
                </Trigger>
            </Style.Triggers>
        </Style>
    </TreeView.ItemContainerStyle>
    <d:TreeView.ItemsSource >
        <x:Array Type="system:String">
            <system:String>First element</system:String>
            <system:String>Second element</system:String>
        </x:Array>
    </d:TreeView.ItemsSource>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate DataType="{x:Type system:String}" >
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding .}" d:Text="{Binding .}" />
                <Rectangle x:Name="Hb" Width="100000" Margin="-10000,0,0,0" Panel.ZIndex="-1" Visibility="Hidden" Style="{DynamicResource  RectangleStyle}" />
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

I figured out how to set the background of the TreeViewItem on mouse hover. How can I set the visibility of Rectangle Hb which is a child of the TreeViewItem to visible on mouse hover of the TreeViewItem?

Note: The idea for this method of highlighting the current item comes from https://stackoverflow.com/a/1627451/2484903.


Solution

  • You may add a DataTrigger on the IsMouseOver property of the TreeViewItem to the Rectangle Style. The Fill Brush should also be a SolidColorBrush:

    <Window.Resources>
        <SolidColorBrush x:Key="HighlightBrush">LightBlue</SolidColorBrush>
        <Style x:Key="RectangleStyle" TargetType="Rectangle">
            <Setter Property="Fill" Value="{StaticResource HighlightBrush}"/>
            <Style.Triggers>
                <DataTrigger
                    Binding="{Binding IsMouseOver,
                        RelativeSource={RelativeSource AncestorType=TreeViewItem}}"
                    Value="False">
                    <Setter Property="Visibility" Value="Hidden"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    

    Alternatively, you could bind the Rectangle's Visibility to the IsMouseOver property like this:

    <Rectangle x:Name="Hb" ...
        Visibility="{Binding IsMouseOver,
                     RelativeSource={RelativeSource AncestorType=TreeViewItem},
                     Converter={StaticResource BooleanToVisibilityConverter}}" />
    

    with a BooleanToVisibilityConverter resource e.g. in Window.Resources:

    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
        <SolidColorBrush x:Key="HighlightBrush">LightBlue</SolidColorBrush>
        <Style x:Key="RectangleStyle" TargetType="Rectangle">
            <Setter Property="Fill" Value="{StaticResource HighlightBrush}"/>
        </Style>
    </Window.Resources>