I originally used an extension method for TreeView that accepts a UIElement - the sender of the PreviewMouseDown event - for example:
private void MyTreeView_PreviewMouseDown(object sender, MouseButtonEventArgs e) { var uiElement = sender as UIElement; var treeViewItem = myTreeView.TreeViewItemFromChild(uiElement); }
The extension method is used here (it is checked by the child himself if you directly clicked on TreeViewItem) ...
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, since then I have switched it to a more general version, which 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; }
This either finds the type you are looking for (again, including checking for itself), or returns null
You would use it in the same PreviewMouseDown handler as ...
private void MyTreeView_PreviewMouseDown(object sender, MouseButtonEventArgs e) { var uiElement = sender as UIElement; var treeViewItem = uiElement.FindAncestor<TreeViewItem>(); }
This is very convenient when my TreeViewItem had a CheckBox template in the template, and I wanted to select an item when the user clicked a checkbox that usually swallows the event.
Hope this helps!
source share