Implementing IBindingListView... or not

Sometimes, it is very difficult to reuse existing code.

Today I wanted to code a class implementing the IBindingListView. At first, I wanted to inherit the BindingList<T> but then I discovered that some features were hidden, such as the AddIndex. This method is not virtual and does not delegate to an AddIndexCore method either.

So I decided to go deaper and starts coding using a Collection<T>. But then, I realized that the indexer item is not virtual and does not delegate to an overridable method. As the IBindingListView is supposed to be a view, I assume that the wrapped collection should not be affected by sorting and filtering. This also means that, once filtering or sorting are in effect, the view should become readonly, eventhough the wrapped collection does not have to be.

Also, BindingList<T> is kind of the "reference" implementation of IBindingList, because it is typed and in the framework. I might find existing code requiring BindingList<T>, instead of IBindingList, so inheriting from Collection<T> might not be a good idea after all.

The IBindingList, with the ListChanged event, is intended to be an intermediate layer between business entities and user interface components. IBindingListView, with only filtering and advanced sorting, could not have the same purpose. It clearly belongs in the realm of the user interface. The INotifyCollectionChanged is better suited for code reuse, as it only focus on the observable aspect. The UI aspects is taken care of by the ICollectionView. I just do not understand why the former is defined in the WindowsBase assembly, instead of, let say, System.Core. INotifyCollectionChanged as nothing to do with UI.

The more thoughts I gave into it IBindingList (and BindingList<T>), the more it puzzles me. The AddIndex/RemoveIndex/Find and ApplySort/RemoveSort are really abstract/general purpose methods intented to work with the user interface. And so are the IBindingListView methods. The Filter method is very generic as it takes a string, so we have no idea on how we should interpret the filter. So it is strange that the IBindingList does not declare a MoveItem method, which is often needed in user interfaces.

[edit]The definition of the format for the filter can be found in the DataColumn.Expression help entry.[/edit]

The documentation states that the BindingSource implements IBindingListView, which sounds great as it would be the perfect place to do so. It would have the reference implementation of the IBindingListView. But, in fact, it only delegates the calls to the data source if it implements it (SupportsAdvanceSorting & SupportsFiltering returns true only when the List implements IBindingListView and supports them). "Implementation" is a little abusive in this case, don't you think?

So, I guess, IBindingListView should be implemented as a decorator over a IList or IBindingList and, if we want to maximize its use, the BindingSource should be overriden as well, to instanciate this decorator when required.

The task list to do so is:

  1. Create a class that implement IBindingListView. This class does not have to be generic as it will mostly be used by the derived BindingSource.
  2. Implement IList methods by delegation
  3. Implement IBindingList methods by delegation whenever possible
  4. Implement sorting and searching
  5. Create a FilterExpressionParser
  6. Create a BindingViewSource that decorate a class with the IBindingListView
  7. Implement MoveItem on the BindingViewSource

Still, I'd like to point out that this task would be easier if we had a utility to, at least, parse the Filter expression.

Leave a comment

Please note that we won't show your email to others, or use it for sending unwanted emails. We will only use it to render your Gravatar image and to validate you as a real person.