views:

248

answers:

2

How can I determine TreeViewItem clicked in PreviewMouseDown event?

A: 

The following seems to work:

private void myTreeView_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
  TreeViewItem item = GetTreeViewItemClicked((FrameworkElement)e.OriginalSource, 
                                                                       myTreeView);
  ...
}

private TreeViewItem GetTreeViewItemClicked(FrameworkElement sender, TreeView treeView)
{
  Point p = ((sender as FrameworkElement)).TranslatePoint(new Point(0, 0), treeView);
  DependencyObject obj = treeView.InputHitTest(p) as DependencyObject;
  while (obj != null && !(obj is TreeViewItem))
    obj = VisualTreeHelper.GetParent(obj);
  return obj as TreeViewItem;
}
synergetic
A: 

I use an attached property on TreeView that takes a UIElement, which is the sender in your PreviewMouseDown event. So put this in your handler...

private void myTreeView_PreviewMouseDown(object sender, MouseButtonEventArgs e){

    TreeViewItem item = myTreeView.TreeViewItemFromUIElement(sender as UIElement);

}

and here's the attached property...

public static TreeViewItem TreeViewItemFromUIElement(this TreeView treeView, UIElement element) {

    UIElement retVal = element;

    while ((retVal != null) && !(retVal is TreeViewItem)) retVal = VisualTreeHelper.GetParent(retVal) as UIElement;

    return retVal as TreeViewItem;

}

This came in very handy for when my TreeViewItem had a CheckBox in its template and I wanted to select the item when the user clicked the checkbox which normally swallows the event.

You can use this same code for a ListBox and a ComboBox (any ItemsControl actually) by changing TreeViewItem to the appropriate type.

Hope this helps!

MarqueIV