如何在显示关联的上下文菜单之前自动 select WPF TreeView 节点,而不管是什么导致显示它?

How to automatically select a WPF TreeView node before associated context menu is displayed, regardless of what caused it to be displayed?

默认情况下,显示与 WPF TreeView 节点关联的上下文菜单不会影响选择了哪些节点。在我的 TreeView 中,我希望与显示的上下文菜单关联的节点成为选定节点。

我研究过此处已回答的类似问题,包括 this one, this one, and this one。令我惊讶的是,none 所提供的答案令人满意,因为它们都假定鼠标右键单击是导致显示上下文菜单的事件。

虽然长期以来单击鼠标右键一直是显示上下文菜单的标准方法,但这并不是唯一的方法。例如,用户可能会使用键盘上的“菜单”键。未来可能会出现新的输入设备和显示上下文菜单的新方法。通过尝试预测所有可能导致上下文菜单显示的不同事物来解决这个问题似乎是错误的。

是否有解决此问题的解决方案,该解决方案与正在使用的特定输入设备无关?

我认为您可以捕获 ContextMenu.Opened 事件并使关联的 TreeViewItem 的 IsSelected 属性 为真。

比方说,使用 Microsoft.Xaml.Behaviors.Wpf,行为将是这样的。

using System.Windows;
using System.Windows.Controls;
using Microsoft.Xaml.Behaviors;

public class ContextMenuBehavior : Behavior<ContextMenu>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        this.AssociatedObject.Opened += OnOpened;
    }

    protected override void OnDetaching()
    {
        this.AssociatedObject.Opened -= OnOpened;

        base.OnDetaching();
    }

    private void OnOpened(object sender, RoutedEventArgs e)
    {
        switch (((ContextMenu)sender).PlacementTarget)
        {
            case TreeViewItem item:
                item.IsSelected = true;
                break;
        }
    }
}

我得到的解决方案与@emoacht 提出的类似,但处理上下文菜单父控件上的 ContextMenuOpening 事件,而不是上下文菜单本身的 OnOpened 事件。这样,节点选择和上下文菜单显示就会按所需的顺序进行。