none
TreeView change selection on right click RRS feed

  • Question

  • Hello,

     

    How can i change the treeviewitem selection when the user right mouse clicks on any treeviewitem?

     

    Thanks and Regards,

    Sheetal

    Thursday, February 14, 2008 1:27 AM

Answers

  • Here is the code:

    Code Snippet
    <TreeView Name="treeView"
    ItemsSource="{Binding Path=Root.Elements}"
    ItemTemplate="{StaticResource template}">
    <
    TreeView.ItemContainerStyle>
    <
    Style TargetType="TreeViewItem">
    <
    EventSetter
    Event="TreeViewItem.MouseRightButtonDown"
    Handler="TreeViewItem_MouseRightButtonDown"/>
    </
    Style>
    </
    TreeView.ItemContainerStyle>
    </
    TreeView>

    private void
    TreeViewItem_MouseRightButtonDown(object sender, MouseEventArgs e)
    {
    TreeViewItem item = sender as TreeViewItem;
    if (item != null)
    {
    item.Focus();
    e.Handled = true;
    }
    }


    For the explanation on why setting focus can select the TreeViewItem, you can refer to this thread instead.

    Hope this helps

    Monday, February 18, 2008 2:23 AM

All replies

  • Here is the code:

    Code Snippet
    <TreeView Name="treeView"
    ItemsSource="{Binding Path=Root.Elements}"
    ItemTemplate="{StaticResource template}">
    <
    TreeView.ItemContainerStyle>
    <
    Style TargetType="TreeViewItem">
    <
    EventSetter
    Event="TreeViewItem.MouseRightButtonDown"
    Handler="TreeViewItem_MouseRightButtonDown"/>
    </
    Style>
    </
    TreeView.ItemContainerStyle>
    </
    TreeView>

    private void
    TreeViewItem_MouseRightButtonDown(object sender, MouseEventArgs e)
    {
    TreeViewItem item = sender as TreeViewItem;
    if (item != null)
    {
    item.Focus();
    e.Handled = true;
    }
    }


    For the explanation on why setting focus can select the TreeViewItem, you can refer to this thread instead.

    Hope this helps

    Monday, February 18, 2008 2:23 AM
  • Thanks, works perfect.
    AVEbrahimi
    Monday, February 9, 2009 8:36 AM
  • This doesn't work for me when the items are defined in XAML.  What would cause it to work with data binding but not with XAML?  I use the exact code in a new window, but removed the ItemsSource  and ItemTemplate, and the focus always returns to the root node when I right-click on any node:

    <Window x:Class="CheatStudio.Test.WindowSimpleTreeTest"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WindowSimpleTreeTest" Height="300" Width="300">
        <Grid>
            <TreeView Name="treeView">
                <TreeView.ItemContainerStyle>
                    <Style TargetType="TreeViewItem">
                        <EventSetter
                            Event="TreeViewItem.MouseRightButtonDown"
                            Handler="TreeViewItem_MouseRightButtonDown"/>
                    </Style>
                </TreeView.ItemContainerStyle>
                <TreeViewItem Header="Root">
                    <TreeViewItem Header="Grandma">
                        <TreeViewItem Header="Mom">
                            <TreeViewItem Header="Sis"/>
                        </TreeViewItem>
                    </TreeViewItem>
                </TreeViewItem>
            </TreeView>
        </Grid>
    </Window>
    
    Wednesday, September 2, 2009 9:17 AM
  • Update: It only works for top-level tree items even with binding.  Using a Setter on the Background property of TreeViewItem, it only shows over the header contents, so there must be some background control from TreeView to draw the + and -, and TreeView must be hogging the right mouse button and only passing it to the children.
    Wednesday, September 2, 2009 9:47 AM
  • I found a solution.  I wrote a method for the PreviewRightMouseButtonDown event on the TreeView object itself.  It uses TreeView.InputHitTest() to find the IInputElement where the click was made.  This ends up being a TextBlock or whatever else is in the TreeView.Header, so I walk up casting IInputElement as FrameworkElement to get at Parent or TemplatedParent until I find the TreeViewItem element, then call Focus() on it.  Since this is on the right mouse button DOWN, ContextMenus work and pop up after the new TreeViewItem is selected.

    private void TreeView_PreviewRightMouseButtonDown(object sender, MouseButtonEventArgs e)
    {
    	TreeView tv = (TreeView)sender;
    	IInputElement element = tv.InputHitTest(e.GetPosition(tv));
    	while (!((element is TreeView) || element == null))
    	{
    		if (element is TreeViewItem)
    			break;
    
    		if (element is FrameworkElement)
    		{
    			FrameworkElement fe = (FrameworkElement)element;
    			element = (IInputElement)(fe.Parent ?? fe.TemplatedParent);
    		}
    		else
    			break;
    	}
    	if (element is TreeViewItem)
    	{
    		element.Focus();
    		e.Handled = true;
    	}
    }
    

    • Proposed as answer by Tim ManganMVP Sunday, February 24, 2013 3:30 AM
    Friday, September 4, 2009 9:00 AM
  • If i do

    e.Handled=true;

    then I'm not able to get the ContextMenu opened.

    but if i don't do it, MouseDown is bubbled to the parent treeviewitem....
    :(
    • Proposed as answer by GrimAura Thursday, January 27, 2011 1:10 AM
    Friday, December 4, 2009 2:03 PM
  • In VB I use this and it seems to cause the node to be selected before the context menu open event fires.

     Private Sub Treeview1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Treeview1.MouseDown


            If e.Button = MouseButtons.Right Then
                Treeview1.SelectedNode = Treeview1.GetNodeAt(e.Location)
            End If
        End Sub

     

    Hope this helps.

    Thursday, January 27, 2011 1:15 AM