Filtering and Grouping ListView and GridView on Windows 8
One of the questions I recently answered on Stack Overflow was how to filter and group data in ListView and GridView.
Filtering and grouping has traditionally be done with CollectionViewSource. Unfortunately,CollectionViewSource no longer has the Filter event or the GroupDescriptions property. It may seem like filtering and grouping are unsupported, but both can still be achieved using LINQ.
In your Xaml, add a CollectionViewSource in the Resources section of your page. Make sure IsSourceGrouped is set to true:
Now, the CollectionViewSource (GroupsCV) should be set as the ItemsSource for your GridView:
Notice that CollectionViewSource is bound to a property called Groups. This property is part of my ViewModel. The value returned by the Groups property will be the result of a LINQ query. This confused me at first because I didn’t know what type the property should return. I settled on an enumerable grouping of comparable items. This pretty much works with any LINQ query of any type.
So, in your ViewModel (or whatever your DataContext is) add the following property:
Now, whenever you want to change the grouping or the filter, just set the Groups property equal to a LINQ query like so:
LINQ does great with property expressions in queries at compile time, but what about letting the user pick from a list of property names and dynamically grouping by a property at runtime? Well, the only requirement for LINQ to be able to create a group is that whatever you pass it must implement IComparable.
Here’s a little extension method that takes the name of a property as a string and returns an IComparable:
With that in place, you can do a dynamic query by property name like this:
The examples above show how to create groups, but you can easily filter as well. On the 2nd line of the query (the line after the from) add a where clause. You can filter on any property and should even be able to use the GetComparableValue trick to dynamically filter on a property by quoted string name.