How to filter a collection when binding to ItemsSource?

I created a tree structure that models directories and files on my hard drive. Each treeviewItem has a flag associated with the isSelected property. What I would like to get is to display for each parent node the number of selected files in the total number of files (10/12 10 files for twelve of all selected).

Is there a way to make a binding with where the property is ...?

<ContentPresenter Content="{Binding MyItems.Count where MyItems.IsSelected, Mode=OneTime}" Margin="2,0" /> 
+7
source share
2 answers

It is not possible to directly filter a collection in a binding. However, WPF allows you to filter (and sort and group) collections using CollectionViewSource .

One approach would be to define a CollectionViewSource in the resources of your ItemTemplate , which filters the ItemsSource and gets the number of elements that pass the filter by binding to the Count property of this CollectionViewSource . However, you must define your filter in codebehind. It will look something like this:

 <TreeView x:Name="Tree" ItemsSource="{Binding Items}"> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding ChildItems}"> <HierarchicalDataTemplate.Resources> <CollectionViewSource x:Key="FilteredItems" Source="{Binding ChildItems}" Filter="FilteredItems_OnFilter" /> </HierarchicalDataTemplate.Resources> <TextBlock> <TextBlock.Text> <MultiBinding StringFormat="{} {0} of {1} selected"> <Binding Path="Count" Source="{StaticResource FilteredItems}" /> <Binding Path="ItemsSource.Count" ElementName="Tree" /> </MultiBinding> </TextBlock.Text> </TextBlock> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView> 

And in codebehind:

 private void FilteredItems_OnFilter(object sender, FilterEventArgs e) { var item = sender as Item; e.Accepted = item.IsSelected; } 

I have not tested it, but it should work as a whole. You never know with WPF though ...

+11
source

I personally use the following structure http://logofx.codeplex.com/ which seems to meet all your requirements (use LogoFX.Mini, as it seems to you enough for your purposes). Use WrappingCollection.WithSelection as your ItemsSource. Use SelectionCount as the value you want to display. If you decide not to use the framework, then you should subscribe to the selection of the changed event using special behavior, create your own dependency property and update it every time the choice changes.

One last thing: Definitely avoid using code . This violates the whole principle of MVVM.

-nine
source

All Articles