Today I tried to find a bug in a ICollectionView-based WPF filtering action. The problem was fortunately easy to find, but I was shocked that I didn't find an easy example in our projects to explain my colleague the way how this all works... So, here is my easy example of a grid which can be filtered:
I created a standard WPF project and installed the nuget-package mvvm-light (see: http://www.codeproject.com/
Articles/321806/MVVMLight- Hello-World-in-10-Minutes if you don't know the nuget package). Long story short: it provides some base classes and some assets like a relay-command which is useful to start your work without the need of creating boiler-plate code again and again. The mvvmlight's viewmodel-locator is defined as a static resource in app.xaml so you can define view-models (and its instances) centrally using an "inversion of control"-container (called SimpleIoc). Here nothing has to be changed, because it creates a MainViewModel (as an example) we will use to create this sample.
I kept the MainWindow.xaml which was created by default and put the needed controls in there:
As we can see in line 9: the datacontext is wired up with the viewmodel instance created in the ViewModelLocator, so we can use the paradigm of MVVM. In the following XAML code we bind the text to filter, the data and two buttons to the background viewmodel...
What we see here is that 99% of the magic happens in the constructor of the viewmodel. This is bad style, but keeps the things easy for the example, so please forgive me here. We see here that all members (defined at the end of the class) are bound by the xaml-code except the CollectionView which is used for the actual filtering.
Important here is:
- if you change the reference of your data source then populate that to the UI (INPC -> RaisePropertyChanged)
- Filtering over ICollectionView is easily achievable over a Predicate-function
- recreate the ICollectionView if the original instance of the data changes (you probably don't need a reference to this)
- if the filter-result might change call CollectionViewInstance.