0

By default, displaying the context menu associated with a WPF TreeView node does not affect which nodes are selected. In my TreeView, I would like for the node associated with a displayed context menu to become the selected node.

I have researched similar questions that have been answered here, including this one, this one, and this one. To my surprise, none of the answers provided are satisfactory because they all presume that a right mouse click is the event that causes the context menu to be displayed.

While a right mouse click has long been a standard method of displaying a context menu, it is not the only way. For example, the user might use the "menu" key on the keyboard. New input devices, and new ways to display context menus might emerge in the future. Approaching this problem by attempting to anticipate all of the different things that could cause a context menu to be displayed seems wrong.

Is there a solution to this problem that is agnostic to the specific input device(s) in play?

Pancake
  • 739
  • 1
  • 5
  • 20

2 Answers2

0

I think you can captured ContextMenu.Opened event and make associated TreeViewItem's IsSelected property true.

Let's say, using Microsoft.Xaml.Behaviors.Wpf, the Behavior will be something like this.

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
  • 2,764
  • 1
  • 13
  • 24
  • Thanks @emoacht, you're not wrong -- however, this would cause the node selection to happen after the context menu is displayed. It's a seemingly minor detail, but in this question I specifically seek to perform the selection before displaying the context menu. – Pancake Mar 29 '22 at 21:36
0

The solution I arrived at is similar to what @emoacht proposed, but handles the ContextMenuOpening event on the context menu's parent control, instead of the OnOpened event on the context menu itself. This way, the node selection and context menu display occur in the desired sequence.

Pancake
  • 739
  • 1
  • 5
  • 20