2016-11-10 2 views
0

J'ai rencontré un problème et je ne suis pas sûr qu'il soit possible de l'empêcher. Je suppose qu'il est conçu comme ça par défaut.WPF IsSelected empêche le déclenchement lors de la sélection de l'enfant

J'ai codé une liste treeview à remplir par un XML et chacun de ces nœuds, lorsqu'il est sélectionné, remplit une zone de texte. Selon leur type, il déclenchera une fonction différente. Le problème est que quand je sélectionne un enfant, il semble déclencher "IsSelecting" pour tous les parents treeviewitem tout le chemin vers le haut qui en retour déclenche la fonction associée aussi et je ne le veux pas.

Une idée comment empêcher ce "Tri de l'héritage inverse" pour IsSelected?

Exemple (vérifier avec le code ci-dessous): la sélection d'un "nœud" déclenchera "Node_Selected", "Dialog_Selected", "Actor_Selected".

Merci pour votre aide.

Meilleures salutations,

Juste pour le contexte:

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     XmlDocument document = new XmlDocument(); 
     document.Load("XML/ActorsDialogs.xml"); 

     XmlNodeList actors = document.SelectNodes("/dialogs/actor"); 

     foreach (XmlNode actor in actors) 
     { 
      TreeViewItem newActor = new TreeViewItem(); 
      newActor.Header = actor.SelectSingleNode("actorname").InnerText; 
      newActor.Selected += new RoutedEventHandler(Actor_Selected); 

      XmlNodeList dialogs = actor.SelectNodes("dialog"); 
      foreach (XmlNode dialog in dialogs) 
      { 
       TreeViewItem newdialog = new TreeViewItem(); 
       newdialog.Header = "Dialog:" + dialog.SelectSingleNode("dialogID").InnerText; 
       newdialog.Selected += new RoutedEventHandler(Dialog_Selected); 

       BuildNodes(newdialog, dialog); 

       newActor.Items.Add(newdialog); 
      } 
      ActorsList.Items.Add(newActor); 
     } 
    } 

    private void BuildNodes(TreeViewItem treeNode, XmlNode parentElement) 
    { 
     foreach (XmlNode child in parentElement.ChildNodes) 
     { 
      if (child.Name == "node" || child.Name == "reply") 
      { 
       XmlElement childElement = child as XmlElement; 
       TreeViewItem childTreeNode = new TreeViewItem(); 
       string ID = child.SelectSingleNode(child.Name + "ID").InnerText; 
       childTreeNode.Header = childElement.Name + ":" + ID; 
       switch (child.Name) 
       { 
        case "node": 
         childTreeNode.Selected += new RoutedEventHandler(Node_Selected); 
         break; 
        case "reply": 
         childTreeNode.Selected += new RoutedEventHandler(Reply_Selected); 
         break; 
        default: 
         break; 
       } 


       treeNode.Items.Add(childTreeNode); 
       BuildNodes(childTreeNode, childElement); 
      } 
     } 
    } 

    private void Actor_Selected(object sender, RoutedEventArgs e){} 
    private void Dialog_Selected(object sender, RoutedEventArgs e){} 
    private void Node_Selected(object sender, RoutedEventArgs e){} 
    private void Reply_Selected(object sender, RoutedEventArgs e){} 
+1

Voulez-vous que le nœud sélectionné apparaisse, mais que Dialog et Actor ne soient pas sélectionnés? Est-ce exact? – phil

+0

Dans mon exemple, oui. Si cela arrivait pour Dialog, alors seulement Dialog_Selected arriverait. –

Répondre

2

Dans le gestionnaire d'événements, vous pouvez définir e.Handled = true. Cela empêchera l'événement de bouillir dans l'arbre.

private void Node_Selected(object sender, RoutedEventArgs e) 
{ 
    e.Handled = true; //this will prevent the event from bubbling up to parents; 
    //Do the rest of the code here. 
} 

Voir https://msdn.microsoft.com/en-us/library/ms742806%28v=vs.110%29.aspx pour plus d'informations sur RoutedEvents. Ceux-ci incluent des événements bouillonnants qui montent l'arbre et des événements de tunnel qui descendent l'arbre.

+0

C'est exactement la bonne réponse. Travaillez parfaitement et j'ai appris quelque chose. Va vérifier la référence. Je vous remercie. –