I have a TreeView bound to a hierarchy consisting of several different classes via HierarchicalDataTemplates. When an item in the tree is selected, the SelectedItemChanged event of course happily bubbles upwards through the parent items, as it should. What it should not do, but still does, is happily keeping on bubbling after I set e.Handled to true.
The event will still fire on the parent item, and the RoutedPropertyChangedEventArgs will look exactly like it was the parent item that was selected; even the OriginalSource property will point to the parent item, not the one that was originally selected. e.Handled will of course be false.
Pretty much the same question was asked here, but I’m not using EventAggregator or CAL, and the workaround found here doesn’t help much because I am not specifically after a mouse event.
Is there any way to precisely get the item that was actually selected or to forcefully stop the bubbling madness (without resorting to a very violent and unethical hack using global variables that I can think of)?
Thanks for any insights.
After reading Rick’s answer, I talked to a co-worker who it turned out had had the same problem before. I tried various things in my application (finding: the TreeViewItem.Selected event behaves exactly the same wrong way) and a test project and found that in the test app the events were firing exactly as one would expect it. So there had to be a significant difference in the surroundings (the XAML and ViewModel classes were nearly identical) that led to this difference in behavior – and the culprit looks to be COM, precisely hosting the WPF controls in a COM application.
My colleague’s application is a Word extension using VSTO, while mine is a VSPackage for Visual Studio 2010 – and both Word and VS2010 are still native code for the most part. My test application, on the other hand, is of course a small plain WPF project. I added a WinForms form with an ElementHost to it that in turn hosted a UserControl with a TreeView, but that still worked as it should, so to me it really looks like the host COM application is in some way interfering with the events raised on the TreeView and TreeViewItems.
Luckily, my colleague found/googled a solution that will do for the time being – after you’re done with the actual reaction to the event, at the end of the event handler method, again set the TreeViewItem as selected and focus it:
We don’t understand why, but this will stop the items from being wrongfully re-selected (this is obviously not really a bubbling event in the WPF sense).
Thanks again to Rick for his nudge towards keeping TreeView and TreeViewItem events separate in my mind.