RoutedEvent Handled continue à arbre bouillonner
-
27-09-2019 - |
Question
Je développe un contrôle basé sur TreeView
et mon événement double clic continue à bouillonner mes nœuds de TreeViewItem
.
Le but est d'avoir le TreeViewItem
développer ou réduire quand il est double-cliqué.
J'ai un style qui applique un gestionnaire d'événements pour l'événement MouseDoubleClick
à chaque TreeViewItem
.
Voici le code qui gère l'événement
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]
}
}
Cela fonctionne bien pour le niveau supérieur TreeViewItem
mais quand un enfant est double-cliqué, l'événement bouillonne l'arbre provoquant l'ensemble de la branche à l'effondrement. Pourquoi l'événement continue à bulles? Comme nous l'avons un [1]
je réglage de l'événement traité.
La solution
La haine de répondre à mes questions, mais voici la solution que je finalement venu à utiliser.
Après avoir lu les quelques sources qui a précisé que le MouseDoubleClick est élevé pour chaque TreeViewItem dans la branche (de l'enfant jusqu'à la racine), peu importe si l'événement est géré j'utilisé la réponse de cette question:
WPF TreeView, get TreeViewItem dans l'événement PreviewMouseDown
pour obtenir le TreeViewItem qui était sous l'événement de la souris. Si l'expéditeur actuel est égal à la TreeViewItem de l'événement I de souris plier / déplier selon les besoins. Sinon, j'ignore tout l'événement et ne rien faire.
Autres conseils
Aucune idée pourquoi, mais la réponse choisie n'a pas fonctionné pour tous les TreeViewItems
pour moi. Donc, j'ai utilisé une approche simple bool
à la clôture de reeintering TreeViewItemDoubleClicked
plus d'une fois.
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;
}
}
Pour permettre au premier gestionnaire invoqué pour exécuter entièrement (se fondant donc sur le fait que le gestionnaire d'un enfant sera appelé avant qu'il ne soit de parents), il suffit d'ajouter:
private void TreeView_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
bubblingBulkwark = false;
}
Et ne pas oublier de l'enregistrer.
treeView.PreviewMouseDown += TreeView_PreviewMouseDown;