Search code examples
c#wpfcollectionviewsource

Adding a SortDescription to a CollectionViewSource clears the view's filter


My code-behind builds a CollectionViewSource to sort and filter a collection of objects representing disk folders. It exposes its View to my XAML. I initially wrote the code to build the object like this

var cvsFolder       = new CollectionViewSource()
{
    Source = _scansSource.Items,
    View = { Filter = IsScan }     // Only show folders that are "scans"
};        

// Sort by desired property -- this clears out the filter
cvsFolder.SortDescriptions.Add(new SortDescription(propertyName, dir));

But my filter was not working. In my UI I was seeing all folders.

A bit of debugging showed that the issue was that my call to SortDescriptions.Add on the last line immediately clears out the filter that I just added a few lines above it. (Either that or it completely replaces the view. I am not sure which)

So I changed the order. Like this

var cvsFolder = new CollectionViewSource() { Source = _scansSource.Items, };        
cvsFolder.SortDescriptions.Add(new SortDescription(propertyName, dir));
cvsFolder.View.Filter = IsScan;   // Set the filter after adding sort descriptions

This works; My data is now sorted and filtered. but the behavior was unexpected, and slightly concerning.

Does this mean that if want to change my sorting dynamically -- add or remove descriptions or change the directions -- as time goes on, I must reset the filter every time? Are there other properties in the CollectionViewSource that might have similar affects or be similarly affected?

Or am I simply doing this the wrong way?


Solution

  • Use the SortDescriptions property of the View that you set the Filter property of. Then the order doesn't matter:

    var cvsFolder = new CollectionViewSource() { Source = ... };
    cvsFolder.View.Filter = ...;
    cvsFolder.View.SortDescriptions.Add(new SortDescription(propertyName, dir));
    

    Or use the Filter event for the CollectionViewSource itself to filter the items:

    private void CvsFolder_Filter(object sender, FilterEventArgs e)
    {
        e.Accepted = ...
    }
    

    But do not add sort descriptions to the view and filter the CollectionViewSource or vice versa.