【问题标题】:WPF TreeView: highlight item on mouse overWPF TreeView:鼠标悬停时突出显示项目
【发布时间】:2014-09-19 09:47:39
【问题描述】:

在 WPF 中,当你有一个 ListView 用鼠标传递一个项目时,会产生一个很好的高亮效果,如下所示:

但是,TreeView 不会发生这种情况。我的问题很简单:如何为 TreeView 中的项目启用相同的效果?

注意:我知道这些问题: WPF TreeView Highlight Row On Hover Highlight whole TreeViewItem line in WPF

但他们主要关注将突出显示行为扩展到整行,而我仍然不知道如何在单个 TreeViewItem 上启用突出显示效果(这对我来说已经足够了)

【问题讨论】:

    标签: wpf treeview


    【解决方案1】:

    通常我们可以为TreeViewItem 添加一些样式,并带有一些触发器来切换鼠标悬停的背景。但是,当TreeViewItem 相互包含(嵌套)并且事件的冒泡会导致一些不良影响时,情况并非如此简单。我已经尝试用这种方法解决问题,但没有运气(几乎解决了它,但并不完美)。

    所以我们必须使用另一种方法,这里我们将通过设置TreeViewItemHeaderTemplate来更改Header的模板。在该模板中,我们将为根边框添加触发器,然后一切正常:

    <TreeView>
       <TreeView.Resources>
           <Style TargetType="TreeViewItem">
              <Setter Property="HeaderTemplate">
                  <Setter.Value>
                    <DataTemplate>  
                      <Border>
                         <TextBlock Text="{Binding}"/>
                         <Border.Style>
                           <Style TargetType="Border">
                             <Setter Property="BorderThickness" Value="1"/>
                             <Setter Property="BorderBrush" Value="Transparent"/>
                             <Style.Triggers>
                               <MultiDataTrigger>
                               <MultiDataTrigger.Conditions>
                                 <Condition Binding="{Binding RelativeSource={RelativeSource Self},
                                                      Path=IsMouseOver}" Value="True"/>
                                 <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=TreeViewItem},
                                                      Path=IsSelected}" Value="False"/>
                               </MultiDataTrigger.Conditions>
                               <Setter Property="Background" Value="#ffe5f3fb"/>
                               <Setter Property="BorderBrush" Value="#ffa5d7f0"/>
                               </MultiDataTrigger>
                             </Style.Triggers>
                           </Style>
                          </Border.Style>
                        </Border>
                      </DataTemplate>
                    </Setter.Value>
                 </Setter>              
           </Style>
       </TreeView.Resources>
       <TreeViewItem Header="Item 1">
          <TreeViewItem Header="Item 11"></TreeViewItem>
          <TreeViewItem Header="Item 12"/>
       </TreeViewItem>
       <TreeViewItem Header="Item 2">
       </TreeViewItem>
    </TreeView>
    

    请注意,您可以创建任何您喜欢的Brush 来替换我上面用于Background 的简单SolidColorBrush。您应该阅读更多关于 WPF 中的Brush 的信息。

    更新:据我所知,要与有关颜色和画笔的系统设置同步,我们只有静态类 SystemColors。我为悬停突出显示找到的最接近的颜色是SystemColors.HotTrackColorKey。但是我猜想在 Windows 7 中用于ListView 的悬停高光为画笔应用了一些不透明度,并且看起来更轻。所以我尝试使用0.05 的不透明度作为画笔,它看起来非常接近 Windows 7 中 ListView 的默认突出显示颜色。您可以在资源中定义画笔并像这样使用它:

    //inside the Style for Border
    <Style.Resources>
        <SolidColorBrush x:Key="hoverBrush" Opacity=".05" 
                 Color="{DynamicResource {x:Static SystemColors.HotTrackColorKey}}"/>
    </Style.Resources>
    

    然后通过Setter设置背景画笔:

    <Setter Property="Background" Value="{DynamicResource hoverBrush}"/>
    

    【讨论】:

    • 这个“有点”有效,但它有两个问题:1)高光画笔只是一种颜色。有没有像我发布的图片那样提供漂亮的背景+边框效果的画笔?还是我必须手动设置边框? 2)如果您将鼠标悬停在树中的子项上,则父项也会突出显示,这看起来很奇怪
    • @Master_T 我刚刚意识到有一个问题,那就是悬停项目的父项也被突出显示(这可能不是你想要的),那么另一个问题是什么?
    • 我正在编辑,另一个问题正是你提到的。我读到其他答案,这应该通过将 TargetName="Bd" 添加到设置器的属性来解决,但这会破坏我的编译(“TargetName 属性不能在样式设置器上设置”)
    • @Master_T 查看我更新的代码。我认为这是您可以拥有的最简单 解决方案。事实上,其他解决方案可能不会更复杂,但它需要您将默认模板的大文件导入到您的项目中。
    • 感谢您的输入,您的新代码有效(它与我的 ItemTemplate 冲突,但我对其进行了一些重构,现在它很完美)。一个问题,如果你知道:“悬停”项目的边框和背景颜色是否有默认画笔,还是我必须手动输入?我问是因为在不同的 Windows 版本上,他们可能会决定更改它……有没有办法知道代码中的正确颜色?我检查了 SystemColors 类中的那些,但似乎没有一个与 ListView 匹配(我在图片中显示的那个)。
    猜你喜欢
    • 2012-05-13
    • 1970-01-01
    • 1970-01-01
    • 2015-05-02
    • 1970-01-01
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多