Обработано RoutedEvent продолжает пузыриться в дереве
Я разрабатываю TreeView
на основе управления и мое событие двойного щелчка продолжает пузыриться мой TreeViewItem
узлы.
Цель состоит в том, чтобы иметь TreeViewItem
развернуть или свернуть при двойном щелчке.
У меня есть стиль, который применяет обработчик событий для MouseDoubleClick
событие для каждого TreeViewItem
,
Вот код, который обрабатывает событие
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.IsExpanded = false;
}
else
{
treeViewItem.IsExpanded = true;
}
// Set event handled
e.Handled = true; // [1]
}
}
Это прекрасно работает для верхнего уровня TreeViewItem
однако при двойном щелчке по дочернему элементу дерево всплывает, что приводит к разрушению всей ветви. Почему событие продолжает пузыриться? Как отметил [1]
Я устанавливаю событие как обработанное.
2 ответа
Ненавижу отвечать на мои собственные вопросы, но вот решение, которое я в конечном итоге пришел использовать.
После обнаружения нескольких источников, которые указали, что MouseDoubleClick вызывается для каждого TreeViewItem в ветви (от дочернего до корневого) независимо от того, обрабатывается ли событие, я использовал ответ на этот вопрос:
WPF TreeView, получить TreeViewItem в событии PreviewMouseDown
чтобы получить TreeViewItem, который был под событием мыши. Если текущий отправитель равен TreeViewItem события мыши, я разверну / сверну, как требуется. В противном случае я просто игнорирую событие и ничего не делаю.
Понятия не имею почему, но выбранный ответ не работает для всех TreeViewItems
для меня. Так что я использовал простой bool
подход к забору от повторного входа TreeViewItemDoubleClicked
больше чем единожды.
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;
}
}
Чтобы позволить самому первому обработчику, вызываемому полностью выполнить (следовательно, полагаясь на тот факт, что обработчик дочернего элемента будет вызываться до его родительского обработчика), просто добавьте:
private void TreeView_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
bubblingBulkwark = false;
}
И не забудьте зарегистрировать его.
treeView.PreviewMouseDown += TreeView_PreviewMouseDown;