In this post we will describe how to create a searchable list with WPF following MVVM principles. To this aim we will use a WPF ListView to display the searched items and a TextBox to enter the text used for the search. Most of the implementation that you will find on the web (e.g. this one) will recommend you to bind your ListView to an ICollectionView. However, this is not 100% satisfactory as long as ICollectionView does not have a built-in generic version. Consequently the ViewModel’s member exposing the binding items will return an ICollectionView which is a powerful object (see this for instance) but is “only” an enumeration of System.Object. In this post we will show you that a generic version can be easily implemented and exposed by your ViewModel.
In this post we will create a very simple app that let you search a player in the list of all the players of the last Football World Cup in Brazil. The complete source code can be found on my Github here.
The key ingredients of such implementation is very simple in MVVM. First take the View which does not need more than the few lines of xaml below.
Let us start by exposing the non-generic version: the DataContext of the control above is bound to an instance of an implementation of the interface IPlayerSearchViewModel below.
A very straightforward implementation that works is the following one.
As I said in the introduction, this is quite enoying. You may want to create screens with many ICollectionView bindings that may contain different types, then it is becoming error prone and we are loosing the benefit of C#’s type safety. The unit test example below is showing you that the elements need to be casted while they are accessed from the ICollectionView.
In addition we cannot use anymore the XAML validation and intellisense provided by Resharper.
Fortunately we can create our generic version of ICollectionView and get back to the comfortable world of type safety. In this example, I will only provide the generic enumeration and the generic version for the SourceCollection member but you can add others. Indeed, you may create a generic version of the Filter predicate to avoid dealing with System.Object in your lambdas but with your generic type T instead.
Actually, the implementation of the ICollectionView is really easy as long as you already have the non-generic instance at hand ICollectionView
Therefore the implementation of the the ViewModel becomes cleaner and statically typed. First the new version of the ViewModel interface.
Then, the implementation.
You do not have to cast or worry anymore on the the type of the objects contained in you ICollectionView. You will also detect binding errors statically with Resharper.