C# WPF TreeView项目上下文菜单取消高亮显示项目

C# WPF TreeView项目上下文菜单取消高亮显示项目,c#,wpf,treeview,C#,Wpf,Treeview,一段时间以来,我一直在这方面遇到问题,并提出了一些不太理想的解决方案。问题在于,当打开TreeView项目的上下文菜单时,TreeView项目会变灰。当一个TreeViewItem的ContextMenu打开时,它是否可以保持高亮显示 TreeViewItem变灰的问题在于,它与上下文菜单和TreeViewItem没有任何关系,而且看起来很难看 通常,我用于设置上下文菜单的代码如下所示。有时,带有PreviewRightMouseButtonDown事件设置器的代码将生成上下文菜单,但这并没有什

一段时间以来,我一直在这方面遇到问题,并提出了一些不太理想的解决方案。问题在于,当打开TreeView项目的上下文菜单时,TreeView项目会变灰。当一个TreeViewItem的ContextMenu打开时,它是否可以保持高亮显示

TreeViewItem变灰的问题在于,它与上下文菜单和TreeViewItem没有任何关系,而且看起来很难看

通常,我用于设置上下文菜单的代码如下所示。有时,带有PreviewRightMouseButtonDown事件设置器的代码将生成上下文菜单,但这并没有什么区别:

    <TreeView>
        <TreeView.Resources>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="ContextMenu">
                    <Setter.Value>
                        <ContextMenu>
                            <MenuItem Header="Menu Item 1" />
                            <MenuItem Header="Menu Item 2" />
                        </ContextMenu>
                    </Setter.Value>
                </Setter>
            </Style>
        </TreeView.Resources>
        <TreeViewItem Header="Item 1">
            <TreeViewItem Header="Sub-Item 1"/>
        </TreeViewItem>
        <TreeViewItem Header="Item 2"></TreeViewItem>
    </TreeView>


到目前为止,我找到的唯一解决方案是用聚焦颜色覆盖“灰色”未聚焦颜色,但是TreeView从来不会出现未聚焦的情况,例如当单击另一个控件时。我在ListView方面也遇到了问题。

WPF的默认行为是在ContextMenu打开时将TreeView项更改为灰色,但与WPF中的其他内容一样,您可以覆盖以下内容:

  • 创建附加的属性ContextMenuOpened
  • 在TreeViewItem样式中,将打开的ContextMenuo绑定到“ContextMenu.IsOpen”
  • 添加一个触发器,在ContextMenuOpened和IsSelected均为true时更改画笔
  • 这是随附的财产:

    public class TreeViewCustomizer : DependencyObject
    {
      public static bool GetContextMenuOpened(DependencyObject obj) { return (bool)obj.GetValue(ContextMenuOpenedProperty); }
      public static void SetContextMenuOpened(DependencyObject obj, bool value) { obj.SetValue(ContextMenuOpenedProperty, value); }
      public static readonly DependencyProperty ContextMenuOpenedProperty = DependencyProperty.RegisterAttached("ContextMenuOpened", typeof(bool), typeof(TreeViewCustomizer));
    }
    
    下面是样式中的setter:

    <Setter Property="my:TreeViewCustomizer.ContextMenuOpened"
            Value="{Binding ContextMenu.IsOpen, RelativeSource={RelativeSource Self}}" />
    
    
    
    触发因素如下:

    <MultiTrigger>
      <MultiTrigger.Conditions>
        <Condition Property="IsSelected" Value="true"/>
        <Condition Property="my:TreeViewCustomizer.ContextMenuOpened" Value="true"/>
      </MultiTrigger.Conditions>
      <Setter TargetName="Bd"
              Property="Background"
              Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
      <Setter Property="Foreground"
              Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
    </MultiTrigger>
    
    
    

    工作原理:每次ContextMenu打开时,都会设置其IsOpen属性。绑定会导致在TreeViewItem上设置附加的属性。这与IsSelected一起调用触发器,该触发器更改前景色和背景色,使项目仍然显示为选中状态。

    。我自己从来没有想到过。不过有一件事:背景设置不正确,但前景设置不正确。我觉得这与TargetName=“Bd”有关,它无法编译。我的回答假设您的自定义TreeViewItem控件模板是默认TreeViewItem控件模板的编辑副本。“Bd”是边框的默认TreeViewItem控件模板中使用的名称。如果为TreeViewItem构建了一个完全自定义的ControlTemplate,而不是复制系统模板并对其进行编辑,则模板中可能根本没有边框,或者它可能被命名为其他名称。在这种情况下,您可能需要另一个TargetName来设置项目的背景色。我刚刚意识到我可能假设得太多了:也许您根本没有为TreeView项目创建自定义控件模板。在这种情况下,除了替换资源之外,我看不到任何影响模板内边框颜色的方法,正如您所注意到的,这些资源具有某种全局范围。因此,我认为您需要使用定制的ControlTemplate。在Blend中,只需右键单击控件并从上下文菜单中选择Edit Template->Edit A Copy,然后将我的MultiTrigger添加到模板中触发器列表的底部。好吧,希望不会出现这种情况,但必须这样做(不幸的是,我没有Blend,但我在前面找到了默认模板)。再次感谢。嘿,我如何通过C#而不是通过XAML实现这一点,因为我已经通过.cs文件创建了我的treeview控件。