Search code examples
.netdatagridviewfilteringbindingsource

Filtering a DataGridView with a BindingList


I've created a WinForms application with a DataGridView and I'd like to filter it. It's setup as follows:

A catalogue entry:

public class CatalogueEntry
{
    private string _code;
    private string _desc;

    public CatalogueEntry(string code, string desc)
    {
        _code = code;
        _desc = desc;
    }

    public string Code => _code;
    public string Description => _desc;
}

The catalogue list (using BindingList):

public class Catalogue : BindingList<CatalogueEntry>
{

}

Initialisation:

_catalogue = new Catalogue();

_catalogue.Add(new CatalogueEntry("BAGG", "It scares us all"));
_catalogue.Add(new CatalogueEntry("BIGG", "It embiggens us all"));
_catalogue.Add(new CatalogueEntry("BOGG", "It demeans us all"));
_catalogue.Add(new CatalogueEntry("BUGG", "It frightens us all"));

_source = new BindingSource();
_source.DataSource = _catalogue;

dataGridView.DataSource = _source;

I get a nice grid of the above data.

If I try to set the filter on the BindingSource as follows:

var filter = "Description like 'scares'";
_source.Filter = filter;

Nothing happens, i.e. the filter doesn't appear to work. What can I do to get the filter working?

I'm guessing the underlying data source isn't a database so won't understand "Description like 'scares'".

EDIT: If I change my filter as follows:

var text = "scares";
var list = _catalogue.Where(entry => entry.Description.Contains(text));
_source.DataSource = list;

then it filters as required; however this is changing the list. Is this the right way to do it?


Solution

  • If you check _source.SupportsFiltering, you'll find it's False. According to MSDN Documentation on BindingSource.Filter:

    Only underlying lists that implement the IBindingListView interface support filtering.

    Which BindingList does not:

    public class BindingList<T> : Collection<T>, IBindingList, IList, ICollection, IEnumerable, ICancelAddNew, IRaiseItemChangedEvents
    

    While what you have will suffice for simple purposes, if you need real filtering without changing the DataSource, you can:

    1. Find a generic implementation of IBindingListView library created by other users.
    2. Roll your own implementation (lot of work but more customizable).
    3. Restructure - think DataTable instead.