WPF TreeView:鼠标悬停时高亮显示项目

WPF TreeView:鼠标悬停时高亮显示项目,wpf,treeview,Wpf,Treeview,在WPF中,当您有一个ListView用鼠标传递一个项目时,会产生一个很好的高亮效果,如下所示: //inside the Style for Border <Style.Resources> <SolidColorBrush x:Key="hoverBrush" Opacity=".05" Color="{DynamicResource {x:Static SystemColors.HotTrackColorKey}}"/> <

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

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

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

注:我知道这些问题:


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

通常,我们可以为
treevieItem
添加一些样式,使用一些触发器在鼠标上方切换背景。然而,当
TreeViewItem
相互包含(嵌套)时,情况就不那么简单了,事件的冒泡将导致一些不必要的影响。我尝试过用这种方法来解决问题,但运气不好(只是几乎解决了问题,但不是很完美)

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

<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>
然后通过
Setter
设置背景笔刷:

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

通常,我们可以为
treevieItem
添加一些样式,使用一些触发器在鼠标上方切换背景。然而,当
TreeViewItem
相互包含(嵌套)时,情况就不那么简单了,事件的冒泡将导致一些不必要的影响。我尝试过用这种方法来解决问题,但运气不好(只是几乎解决了问题,但不是很完美)

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

<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>
然后通过
Setter
设置背景笔刷:

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


这种“有点”有效,但它有两个问题:1)高亮画笔只是一种颜色。有没有像我贴的图片中那样的画笔,可以提供很好的背景+边框效果?还是必须手动设置边框?2) 如果将鼠标悬停在树中的子项上,父项也会高亮显示,看起来weird@Master_T我刚刚意识到有一个问题,悬停项的父项也被突出显示(这可能不是您想要的),那么还有什么问题呢?我正在编辑,另一个问题正是您提到的。我在其他回答中读到,这应该通过向setter的属性添加TargetName=“Bd”来解决,但这会中断编译(“不能在样式setter上设置TargetName属性”)@Master\u看不到我的更新代码。我认为这是你能得到的最简单的解决办法。事实上,其他解决方案可能并不复杂,但它需要您将一个大文件的默认模板导入到您的项目中。感谢您的输入,您的新代码可以正常工作(它与我的ItemTemplate冲突,但我对它进行了一点重构,现在它非常完美)。一个问题,如果你知道的话:是否有一个默认的笔刷用于“悬停”项目的边框和背景颜色,或者我必须手动输入它?我这样问是因为在不同的windows版本上,他们可能会决定更改它。。。有没有办法知道代码中的正确颜色?我检查了SystemColor类中的选项,但似乎没有一个与ListView(我在图片中显示的)匹配。这种“有点”有效,但它有两个问题:1)高光笔刷只是一种颜色。有没有像我贴的图片中那样的画笔,可以提供很好的背景+边框效果?还是必须手动设置边框?2) 如果将鼠标悬停在树中的子项上,父项也会高亮显示,看起来weird@Master_T我刚刚意识到有一个问题,悬停项的父项也被突出显示(这可能不是您想要的),那么还有什么问题呢?我正在编辑,另一个问题正是您提到的。我在其他回答中读到,这应该通过向setter的属性添加TargetName=“Bd”来解决,但这会中断编译(“不能在样式setter上设置TargetName属性”)@Master\u看不到我的更新代码。我认为这是你能得到的最简单的解决办法。事实上,其他解决方案可能并不复杂,但它需要您将一个大文件的默认模板导入到您的项目中。感谢您的输入,您的新代码可以正常工作(它与我的ItemTemplate冲突,但我对它进行了一点重构,现在它非常完美)。一个问题,如果你知道的话:是否有一个默认的笔刷用于“悬停”项目的边框和背景颜色,或者我必须手动输入它?我这样问是因为在不同的windows版本上,他们可能会决定更改它。。。有没有办法知道代码中的正确颜色?我检查了SystemColor类中的那些,但似乎没有一个与ListView(我在图片中显示的)匹配。