Handled RoutedEvent continues to bubble up tree
I'm developing a TreeView
based control and my double click event continues to bubble up my TreeViewItem
nodes.
The goal is to have the TreeViewItem
expand or collapse when it is double clicked.
I have a style that applies an event handler for the MouseDoubleClick
event to each TreeViewItem
.
Here's the code that handles the event
private void TreeViewItemDoubleClicked( object sender, RoutedEventArgs e )
{
// Get the specific tree view item that was double clicked
TreeViewItem treeViewItem = sender as TreeViewItem;
// not null?
if( null != treeViewItem )
{
// Switch expanded state
if( true == treeViewItem.IsExpanded )
{
treeViewItem.IsExpan开发者_如何学JAVAded = false;
}
else
{
treeViewItem.IsExpanded = true;
}
// Set event handled
e.Handled = true; // [1]
}
}
This works fine for the top level TreeViewItem
however when a child is double clicked, the event bubbles up the tree causing the entire branch to collapse. Why is the event continuing to bubble? As noted a [1]
I'm setting the event as handled.
Hate answering my own questions but here is the solution that I ultimately came to use.
After coming across a few sources that specified that the MouseDoubleClick is raised for each TreeViewItem in the branch ( from child up to the root ) regardless if the event is handled I utilized the answer from this question:
WPF TreeView, get TreeViewItem in PreviewMouseDown event
to get the TreeViewItem that was under the mouse event. If the current sender is equal to the TreeViewItem of the mouse event I expand/collapse as required. Otherwise, I just ignore the event and do nothing.
No idea why, but the selected answer didn't work for every TreeViewItems
for me. So I used a simple bool
approach to fence from reeintering TreeViewItemDoubleClicked
more than once.
private void TreeViewItemDoubleClicked( object sender, RoutedEventArgs e )
{
// Make sure the event has never been handled first
if (bubblingBulkwark)
return;
// Get the specific tree view item that was double clicked
TreeViewItem treeViewItem = sender as TreeViewItem;
// not null?
if( null != treeViewItem )
{
// Switch expanded state
if( true == treeViewItem.IsExpanded )
{
treeViewItem.IsExpanded = false;
}
else
{
treeViewItem.IsExpanded = true;
}
// Raise bulkwark
bubblingBulkwark = true;
}
}
To allow the very first handler invoked to execute fully (therefore relying on the fact that a child's handler will be called before it's parent's), simply add :
private void TreeView_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
bubblingBulkwark = false;
}
And don't forget to register it.
treeView.PreviewMouseDown += TreeView_PreviewMouseDown;
精彩评论