views:

606

answers:

5

Hi,

I'm implementing a wpf application which display a list of items, and provides the functionality to filter this list by typing in a textbox (quite trivial use case i think).

We're using a MVVM structure.

My question is, whose responsibility is it to filter the list? The view or the viewmodel? Should I implement an "OnTextChanged" event in the xaml.cs, or should I use a property in the ViewModel and use the PropertyChanged to filter the list.
Follow-up question is, should I use a BindingList/ObservableCollection in the ViewModel, or use a ICollectionView to bind the ItemsControl to?

I tried both methods, and they both work. Giving the ViewModel the responsibility keeps the code behind from the View empty, but on the other hand I'm not completely convinced that it is the ViewModels responsibility to apply filtering (eg: different views might require different filtering)

Any thoughts?

thanks, Roel

EDIT:

what bothers me about putting it in the ViewModel is that (in my current implementation) there is a reference the System.Windows.Data. This is a reference I'd rather not have in the ViewModel because it is clearly something View related. Or am I missing something? relevant code:

ICollectionView customerView = CollectionViewSource.GetDefaultView(customers);
+3  A: 

I think this kind of filtering functionality belongs in the viewmodel. Remember, you want to keep as much testable code as possible in the viewmodel (which you will unit-test, right?). Conversely, you'll want to keep the view lean and mean.

The filtering functionality is generic, and not bound to the view as such. But if a different view should need different filtering, you should see that as additional functionality supported by the viewmodel.

Tor Haugen
+1  A: 

There is no right technical answer. The aim of the pattern is to split the concerns of functionality and aesthetics, on the basis that an artistic designer person doesn't understand how to implement functionality, and UIs are hard to test.

But if you can parameterise the filtering to something very simple, e.g. a text property called "Region" that can be set to "Europe", "North America", "Aisa", etc. that's pretty easy to understand, and is independently testable. It lets you put a tiny bit of control over functionality (in a very limited sense) into the view. If that has some value to your efforts, then do it. If it doesn't, don't.

And ultimately, if trying to apply this pattern is causing you to pause and wonder about philosophical distinctions, at the expensive of productivity, then it's not helping you.

Daniel Earwicker
+3  A: 

You can check out this article on my blog where I use the MVVM methodology to filter a collection of items. I think this is definitively the responsibility of the VM class.

Jalfp
very good article, thank you!
Roel
+4  A: 

ViewModel, without any doubt. Avoiding code-behind is the ultimate goal of the pattern - in fact, ViewModel itself is the code behind view.

eg: different views might require different filtering

Different views should have different ViewModels. ViewModel is basically a (somewhat more) object-oriented approach to code-behind files.

Regarding CollectionView: you can define CollectionViewSource in the view XAML, and then bind its sorting and filtering properties to ViewModel. That should keep control in ViewModel and CollectionView in view, but I believe it's over-engineering.

ima
A: 

I agree with you that it is troubling that there is View technology leakage in the VieModel. In a similar vein, I use a RelayCommand object in my ViewModels that is using System.Windows.Input.

For all of the reasons posted here though, I think the ViewModel is the correct design choice for this medium (wpf / silverlight), even though it is less than perfect.

Berryl