You have a
DataGrid control that displays a bunch of data, and suppose that you want to do some filtering on it. What’s the best way to go about it?
Perhaps the simplest and most obvious way to do this is by creating two lists. One holds all the data, and when you want to filter, you create a subset of that data according to your filtering criteria, and we bind that list to the
DataGrid, so the updated (by which I mean filtered) data will be displayed. But you probably already noticed the big flaw of this approach; data duplication. It’s quite fine for few thousand lines, but suppose you’re handling lists that contain few hundred thousands, or even millions of items. Now that data duplication can potentially be a burden on your system. Besides, there’s a fundamental problem with this approach anyway; merely to show a subset of data, you shouldn’t have to create a subset of data.
Luckily, we don’t have to do that.
.NET provides a neat way to do this using what’s called a
CollectionView. The basic idea is this; we have only one list of data, but we create a
CollectionView and we link the list to it. Then we attach a
Filter to this
CollectionView, which essentially is a method inside which we determine, based on whatever logic we wish, whether an item should be displayed or not. Finally, when we want to filter data, we simply tell the
CollectionView to go filter data based on that method.
So… let’s get started.
For the purpose of this, let’s say we have a contact list, and we want to filter contacts based on age. My
XAML is going to be very simple: a
DataGrid with two columns. At the bottom, two text boxes,
To which lets user enter the minimum and maximum ages for the filter. Finally a button, which, when clicked, does the filtering. I bind my
Contacts list to the
DataGrid, and rest of the bindings should be obvious. For this example I’m using
MVVM Light Toolkit, hence
RelayCommand and such you’ll see later are part of that suite.
And it should look like this:
GetContacts() method simply returns a list of
RelayCommand to link
Click event, and properties for
To text boxes as well as
Filter button. These all go inside your
Now to the business end of things. We need a
CollectionView property, and a method (
OnFilterTriggered()) to execute when we do the filtering. Next, attach a second method to the button click, so we tell the
CollectionView to trigger the filtering.
Above, we initialize the
ContactFilterView with the
Contacts list. Then, attach
OnFilterTriggered() method to it’s
Then, our filter logic. Here, the parameter
item is each item in the list. So if you have 10 items in the list, this will get called 10 times, each time passing an item form the list. We cast it into a
Contact, then we grab the values of text boxes and see if the
Age of the contact passed is within the user entered min and max values. If so, wer return
Finally, we tell the
CollectionView to start filtering when this method is executed by ‘refreshing’ the list. Since when refreshing, each item is passed through the filter, only the items that satisfy the criteria in the above method are displayed. Also note that this method is attached to the
Click event of the button, so when the button is filtered, we start filtering.
When application is launched, it will display all items.
Then, let’s say we want to filter contacts whose ages are between
40 inclusive. Simply enter those values to the
To text boxes, and click
Pretty neat, ha?