Implementation of WPF’s ICollectionView interface

The existing ICollectionView implementations in WPF, for example ListCollectionView, work very good in trivial cases, they even can sort and filter the items from the underlying collection, but they have some significant disadvantage: they do not keep the correct sort order of an item and they do not filter the item out if its property is changed until ICollectionView.Refresh() method is called implicitly.

To overcome this inconvenience I developed my own implementation of ICollectionView interface that listens to all its items property change events via WeakEventManager and fires corresponding collection change events to re-soft or re-filter the item if needed. It was not a very simple task for me, and I even debugged WPF source code a bit and realized that it works a bit strange, for example, ItemsControl cannot work with my ICollectionView implementation directly, instead it creates some CollectionViewProxy that wraps it and uses some proxy enumerator to access an item by index:

debugging WPF source code

In other words it requires not ICollectionView implementation but a class derived from CollectionView, but CollectionView does not provide the ability to change sorting and filtering algorithms significantly, so this all is definitely strange.

Also I realized that ICollectionView.DeferRefresh() probably is a bit complicated thing, because it supposes handing of underlying collection change events in deferred state, and as far as I understand it means that we should queue the events somehow until we leave deferred state.

The other question is what ICollectionView.SourceCollection property for?

Fortunately, WinRT’s ICollectionView version does not support sorting and filtering and it does not have this ICollectionView.SourceCollection property. So probably WinRT gives a chance to write some efficient implementation of ICollectionView, at least some guy on CodeProject already did something like this.

Leave a Reply

Your email address will not be published. Required fields are marked *