Click here to Skip to main content
Click here to Skip to main content

Multi-filtered WPF DataGrid with MVVM

, 18 Aug 2012
Rate this:
Please Sign up or sign in to vote.
A simple example of using multi-filters with a WPF DataGrid with MVVM.

Introduction  

This article demonstrates how to implement multiple filters for a WPF DataGrid using the MVVM paradigm and can probably be easily modified to provide multi-filtering on other collection controls like a ListBox. There are articles in CodeProject and other sites which describe general purpose filtering or auto-filtering in a DataGrid, but they use code behind rather than MVVM (see references). The goal of this article is to provide a simple example that can be adapted to meet your project needs with a minimum of refactoring. The impetus for this article was a requirement for custom filtering with multiple filters (the filter mechanism needed to include synonyms of selected filter words). The example present in this article does allow for custom filter logic.

This article is marked as intermediate article because it assumes the reader will have some experience with the MVVM design paradigm. Despite this the sample should be simple, readable code that could be easily followed by beginners too.

The sample code provides a single view with a DataGrid that displays a collection of Thing objects. A Thing is a simple data class which contains multiple properties. The DropDownLists at the top of the view each apply a filter when a value is selected. The filters can be applied in any order and when a filter is applied the red x button can be used to remove the filter. The Reset button removes all filters. 

The code sample is implemented with .NET 3.5 and uses the following:

The required libraries are bundled in a solution folder and should not need to be installed separately.   The solution has 3 projects but the two classes of interest are MainView.xaml and MainViewModel.cs, all others are there to support the example. 

Using the code 

The key to implementing multiple filters in WPF is to instantiate a CollectionViewSource instance rather than using the CollectionViewSource.GetDefaultView() static method. The difference between the two can be summed up as follows:

  • CollectionViewSource.GetDefaultView() returns an ICollectionView which allows a single filter using the Filter property. Each time this property is changed it resets the previous filter.
  • Instantiating a CollectionViewSource allows for multiple filters by providing a Filter event. Multiple filter event handlers can subscribe to this event and each filter is applied in the order it is subscribed to the event. To remove a filter involves unsubscribing from the event. 

Here are the key steps in the example each associated file:

  1. Load the data into the MainViewModel from the DataService (the example just loads an xml file) to populate the Things property
  2. Instantiate the CollectionViewSource object in the MainView and bind it to the collection of Thing objects which was loaded in step 1 (~ line 13 of MainView.xaml) (*)
    <Window.Resources>
       ...
       <CollectionViewSource Source="{Binding Things}" x:Key="X_CVS"/>
    </Window.Resources>
  3. Bind the CollectionViewSource instance to the DataGrid in the MainView (~ line 51 of MainView.xaml)
    ...
    <Custom:DataGrid ItemSource="{Binding Source={StaticResource X_CVS}}" 
           Margin="8" Grid.Row="1" AutoGenerateColumns="True" 
           IsReadOnly="True"></Custom:DataGrid>
    ...
  4. A reference to the CollectionViewSource instance is passed to the MainViewModel (~ line 18 of MainView.xaml.cs) where it is assigned to the local property CVS (~ line 265 of MainViewModel.cs)
  5. When a target filter is specified in a drop down list, a filter event handler is subscribed to the filter event of the CollectionViewSource
  6. When a filter is removed, the corresponding event handler is un-subscribed from the Filter event of the CollectionViewSource 

One thing to note about the filter methods as seen in the following method which filters each row based on the SelectedAuthor property of the MainViewModel:

private void FilterByAuthor(object sender, FilterEventArgs e)
{
    var src = e.Item as Thing;
    if (src == null)
        e.Accepted = false;
    else if (string.Compare(SelectedAuthor, src.Author) != 0)
        e.Accepted = false;
}

A row in the grid does not match the filter and is hidden by setting e.Accepted = false. Note that e.Accepted is not set to true if a match is found. Rather, only set e.Accepted to false for items that do not match. This enables filter results to be applied on top of existing filter results. If e.Accepted is set to true, it may negate any previous filter results.

References    

WPF’s CollectionViewSource by Bea Stollnitz is an article for multiple filters on a ListBox using the CollectionViewSource mechanism with code behind and was responsible for leading me down the path to this creating this example.

The following are several CodeProject articles with code-behind WPF DataGrid filtering:

History

18 Aug 2012:  updated the example code to include wpftoolkit.dll in the solution folder.

License

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

About the Author

M. Pastore

United States United States
Neck deep in Social Network Analysis

Comments and Discussions

 
BugDate format problems PinmemberTroels Jakobsen24-Nov-13 21:10 
GeneralRe: Date format problems PinmemberM. Pastore25-Nov-13 11:46 
GeneralMy vote of 5 PinmemberFloppyDisk_5.251-Jul-13 18:06 
Questionthanks Pinmember孙岩8-Jun-13 23:28 
QuestionMVVM with multiple Models PinmemberOctopus112620-May-13 10:34 
AnswerRe: MVVM with multiple Models PinmemberM. Pastore20-May-13 11:21 
GeneralRe: MVVM with multiple Models PinmemberOctopus112621-May-13 4:35 
GeneralRe: MVVM with multiple Models PinmemberM. Pastore22-May-13 5:45 
GeneralMy vote of 5 PinmemberKhaled Kokah23-Apr-13 21:46 
QuestionError PinmemberMember 45586618-Aug-12 1:44 
Error:
teg "DataGrid" don't exist in namespace XML "http://schemas.microsoft.com/wpf/2008/toolkit". 10. (MC3074) - \...\DataGrid_WPF\Multi-filtered WPF DataGrid with MVVM\MultiFilteredDataGrid_Source\MultiFilteredDataGrid_Source\MultiFilteredDataGridMVVM\View\MainView.xaml:51,1
Rand

AnswerRe: Error PinmemberM. Pastore18-Aug-12 4:27 
GeneralThanks!!! PinmemberMember 45586621-Aug-12 9:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 18 Aug 2012
Article Copyright 2012 by M. Pastore
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid