Click here to Skip to main content
15,891,763 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
XML
I am working on treeview in mvvm wpf application. In this I need to do some functionality on selecting a item in the treeview(like add a new tab control corresponding to the selected item). For this I am trying to achive this using ICollectionview as below. I am able to bind the data to the treeview but noevent is getting fired on selecteing an item.
ViewModel:

 public ObservableCollection<TreeviewLeaf> TreeviewData
        {
            get { return _treeviewData; }
            set
            {
                _treeviewData = value;

            }

        }


        private ICollectionView _customerView;

        public ICollectionView Customers
        {
            get { return _customerView; }
        }

        public CustomViewViewModel()
        {

            TreeviewData = GetStorageServicesList();
            _customerView = CollectionViewSource.GetDefaultView(TreeviewData);

            object obj = Customers.CurrentItem;
            _customerView.CurrentChanged+=_customerView_CurrentChanged;
        }

View(xaml):

<TreeView x:Name="treeview1" ItemsSource="{Binding Customers}" >
            <TreeView.ItemTemplate >
                <HierarchicalDataTemplate ItemsSource="{Binding Childs}"   >
                    <TextBlock Text="{Binding Name}" />

                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

But to set IsSynchronizedWithCurrentItem="True" I am not able to find it for Treeview.

Please reply me if anyone know how to solve this.

Thanks in advance.
Posted

1 solution

TreeView does not support this kind of tracking the selected item (how should it be done whatsoever...you would have to deal with many instances of ICollectionView, as one DataItem has a collection of children, which themeself could have a collection of children, etc.).

Instead you could bind the TreeView's SelectedItem [^]or SelectedValue [^]property to a property of your ViewModel.

This way you would track the selected item regardless of the containing collection (that is: the depth in the tree). This solution is ok, if your DataItems are all of the same type and gets uglier, when you have to deal with various Types. Also, multi selection can not be accomplished using this approach.

Alternatively, introduce an IsSelected-property to your DataItem and bind the IsSelected-property of the TreeView's ItemContainer to it:
HTML
<TreeView>
     <TreeView.ItemContainerStyle>
         <Style
             TargetType="TreeViewItem">
             <Setter
                 Property="IsSelected"
                 Value="{Binding IsSelected, Mode=TwoWay}"></Setter>
         </Style>
     </TreeView.ItemContainerStyle>
 </TreeView>




with this apporach, you would have support for multiselect and changes to your data items would reflect in the UI (if the IsSelected-property makes use of INotifyPropertyChanged or is implemented as a DependencyProperty)

only getting a list of selected items is ugly, as you would have to travers the complete tree of data items and gather all that have IsSelected == true.

hope it helped
 
Share this answer
 
v3
Comments
Espen Harlinn 19-Dec-12 7:37am    
It should definitely help, well answered :-D
Nekka 20-Dec-12 1:51am    
Hi Espen, Thank you for your quick response.

I have tried this approch of binding the IsSelected to a viewmodel property. But it is getting hitted for the first time when I run the application and from the next time when I select a differen item it is not getting hitted. I have also implemented onPropertychange for it. Could you please sare me any sample code snippet.

Also as per my requirement single selection is fine and all the objects will be of same type.

<TreeView x:Name="treeview1" ItemsSource="{Binding Customers}" >

<TreeView.ItemContainerStyle>


<Style TargetType="{x:Type TreeViewItem}">
<setter property="IsSelected" value="{Binding Path=IsSelected, Mode=TwoWay}">


</Style>
</TreeView.ItemContainerStyle>

<TreeView.ItemTemplate >
<hierarchicaldatatemplate itemssource="{Binding Childs}">
<textblock text="{Binding Name}">


</TreeView.ItemTemplate>
</TreeView>
earloc 20-Dec-12 4:46am    
I'll see if i can manage to improve the solution, providing a more detailed sample on how to accomplish this. Nevertheless i recommend to bind the TreeView's SelectedItem-Property to a appropriate ViewModel-Property, as this would drastically reduce the coding needed compared to the other approach.

btw: your xaml-snippet is missing a binding to the IsSelected property of your dataitem...you provide a style for the TreeView's ItemContainerStyle but don't have any setters in it!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900