So not really. I don’t particularly mind trees. Tree controls on the other hand I hate. Take for example a simple requirement of launching a new window each time a tree item is selected. Simple right? Well not in WPF. Lets look at a quick example.
<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <Grid> <TreeView> <TreeViewItem Header="Root"> <TreeViewItem Header="Parent" > <TreeViewItem Header="Child" Selected="ChildTreeViewItem_Selected"></TreeViewItem> </TreeViewItem> </TreeViewItem> </TreeView> </Grid> </Window>

Pile!
The idea here is simple. I want to click on the TreeViewItem labeled ‘child’ and launch a new Window when the its Selected event is raised.
namespace WpfApplication1 { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void ChildTreeViewItem_Selected(object sender, RoutedEventArgs e) { new Window().Show(); } } }
Ok so maybe that is not all want. Along with a new window launching, I want it to have focus, and I want the TreeViewItem clicked to turn gray indicating the selection made. Sadly however, this is not what I get. Instead the window is launched *not to bad*, however the new window does not have focus after it is activated *who needs focus*. If that is not bad enough adding insult to injury the TreeViewControl in what I can only imagine is a last ditch effort to handle focus raises a second Selection event on the the TreeViewItem labeled Parent. This *bonus* event sets focus back to the TreeViewControl, showing the incorrect TreeViewItem selected. Like so.

HATE YOU
Humm this image is not so clear how is this.

Pile
In the image above you will see that the ‘Parent’ node is selected. That would be fine if that is what I clicked!
Okay okay rant done. How to fix this? Well I spent a day on this sadly, hence the blog posting. Turns out in order to get this to work you need to use the dispatcher. I am not sure why but when I use a simple Action delegate to launch the window using the Dispatcher it all works just fine. Here is the code.
namespace WpfApplication1 { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void ChildTreeViewItem_Selected(object sender, RoutedEventArgs e) { Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => new Window().Show())); } } }
Anyone care to comment on why this works? Well at least it does!
Enjoy!