Pergunta

Estou desenvolvendo um TreeView controle baseado e meu evento de clique duplo continua a borbulhar meu TreeViewItem nós.

O objetivo é ter o TreeViewItem Expanda ou colapse quando for clicada duas vezes.

Eu tenho um estilo que aplica um manipulador de eventos para o MouseDoubleClick evento para cada um TreeViewItem.

Aqui está o código que lida com o evento


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

Isso funciona bem para o nível superior TreeViewItem No entanto, quando uma criança é clicada duas vezes, o evento borbulha a árvore, fazendo com que todo o ramo entre em colapso. Por que o evento continua a borbulhar? Como observado a [1] Estou definindo o evento como tratado.

Foi útil?

Solução

Odeio responder às minhas próprias perguntas, mas aqui está a solução que eu finalmente cheguei a usar.

Depois de encontrar algumas fontes que especificaram que o mousedoubleclick é levantado para cada TreeViewItem no ramo (da criança até a raiz), independentemente de o evento ser tratado, utilizei a resposta desta pergunta:

WPF TreeView, Get TreeViewItem no Evento PreviewMouDown

Para obter o TreeViewItem que estava no evento do mouse. Se o remetente atual for igual ao TreeViewItem do evento do mouse, expandi/colapso conforme necessário. Caso contrário, eu apenas ignoro o evento e não faço nada.

Outras dicas

Não tenho idéia do porquê, mas a resposta selecionada não funcionou para cada TreeViewItems para mim. Então eu usei um simples bool abordagem de cerca de reeintering TreeViewItemDoubleClicked mais de uma vez.

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

Para permitir que o primeiro manipulador invocado seja executado totalmente (portanto, confiando no fato de que o manipulador de uma criança será chamado antes de seus pais), basta adicionar:

private void TreeView_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    bubblingBulkwark = false;
}

E não se esqueça de registrá -lo.

treeView.PreviewMouseDown += TreeView_PreviewMouseDown;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top