In short my question is: How do you prefer to expose filtered/sorted/grouped ObservableCollections to Views in WAF?
I was fairly happy with my first attempt which involved filtering on the VM and exposing an ICollectionView of Model objects for the View to bind to:
public StartDetailViewModel(IStartDetailView view, StartPoint start, Scenario scenario)
: base(view)
{
this.scenario = scenario;
this.start = start;
this.startsViewSource = new CollectionViewSource();
this.startsViewSource.Filter += new FilterEventHandler(Starts_Filter);
this.startsViewSource.Source = scenario.Starts;
}
public ICollectionView FilteredStarts
{
get
{
return startsViewSource.View;
}
}
void Starts_Filter(object sender, FilterEventArgs e)
{
if (e.Item != null)
{
e.Accepted = (((StartPoint)e.Item).Date == this.start);
}
}
}
However, exposing the Model objects directly is insufficient since each item now needs its own ViewModel.
So, CollectionViewSource.Source is now attached to a collection of Views. The main problem with this is when applying filters:
void Starts_Filter(object sender, FilterEventArgs e)
{
//Since e.Item is now a view we are forced to ask the View for the ViewModel:
StartItemViewModel vm = ((IStartItemView)e.Item).GetViewModel<StartItemViewModel>();
[...]
}
This feels wrong to me. Are there better approaches?
UPDATE
So I reverted to a CollectionViewSource.Source of Model objects and maintained a seperate collection of child View objects to which the View was bound.
The question then of course is why am I using CollectionViewSource in a ViewModel at all?
I think the following prinicple applies: If the filtering/sorting functionality is a property of the View only (i.e. an alternate view might legitimately not provide such functionality) then CollectionViews should be used in the View (with code-behind as necessary). If the filtering/sorting functionality is a dimension of the Model then this can be dealt with in the ViewModel or Model by other means.
This makes sense once you realise that code-behind in MVVM views is perfectly acceptable.
Any comments?