views:

7061

answers:

3

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

For WinForms I could use code like this http://stackoverflow.com/questions/2527/c-treeview-context-menus, what are the WPF alternatives?

+6  A: 

In XAML, add a PreviewMouseRightButtonDown handler in XAML:

    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <!-- We have to select the item which is right-clicked on -->
            <EventSetter Event="TreeViewItem.PreviewMouseRightButtonDown" Handler="TreeViewItem_PreviewMouseRightButtonDown"/>
        </Style>
    </TreeView.ItemContainerStyle>

Then handle the event like this:

 private void TreeViewItem_PreviewMouseRightButtonDown( object sender, MouseEventArgs e )
 {
  TreeViewItem item = sender as TreeViewItem;
  if ( item != null )
  {
   item.Focus( );
   e.Handled = true;
  }
 }
Stefan
It does not work as expected, I always get the root element as a sender. I have found a similar solution one http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/25e113a5-6f52-4c25-974f-d58b9b689f62/ Event handlers added this way works as expected. Any changes to your code to accept it? :-)
alex2k8
It apparently depends on how you populate the tree view. The code I posted works, because that's the exact code I use in one of my tools.
Stefan
+14  A: 

Depending on the way the tree was populated, the sender and the e.Source values may vary (http://stackoverflow.com/questions/593194/why-e-source-depends-on-treeview-populating-method)

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<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;
}
alex2k8
+2  A: 

Using "item.Focus();" doesn't seems to work 100%, using "item.IsSelected = true;" does.

Erlend