Filter WPF TreeView using MVVM

10,128

you could use ICollectionView to filter your collection. something like this:

ICollectionView view = CollectionViewSource.GetDefaultView(this.YourObservableCollection);
view.Filter = o => {
                      var itemtofilter = o as yourviewmodeltype;

                      //check your conditions here
                      ...

                      return (bool)itemtofilercondition;
                    };

edit: you have to recreate the view if you call new YourObservableCollection();

Share:
10,128
alimbada
Author by

alimbada

C#/WPF developer

Updated on June 04, 2022

Comments

  • alimbada
    alimbada almost 2 years

    I currently have a TreeView which has the following structure:

            <TreeView ItemsSource="{Binding RootViewModels}"
                      FontSize="12">
                <TreeView.ItemContainerStyle>
                    <Style TargetType="{x:Type TreeViewItem}">
                        <Setter Property="local:TreeViewItemBehaviour.IsBroughtIntoViewWhenSelected"
                                Value="True" />
                        <Setter Property="IsExpanded"
                                Value="{Binding IsExpanded, Mode=TwoWay}" />
                        <Setter Property="IsSelected"
                                Value="{Binding IsSelected, Mode=TwoWay}" />
                        <Setter Property="Visibility"
                                Value="{Binding IsVisible, Mode=TwoWay, Converter={StaticResource boolVisibilityConverter}}" />
                    </Style>
                </TreeView.ItemContainerStyle>
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                        <TextBlock Text="{Binding SomeDisplayText}" />
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>
    

    where RootViewModels and Children are of type ObservableCollection<SomeItemViewModel>

    In the same View I have a ComboBox and I want the selected item in this ComboBox to serve as the criteria to filter the TreeView by. I have a ViewModelRepository which is also of type ObservableCollection<SomeItemViewModel> and is provided by my IoC container. I use this to create my other ObservableCollections that are in the XAML above.

    At the moment, I'm trying to set the Visibility of each SomeItemViewModel in my ViewModelRepository when an item in the ComboBox is selected. This seems to work for anything below the first two levels in the tree, but not for the 2nd level itself (the first level being the root which is always visible).

    However, it doesn't work consistently. When I apply the "filter" the correct nodes are set invisible, but if I then expand a node which contains "filtered" nodes then any subsequent "filters" fail.

    I've read about binding ItemsControls to a CollectionViewSource in order to do filtering, but I can't find an example of it's usage with the TreeView. Does anyone have any pointers on how I can use it here?

  • alimbada
    alimbada over 13 years
    Thanks! This put me on the right track. Finally got my head around CollectionViewSource and ICollectionView. :-) I just had to add an iterator for filtering each of the child viewmodels of the root, which recursively filters down the whole hierarchy.