In WPF, TreeView does not support right-click selection by default. That is to say, a node cannot be selected when right-click a node. When we want to implement the right-click menu in TreeViewItem, we usually want to select this node while the menu is popped up, so that the menu takes effect for the selected node.
Figure 1: although the shortcut menu is displayed on the GNU node, the selected node is still the DOC node that was left-clicked last time.
Figure 2: Right-click the pop-up menu and select the GNU node.
It is not difficult to implement this function. My first practice is the popular online version:
- Response to the PreviewMouseRightButtonDown event in the TreeViewItem
- Right-click the event and select the sender (TreeViewItem) node.
Private void TreeViewItem_PreviewMouseRightButtonDown (object sender, MouseButtonEventArgs e)
{
Var treeViewItem = sender as TreeViewItem;
If (treeViewItem! = Null)
{
TreeViewItem. Focus ();
E. Handled = true;
}
}
However, when a subnode is selected, the sender is not the TreeViewItem of the subnode, but its parent node. As a result, you cannot select a subnode. As shown in:
It is not difficult to solve this problem, that is, to obtain the node based on the OriginalSource of MouseButtonEventArgs. However, OriginalSource is not a TreeViewItem, but a child control that generates a mouse event. Therefore, you have to search for it to find the TreeViewItem.
The final solution is as follows:
1. Respond to the PreviewMouseRightButtonDown event in the TreeViewItem
<TreeView. ItemContainerStyle>
<Style TargetType = "{x: Type TreeViewItem}">
<EventSetter Event = "TreeViewItem. PreviewMouseRightButtonDown" Handler = "TreeViewItem_PreviewMouseRightButtonDown"/>
</Style>
</TreeView. ItemContainerStyle>
2. Right-click the event and select the TreeViewItem node.
Private void TreeViewItem_PreviewMouseRightButtonDown (object sender, MouseButtonEventArgs e)
{
Var treeViewItem = VisualUpwardSearch <TreeViewItem> (e. OriginalSource as DependencyObject) as TreeViewItem;
If (treeViewItem! = Null)
{
TreeViewItem. Focus ();
E. Handled = true;
}
}
Static DependencyObject VisualUpwardSearch <T> (DependencyObject source)
{
While (source! = Null & source. GetType ()! = Typeof (T ))
Source = VisualTreeHelper. GetParent (source );
Return source;
}
Now is a perfect solution.