WPF wrong binding but CollectionView still filtering

397 views Asked by At

I wrote a simple code to allow filtering on my datagrid, but I made a mistake in my code. But it still work as expected.

Here is what I did:

  1. Gettings the source items (from the database)
  2. Creating the ICollectionView from it
  3. Setting my custom filter
  4. Binding the source to the DataGrid instead of the view

The 4th point is where I made my mistake. I should have bound the view to the DataGrid, not the source, right?

Here is the code:

var mySources = GettingMySource();

var myView = CollectionViewSource.GetDefaultView(mySources);
myView.Filter = MyFilter;

DataGrid.ItemsSource = mySources;

Somewhere else in my code (when the user enter a filter), I just call:

myView.Refresh();

And it works... The elements that don't match with my filter are removed from the CollectionView and from the UI, but my source list is unchanged...

Can someone explain me how this can work ?

2

There are 2 answers

1
wkl On BEST ANSWER

MSDN says:

All collections have a default CollectionView. WPF always binds to a view rather than a collection. If you bind directly to a collection, WPF actually binds to the default view for that collection. This default view is shared by all bindings to the collection, which causes all direct bindings to the collection to share the sort, filter, group, and current item characteristics of the one default view.

So it seems that while you tell the DataGrid to use the source, it still automatically takes the (default) view which is shared over all bindings and has your filter applied to it.

edit:

it also says that

This default view is never affiliated with any CollectionViewSource objects.

So, it would not have filtered if you had applied the filter to the View of a new CollectionViewSource(mySources) instead of the default view.

1
Alex On

I should have bound the view to the DataGrid, not the source, right?

Yes. The CollectionView is a layer between your collection and the DataGrid. It allows you to navigate, sort, filter and group the items in your collection without actually modifying your original collection. So the line DataGrid.ItemsSource = mySources; is wrong, you should bind it to myView instead.

The elements that don't match with my filter are removed from the CollectionView and from the UI, but my source list is unchanged...

If your goal is to get the list of filtered items from your CollectionView, you should use Cast extension method:

var filteredData = myView.Cast<Entity>()