Selecting an item in a TreeView in WPF
I have to admit that I much prefer WPF over Windows Forms (but prefer ASP.Net to either). However, the programming model is still a bit immature (in my opinion), and sometimes things that you wish were simple just aren’t. Case and point: trying to programmatically select an item in a TreeView control; it just ain’t easy!
Anyway, after scrubbing the web and finding a few solutions that really didn’t appeal (e.g. using reflection; surely it’s not that hard!) I came up with this extension method which does the trick quite nicely.
/// <summary>
/// Walks the tree items to find the node corresponding with
/// the given item, then sets it to be selected.
/// </summary>
/// <param name="treeView">The tree view to set the selected
/// item on</param>
/// <param name="item">The item to be selected</param>
/// <returns><c>true</c> if the item was found and set to be
/// selected</returns>
static public bool SetSelectedItem(
this TreeView treeView, object item) {
return SetSelected(treeView, item);
}
static private bool SetSelected(ItemsControl parent,
object child) {
if (parent == null || child == null) {
return false;
}
TreeViewItem childNode = parent.ItemContainerGenerator
.ContainerFromItem(child) as TreeViewItem;
if (childNode != null) {
childNode.Focus();
return childNode.IsSelected = true;
}
if (parent.Items.Count > 0) {
foreach (object childItem in parent.Items) {
ItemsControl childControl = parent
.ItemContainerGenerator
.ContainerFromItem(childItem)
as ItemsControl;
if (SetSelected(childControl, child)) {
return true;
}
}
}
return false;
}
(Forgive formatting; the code window is only so-wide.)
The trick, you see, is to use the ItemContainerGenerator on the ItemsControl – which TreeView and TreeViewNode both inherit from – to try to find the container for the item you are selecting. This will only work for the immediate children of the control that you’re calling it on – so asking your root node for the container for an item which is three nodes deep is fruitless; hence, you have to walk down the tree asking each branch node if it contains the item.
It’s possibly not the fastest executing code in the world – walking a tree rarely is – but you could speed things up if you knew where the parent node was; then you could just call the recursive method directly.
Enjoy!

Note that you can only walk down the visual tree if it has been built (i.e. all nodes are expanded). Once you set IsExpanded to true, you have to let the Generator render the visual elements and then try again once it has completed.
You can do this by re-calling SetSelectedItem on ItemContainerGenerator.StatusChanged where ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated.
I don’t understand how something as fundamental as a set accessor on SelectedItem made it through a design review.
Hi,
Thanks for your code snippet. It really helped me a lot. Thanks a lot :)
Best Regards,
Subalakshmi Vijayarajan.
[...] to Gerrod’s post on selecting an item in a treeview, I found myself scratching my head on how to find a treeviewitem’s parent item. Here I was [...]
Thanks for your code snippet. It really helped me a lot. Thanks a lot
I want to how many child are available in one root node in treeview in wpf application? please give the sample code
I wasted about three hours on this until I finally came across your blog. You’re a life saver. :)
I had been looking for this and finally your blog helped after 5 hours of search. Thanks. This is wonderful work.
[...] [...]
Hi that was a gr8 code …. helped me a lot….
Thanx a lot for this nice code!
I have been trying to implement htis feature with virtualization enabled from past few days but no success, can you give any idea on how to do that?
Your blog helped me alot. Thanx alot.
Thanks. Helped a lot!
Alex.
Thanks for the code! However, when I try and copy and paste the code from the entry, it all ends up on one long line when pasted, rendering it useless. Is there a way to copy and paste it so that it ends up on multiple lines like it appears here?
Sometimes things that you wish were simple just aren’t :D
Hi Matt – not sure why it doesn’t copy and paste properly… try this:
static public bool SetSelectedItem(
this TreeView treeView, object item) {
return SetSelected(treeView, item);
}
static private bool SetSelected(ItemsControl parent,
object child) {
if (parent == null || child == null) {
return false;
}
TreeViewItem childNode = parent.ItemContainerGenerator
.ContainerFromItem(child) as TreeViewItem;
if (childNode != null) {
childNode.Focus();
return childNode.IsSelected = true;
}
if (parent.Items.Count > 0) {
foreach (object childItem in parent.Items) {
ItemsControl childControl = parent
.ItemContainerGenerator
.ContainerFromItem(childItem)
as ItemsControl;
if (SetSelected(childControl, child)) {
return true;
}
}
}
return false;
}
I tried your code but i cannot do it work when some “items” (nodes) are not treeviewitem. Any help will be appreciate
Thanks a lot, works perfect ;)
Thanks for the code. You really saved my ass!!!
Thanks, this was very helpful
I changed the function SetSelectedItem to take TreeViewItem instead of TreeView since I knew the level of the tree I needed to search to take place SetSelectedItem(TreeViewItem treeViewItem, object item)