views:

401

answers:

0

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?