Manipled Routedevent continua a borbulhar a árvore
-
27-09-2019 - |
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.
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;