Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select TreeView Node on right click before displaying ContextMenu

I would like to select a WPF TreeView Node on right click, right before the ContextMenu displayed.

For WinForms I could use code like this Find node clicked under context menu, what are the WPF alternatives?

like image 231
alex2k8 Avatar asked Feb 26 '09 20:02

alex2k8


People also ask

How do I know if Treeview node is selected?

SelectedNode; if ( tn == null ) Console. WriteLine("No tree node selected."); else Console. WriteLine("Selected tree node {0}.", tn.Name ); You can compare the returned TreeNode reference to the TreeNode you're looking for, and so check if it's currently selected.

What is Treeview item?

TreeViewItem is a HeaderedItemsControl, which means its header and collection of objects can be of any type (such as string, image, or panel). For more information, see the HeaderedItemsControl class.


2 Answers

Depending on the way the tree was populated, the sender and the e.Source values may vary.

One of the possible solutions is to use e.OriginalSource and find TreeViewItem using the VisualTreeHelper:

private void OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) {     TreeViewItem treeViewItem = VisualUpwardSearch(e.OriginalSource as DependencyObject);      if (treeViewItem != null)     {         treeViewItem.Focus();         e.Handled = true;     } }  static TreeViewItem VisualUpwardSearch(DependencyObject source) {     while (source != null && !(source is TreeViewItem))         source = VisualTreeHelper.GetParent(source);      return source as TreeViewItem; } 
like image 159
alex2k8 Avatar answered Sep 20 '22 13:09

alex2k8


If you want a XAML-only solution you can use Blend Interactivity.

Assume the TreeView is data bound to a hierarchical collection of view-models having a Boolean property IsSelected and a String property Name as well as a collection of child items named Children.

<TreeView ItemsSource="{Binding Items}">   <TreeView.ItemContainerStyle>     <Style TargetType="TreeViewItem">       <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>     </Style>   </TreeView.ItemContainerStyle>   <TreeView.ItemTemplate>     <HierarchicalDataTemplate ItemsSource="{Binding Children}">       <TextBlock Text="{Binding Name}">         <i:Interaction.Triggers>           <i:EventTrigger EventName="PreviewMouseRightButtonDown">             <ei:ChangePropertyAction PropertyName="IsSelected" Value="true" TargetObject="{Binding}"/>           </i:EventTrigger>         </i:Interaction.Triggers>       </TextBlock>     </HierarchicalDataTemplate>   </TreeView.ItemTemplate> </TreeView> 

There are two interesting parts:

  1. The TreeViewItem.IsSelected property is bound to the IsSelected property on the view-model. Setting the IsSelected property on the view-model to true will select the corresponding node in the tree.

  2. When PreviewMouseRightButtonDown fires on the visual part of the node (in this sample a TextBlock) the IsSelected property on the view-model is set to true. Going back to 1. you can see that the corresponding node that was clicked on in the tree becomes the selected node.

One way to get Blend Interactivity in your project is to use the NuGet package Unofficial.Blend.Interactivity.

like image 37
Martin Liversage Avatar answered Sep 18 '22 13:09

Martin Liversage