none
How to make a TreeView’s and ListBox’s SelectedItem stay in sync? (in an MVVM app)

    Question

  • Hi,

    I'm certain this has come up before, but I haven't been able to find the answer.

    I made a basic ViewModel that contains a list of People (an array of Person) with a property called SelectedPerson, which naturally points to the currently selected Person in the list of People. I also have a ListBox and a TreeView that are databound to the ViewModel's People list.

    What I'd like to do is to keep the ListBox's SelectedValue and TreeView's SelectedItem in sync with with the ViewModel's SelectedPerson. The idea is that no matter how the SelectedPerson is modified (through a control, through code, etc), all the controls should update themselves properly by selecting the correct item. I can get it to work with two ListBoxes, which is nice, but I can't get it to work with a ListBox and a TreeView because the TreeView's SelectedItem is readonly and apparently unavailable through XAML.

    Where should I look to get ideas on making this work?

    Also note that I'm trying to make this work in pure XAML. No code-behind as XAML files in my application can be loaded and changed dynamically.

    Thanks!

    Monday, June 01, 2009 1:59 PM

Answers

  • Hi Steve,

    TreeViewItem.IsSelected is not readonly and can be used to change the SelectedItem of the TreeView.

    Wrap a PersonViewModel class around the Person class that provides a IsSelected Property (as you have for the SelectedPerson).

    Make SelectedPerson in your ViewModel of type PersonViewModel and if its set to a new value then set the IsSelected of the PersonViewModel to true.

    Make the array of Person to a ObservableCollection<PersonViewModel>.

    Bind the TreeViewItem.IsSelected to the IsSelected of the PersonViewModel.

    This should do the trick.

    <TreeView.ItemContainerStyle>       
        <Style TargetType="{x:Type TreeViewItem}">
           <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
        </Style>
    </TreeView.ItemContainerStyle>
    Hope this helps.
    Monday, June 01, 2009 2:54 PM

All replies

  • Hi Steve,

    TreeViewItem.IsSelected is not readonly and can be used to change the SelectedItem of the TreeView.

    Wrap a PersonViewModel class around the Person class that provides a IsSelected Property (as you have for the SelectedPerson).

    Make SelectedPerson in your ViewModel of type PersonViewModel and if its set to a new value then set the IsSelected of the PersonViewModel to true.

    Make the array of Person to a ObservableCollection<PersonViewModel>.

    Bind the TreeViewItem.IsSelected to the IsSelected of the PersonViewModel.

    This should do the trick.

    <TreeView.ItemContainerStyle>       
        <Style TargetType="{x:Type TreeViewItem}">
           <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
        </Style>
    </TreeView.ItemContainerStyle>
    Hope this helps.
    Monday, June 01, 2009 2:54 PM
  • Hi Guenter!

    Your suggested code was a good jumping off point. After that, I just needed to do two things: One was to update my main ViewModel about the change so that the other controls would get updated. So in the PersonViewModel's IsSelected setter, I go MainViewModel.SelectedPerson = this; The second was to also set the PersonViewModel's IsSelected to true whenever some code or control changes the SelectedPerson so that the TreeView knows about it too. Then I added a bit of protection code to make sure not to cause circular assignments. (when MainViewModel.SelectedPerson is set, it sets the PersonViewModel's IsSelected which in turn sets itself to MainViewMode.SelectedPerson, etc, etc.)

    It's not the most elegant solution I've written, as there's coupling between the MainViewModel and PersonViewModel, but it's the first that works.

    Thanks!
    Monday, June 01, 2009 4:09 PM
  • Hi Guenter,

    Your idea helped me a lot. Thank you.
    Friday, August 14, 2009 6:47 PM
  • Hello Steve,

    I am trying to create a navigation model with two listboxes and treeview where I need to be able to update selected states of listboxitems and treeview items by selecting any of them or other control. Your task is similar in a way of what I am trying to achieve. I am wondering if you can share your sample prototype. It will be a huge help for me. Thank you.

    • Proposed as answer by Wikus.Olivier Friday, September 02, 2011 10:06 AM
    • Unproposed as answer by Wikus.Olivier Friday, September 02, 2011 10:07 AM
    Tuesday, November 02, 2010 3:43 PM
  • Hi All

    I solved this isue with Cinch framwork. http://cinch.codeplex.com/

     

    Regards

    Friday, September 02, 2011 10:09 AM