Programmatically select a specific TreeViewItem into an unbound TreeView

3.9k views Asked by At

In the code behind of my Silverlight application, I have the need to re-populate the TreeView and then make a specific TreeViewItem selected.

The code itself is pretty simple, here it is (i'll trim and pseudo-code-ify it to make it as short as possible)

private void Button_Click()
{
    Guid idToSelect = TellMeWhatToSelect();
    List<myObject> myDataList = myObjectRepository.RetrieveData().ToList();

    myTreeView.Items.Clear();
    foreach(myObject o in myDataList)
    {
        myTreeView.Items.Add(new TreeViewItem() { Content = o.DataField, Tag = o.Id });
    }

    myTreeView.Items.First(o => ((Guid)(o as TreeViewItem).Tag).Equals(idToSelect)).IsSelected = true;

}

That's basically it: i'm reading some data into myDataList, then i cycle through it and create as many TreeViewItems as needed in order to display the data.

Problem is, myTreeView.SelectedItem is null at the end of this, and SelectionChanged event isn't triggered. I would think that, since Items collection has been cleared and re-filled, switching IsSelected on one of the items would act like clicking, but it seems it doesn't).

Oddly enough (for me at least), issuing myTreeView.Items.First().IsSelected = true; by itself (that is, calling a method with that single line of code inside) works as expected: SelectedItem is there and all events are fired appropriateyl.

What's wrong with my code and/or what am I missing ? Looks like cleaning items up kind of breaks something.

I'm fairly sure others have had similar issues, but a bunch of searches I tried didn't help (most of the info & questions I came up with are WPF-related).

Thanks for your time, I'll provide more info if needed. Also, sorry for the wall of text.

UPDATE

Modifying code like this, now the method works as expected.

private void Button_Click()
{
    Guid idToSelect = TellMeWhatToSelect();
    List<myObject> myDataList = myObjectRepository.RetrieveData().ToList();

    myTreeView.Items.Clear();
    foreach(myObject o in myDataList)
    {
        myTreeView.Items.Add(new TreeViewItem() { Content = o.DataField, Tag = o.Id });
    }

    Dispatcher.BeginInvoke(()=>
    {        
        myTreeView.Items.First(o => ((Guid)(o as TreeViewItem).Tag).Equals(idToSelect)).IsSelected = true;
    });
}
2

There are 2 answers

3
RredCat On BEST ANSWER

Set property IsSelected inside of Dispatcher.BeginInvoke.

0
Akauam Westphal On

I had the same problem a while ago, I've solved by calling the UpdateLayout method from the treeview before setting the TreeViewItem as selected.Like this:

 myTreeView.UpdateLayout();   
 myTreeView.Items.First(o => ((Guid)(o as TreeViewItem).Tag).Equals(idToSelect)).IsSelected = true;