Drizzt Do Urden Drizzt Do Urden - 24 days ago 15
C# Question

WPF IsSelected prevent trigger when selecting child

I have a problem I've ran into and I'm not sure if it is possible to prevent it. I supose it is designed like this by default.

I have coded a treeview list to be filled by a XML and each of these node, when selected, are filling some textbox. Depending on their type, it will trigger a different function.

The problem is that when I select a child, it seems to trigger "IsSelecting" for all parents treeviewitem all the way to the top which in return trigger the associated function as well and I don't want that.

Any idea how to prevent this "Sort of reverse inheritance" for IsSelected?

Example (check with code below): selecting a "node" will trigger "Node_Selected", "Dialog_Selected", "Actor_Selected".

Thanks for your help.

Best regards,

Just for context:

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){}

Answer

In the event handler you can set e.Handled = true. That will prevent the event from bubbling up the tree.

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

See https://msdn.microsoft.com/en-us/library/ms742806%28v=vs.110%29.aspx for more information on RoutedEvents. These include bubbling events which go up the tree and tunneling events which go down the tree.

Comments