Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TreeView Sync to SelectedItem in View Model

I have a ViewModel on top of a WPF TreeView control. I want the ViewModel to be able to set and read the SelectedItem from the TreeView. However, the SelectedItem property of the TreeView is not bindable.

I am able to set and get the selected item in the code behind (using the ItemContainerGenerator and TreeViewItem.IsSelected = true) but this leads to some ugly communication between the code behind and the ViewModel.

Does anyone have a clean solution for this?

like image 745
according2me Avatar asked Nov 12 '09 16:11

according2me


1 Answers

I can provide an example. What I do is setting the IsSelected property of a TreeViewItem (not the TreeView itself) in the view model, because you can bind to this.

In my view model I have a property ElementInViewModel which is a data structure that forms a tree itself. I use a HierarchicalDataTemplate in my Xaml to display it. The data object itself is of type YourDomainType and its child elements (of the same type) are in its ChildElements property.

In the view model, I set the IsExpanded and IsSelected property of my data class YourDomainType. Because of the style defined below, they will pass this setting to the TreeViewItem.

Does this work for you?

<UserControl>

    <UserControl.Resources>        
        <CollectionViewSource Source="{Binding Path=ElementInViewModel}" x:Key="Cvs">
        </CollectionViewSource>

        <HierarchicalDataTemplate DataType="{x:Type DomainModel:YourDomainType}"
                                  ItemsSource="{Binding Path=ChildElements}">
            <TextBlock Text="{Binding Path=Name}"/>            
        </HierarchicalDataTemplate>        

        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
            </Setter>
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
            </Setter>            
        </Style>

    </UserControl.Resources>


    <DockPanel>
        <TreeView ItemsSource="{Binding Source={StaticResource Cvs}}"/>
    </DockPanel>

</UserControl>
like image 157
Martin Avatar answered Nov 11 '22 03:11

Martin