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!