Click here to Skip to main content
Click here to Skip to main content
Go to top

Multi-filtered WPF DataGrid with MVVM

, 17 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.
This is an old version of the currently published article.

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:

These 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 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 <Window.Resources> ... <CollectionViewSource Source="{Binding Things}" x:Key="X_CVS"/> </Window.Resources>
  • 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>
    ...
  • 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)
  • When a target filter is specified in a drop down list, a filter event handler is subscribed to the filter event of the CollectionViewSource
  • 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

    Initial drop.

    License

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

    Share

    About the Author

    M. Pastore

    United States United States
    Neck deep in Social Network Analysis

    Comments and Discussions


    Discussions posted for the Published version of this article. Posting a message here will take you to the publicly available article in order to continue your conversation in public.
     
    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 
    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.140922.1 | Last Updated 17 Aug 2012
    Article Copyright 2012 by M. Pastore
    Everything else Copyright © CodeProject, 1999-2014
    Terms of Service
    Layout: fixed | fluid