c# - 将鼠标悬停在子节点上时,TreeViewItem 父节点和子节点 IsSelected 分离

标签 c# wpf xaml treeview treeviewitem

我真的不知道如何问这个,但我有一个特定的风格,我想在我的 TreeView 上实现。

所以据我了解 TreeView 控件,当您展开 TreeViewItem 时节点来查看它的子节点,它会创建一个新的 ItemsPresenter那是新子节点的 TreeViewItem 的容器。这意味着所有子节点都连接到它们的每个父节点。

我想要实现的是,当子节点展开到 View 中并选择父节点时,用户将鼠标悬停在子节点之一上,父节点仍然激活了默认的选定样式。而不是通过将鼠标悬停在其子节点之一上来激活 IsMouseOver 样式。

这是一个例子:

选定的父颜色

enter image description here

选择父节点并将鼠标悬停在子节点上时会发生什么

enter image description here

What I want it to look like when parent node is selected and when hovering over one of it's children (excuse my amazing paint skills with this one)

enter image description here

这是我的代码供引用

TreeView

    <TreeView Background="{x:Null}" BorderThickness="0" Margin="0,3,0,0">
        <TreeViewItem  Header="Root Node" IsExpanded="True">
            <TreeViewItem Header="Parent Node" IsExpanded="True">
                <TreeViewItem Header="Child Node" IsExpanded="True">
                    <TreeViewItem Header="Child Node" IsExpanded="True">
                        <TreeViewItem Header="Child Node" IsExpanded="True" IsSelected="True"/>
                    </TreeViewItem>
                </TreeViewItem>
            </TreeViewItem>
            ...
            <TreeViewItem Header="Child Node">
                <TreeViewItem Header="Child Node"/>
                <TreeViewItem Header="Child Node"/>
            </TreeViewItem>
            <TreeViewItem Header="Child Node"/>
        </TreeViewItem>
    </TreeView>

风格
<Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="Padding" Value="1,0,0,0"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TreeViewItem}">
                <StackPanel>
                    <Border x:Name="Bd" Grid.ColumnSpan="3" BorderThickness="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true" Margin="3,0,3,-1" MinHeight="20">
                        <Border.Style>
                            <Style TargetType="{x:Type Border}">
                                <Style.Triggers>
                                    <Trigger Property="IsMouseOver" Value="true">
                                        <Setter Property="Background" Value="Red"/>
                                        <Setter Property="BorderBrush" Value="Black"/>
                                    </Trigger>
                                    <Trigger Property="IsMouseOver" Value="false">
                                        <Setter Property="Background" Value="Transparent"/>
                                    </Trigger>
                                </Style.Triggers>
                            </Style>
                        </Border.Style>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition MinWidth="19" Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <ToggleButton x:Name="Expander" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ExpandCollapseToggleStyle}"/>
                            <ContentPresenter x:Name="PART_Header" ContentSource="Header" Grid.Column="1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </Grid>
                    </Border>

                    <ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"/>
                </StackPanel>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsExpanded" Value="false">
                        <Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
                    </Trigger>
                    <Trigger Property="HasItems" Value="false">
                        <Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
                    </Trigger>
                    <Trigger Property="IsSelected" Value="true">
                        <Setter Property="Background" TargetName="Bd" Value="Green"/>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="Black"/>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="true"/>
                            <Condition Property="IsMouseOver" Value="true"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" TargetName="Bd" Value="Red"/>
                    </MultiTrigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

如果有人有任何提示可以帮助我实现这一目标,我将不胜感激。此外,如果我尝试在 XAML 中而不是在 C# 中完成大部分工作,但如果无法完成,我很乐意在 C# 中完成。谢谢。

最佳答案

我只是在这里添加了一些代码。

<Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}">
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                <Setter Property="Padding" Value="1,0,0,0"/>
                <Setter Property="Foreground" Value="Black"/>
                <Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TreeViewItem}">
                            <StackPanel>
                                <Border x:Name="Bd" Grid.ColumnSpan="3" BorderThickness="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true" Margin="3,0,3,-1" MinHeight="20">
                                    <Border.Style>
                                        <Style TargetType="{x:Type Border}">
                                            <Style.Triggers>
                                                <Trigger Property="IsMouseOver" Value="true">
                                                    <Setter Property="Background" Value="Red"/>
                                                    <Setter Property="BorderBrush" Value="Black"/>
                                                </Trigger>
                                                <Trigger Property="IsMouseOver" Value="false">
                                                    <Setter Property="Background" Value="Transparent"/>
                                                </Trigger>
                                            </Style.Triggers>
                                        </Style>
                                    </Border.Style>
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition MinWidth="19" Width="Auto"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>
                                        <ToggleButton x:Name="Expander" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ExpandCollapseToggleStyle}"/>
                                        <ContentPresenter x:Name="PART_Header" ContentSource="Header" Grid.Column="1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                    </Grid>
                                </Border>

                                <ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"/>
                            </StackPanel>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsExpanded" Value="false">
                                    <Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
                                </Trigger>
                                <Trigger Property="HasItems" Value="false">
                                    <Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
                                </Trigger>
                                <Trigger Property="IsSelected" Value="true">
                                    <Setter Property="Background" TargetName="Bd" Value="Green"/>
                                    <Setter Property="BorderBrush" TargetName="Bd" Value="Black"/>
                                </Trigger>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="IsSelected" Value="true"/>
                                        <Condition Property="IsMouseOver" Value="true"/>
                                    </MultiTrigger.Conditions>
                                    <Setter Property="Background" TargetName="Bd" Value="Red"/>
                                </MultiTrigger>
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                                </Trigger>


                                <!--begin: I added just this, but you can cleanup your xaml and made it better, this just showing how you can do-->
                                <MultiDataTrigger>
                                    <MultiDataTrigger.Conditions>
                                        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="true"/>
                                        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" Value="true"/>
                                        <Condition Binding="{Binding ElementName=ItemsHost, Path=IsMouseOver}" Value="True"/>
                                    </MultiDataTrigger.Conditions>
                                    <Setter Property="Background" TargetName="Bd" Value="Green"/>
                                </MultiDataTrigger>
                                <!--end-->

                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

关于c# - 将鼠标悬停在子节点上时,TreeViewItem 父节点和子节点 IsSelected 分离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53153284/

相关文章:

c# - 应用程序图标

c# - 可以在声明为 void 的 C# 方法中使用 "return"语句吗?

wpf - 在WPF MVVM项目的解决方案资源管理器中移动XAML文件

c# - 在带有 MVVM 的 DataTemplate 中使用窗口资源

C# WPF 应用程序在 Visual 中启动,但直接运行时无法启动

c# - Entity Framework : How to map Int64 field to Int32 db column?

c# - C# 中的方法 BitConverter.DoubleToInt64Bits (Double)

c# - XAML 弹出模板中的 opaqueRect 有何用途

c# - “文本”属性不能从属性触发器设置并同时出现在触发器的条件中

c# - 如何使文本框的宽度像xaml中的按钮一样动态