Question

I define a CollectionViewSource like this, but it seems the filter is not working.

CollectionViewSource cvs = new CollectionViewSource();

//oc IS AN OBSERVABLE COLLECTION WITH SOME ITEMS OF TYPE MyClass
cvs.Source = oc;           

//IsSelected IS A bool? PROPERTY OF THE MyClass
cvs.View.Filter = new Predicate<object>(input=>(input as MyClass).IsSelected == true);

//Major IS AN string PROPERTY OF THE MyClass
cvs.SortDescriptions.Add(new SortDescription(
                           "Major", ListSortDirection.Ascending));

However I changed the code this way and everything was solved!

CollectionViewSource cvs = new CollectionViewSource();
cvs.Source = oc;           

cvs.SortDescriptions.Add(new SortDescription(
                           "Major", ListSortDirection.Ascending));

cvs.View.Filter = new Predicate<object>(input=>(input as MyClass).IsSelected == true);

Anyone knows way?

Was it helpful?

Solution

The first thing you should be asking yourself is...

Why am I adding the sorting description to the CollectionViewSource and the filter to the View? Shouldn't I be adding them both to the same object?

The answer is YES!

To add filter logic to the CollectionViewSource directly, you add an event handler for the Filter event.

Straight from MSDN, here is an example

listingDataView.Filter += new FilterEventHandler(ShowOnlyBargainsFilter);
private void ShowOnlyBargainsFilter(object sender, FilterEventArgs e)
{
    AuctionItem product = e.Item as AuctionItem;
    if (product != null)
    {
        // Filter out products with price 25 or above 
        if (product.CurrentPrice < 25)
        {
            e.Accepted = true;
        }
        else
        {
            e.Accepted = false;
        }
    }
}

Now, as for why the filter is getting removed when you add a sort description.

When you add a SortDescription to a CollectionViewSource, behind the scenes it eventually hits this block of code.

Predicate<object> filter;
if (FilterHandlersField.GetValue(this) != null)
{
    filter = FilterWrapper;
}
else
{
    filter = null;
}

if (view.CanFilter)
{
    view.Filter = filter;
}

Clearly, it is overwriting the Filter you set on the View.

In case you are still curious, here is the source code for CollectionViewSource.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top