Обработано 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;
Другие вопросы по тегам