WPF TreeView, get TreeViewItem in PreviewMouseDown event

懵懂的女人 提交于 2019-12-10 18:42:59

问题


How can I determine TreeViewItem clicked in PreviewMouseDown event?


回答1:


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;
}



回答2:


I originally used an extension method on TreeView that takes a UIElement--the sender of the PreviewMouseDown event--like this:

private void MyTreeView_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var uiElement = sender as UIElement;
    var treeViewItem = myTreeView.TreeViewItemFromChild(uiElement);
}

Here's the extension method (it checks the child itself in case you clicked right on a TreeViewItem directly)...

public static TreeViewItem TreeViewItemFromChild(this TreeView treeView, UIElement child)
{
    UIElement proposedElement = child;

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

    return proposedElement as TreeViewItem;
}

Update:

However, I've since switched it to a more generic version that I can use anywhere.

public static TAncestor FindAncestor<TAncestor>(this UIElement uiElement)
{
    while ((uiElement != null) && !(uiElement is TAncestor))
        retVal = VisualTreeHelper.GetParent(uiElement) as UIElement;

    return uiElement as TAncestor;
}

That either finds the type you're looking for (again, including checking itself) or returns null

You'd use it in the same PreviewMouseDown handler like so...

private void MyTreeView_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var uiElement = sender as UIElement;
    var treeViewItem = uiElement.FindAncestor<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.

Hope this helps!



来源:https://stackoverflow.com/questions/2941762/wpf-treeview-get-treeviewitem-in-previewmousedown-event

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!