Click here to Skip to main content
15,868,016 members
Articles / Desktop Programming / WPF

Multi-filtered WPF DataGrid with MVVM

Rate me:
Please Sign up or sign in to vote.
4.88/5 (16 votes)
18 Aug 2012CPOL4 min read 125.2K   9.5K   44   20
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. 

Image 1

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) (*)
    XML
    <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)
    XML
    ...
    <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:

C#
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)


Written By
United States United States
Neck deep in Social Network Analysis

Comments and Discussions

 
QuestionMy vote of 5 Pin
Paula Scholz31-Jul-18 7:05
Paula Scholz31-Jul-18 7:05 
NewsBroken link to the article Pin
Rafael C A Ribeiro6-Jul-18 1:48
Rafael C A Ribeiro6-Jul-18 1:48 
GeneralRe: Broken link to the article Pin
LyndonGingerich23-Aug-23 8:21
LyndonGingerich23-Aug-23 8:21 
GeneralMy vote of 5 Pin
xleb230-Dec-15 7:52
xleb230-Dec-15 7:52 
GeneralMy vote of 3 Pin
tomtom198015-Jun-15 0:40
tomtom198015-Jun-15 0:40 
BugDate format problems Pin
Troels Jakobsen24-Nov-13 21:10
Troels Jakobsen24-Nov-13 21:10 
GeneralRe: Date format problems Pin
M. Pastore25-Nov-13 11:46
M. Pastore25-Nov-13 11:46 
BugRe: Date format problems Pin
JayMicheal26-Jul-17 7:14
JayMicheal26-Jul-17 7:14 
GeneralMy vote of 5 Pin
FloppyDisk_5.251-Jul-13 18:06
FloppyDisk_5.251-Jul-13 18:06 
Questionthanks Pin
孙岩8-Jun-13 23:28
孙岩8-Jun-13 23:28 
thanks for ur articles.I'm a beginner in WPF and my English is not good.but i can read the codes,it's very helpful for my study.
QuestionMVVM with multiple Models Pin
Octopus112620-May-13 10:34
Octopus112620-May-13 10:34 
AnswerRe: MVVM with multiple Models Pin
M. Pastore20-May-13 11:21
M. Pastore20-May-13 11:21 
GeneralRe: MVVM with multiple Models Pin
Octopus112621-May-13 4:35
Octopus112621-May-13 4:35 
GeneralRe: MVVM with multiple Models Pin
M. Pastore22-May-13 5:45
M. Pastore22-May-13 5:45 
GeneralMy vote of 5 Pin
Khaled Kokah23-Apr-13 21:46
Khaled Kokah23-Apr-13 21:46 
QuestionError Pin
RAND 45586618-Aug-12 1:44
RAND 45586618-Aug-12 1:44 
AnswerRe: Error Pin
M. Pastore18-Aug-12 4:27
M. Pastore18-Aug-12 4:27 
GeneralThanks!!! Pin
RAND 45586621-Aug-12 9:14
RAND 45586621-Aug-12 9:14 
GeneralRe: Thanks!!! Pin
Member 1344230629-Oct-17 11:36
Member 1344230629-Oct-17 11:36 
AnswerRe: Error Pin
Member 1344230629-Oct-17 11:37
Member 1344230629-Oct-17 11:37 

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

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