Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why e.Source depends on TreeView populating method?

I have two trees:

  1. fooTree - made up of elements,
  2. barTree - constructed by

Both trees have MouseRightButtonDown event, but the e.Source type differs:

  1. fooTree - System.Windows.Controls.TreeViewItem
  2. barTree - System.Windows.Controls.TreeView

Why e.Source differs? Also, how can I get the clicked item for the barTree?

Markup:

    <TreeView Name="fooTree" MouseRightButtonDown="fooTree_MouseDown">
        <TreeViewItem Header="foo"></TreeViewItem>
        <TreeViewItem Header="foo"></TreeViewItem>
    </TreeView>

    <TreeView Name="barTree" MouseRightButtonDown="barTree_MouseDown" ItemsSource="{Binding BarItems}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate>
                <TextBlock Text="{Binding}" />
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

Code:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    public string[] BarItems
    {
        get { return new string[] { "bar", "bar" }; }
    }

    private void barTree_MouseDown(object sender, MouseButtonEventArgs e) 
    {
    }

    private void fooTree_MouseDown(object sender, MouseButtonEventArgs e) 
    {
    }
}
like image 229
alex2k8 Avatar asked Feb 23 '26 09:02

alex2k8


2 Answers

Don't know why this happens, but at least I have found a solution:

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/f0d3af69-6ecc-4ddb-9526-588b72d5196b/

  1. If your handler is on the TreeView, use the OriginalSource property in the event arguments and walk up the visual parent chain until you find a TreeViewItem. Then, select it. You can walk the visual parent chain by using System.Windows.Media.VisualTreeHelper.GetParent.

  2. You could try registering a class handler for type TreeViewItem and the mouse down event. Then, your handler should only be called when mouse events pass through TreeViewItem elements.

  3. You could register a class handler for type TreeViewItem and the context menu opening event.

So my code is:

private void OnMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    TreeViewItem treeViewItem = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
}

static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
{
    while (source != null && source.GetType() != typeof(T))
        source = VisualTreeHelper.GetParent(source);

    return source;
}
like image 50
alex2k8 Avatar answered Feb 26 '26 15:02

alex2k8


You can get the clicked item in the bartree using:

((e.Source) as TreeView).SelectedValue

But be aware that the item must actually selected first (using leftMouse). The item is not immediately selected using rightMouse...

like image 35
Jowen Avatar answered Feb 26 '26 14:02

Jowen