41

I'm developing a WPF application using the MVVM pattern and I need to display a list of items in a ListView (with filtering), with the fields of the selected item displayed in a Master/Detail view. I'm torn between the following two ways of doing this:

  1. Exposing a CollectionView in my ViewModel, and binding to this.
  2. Exposing a plain IList in my ViewModel, and using CollectionViewSource to create the CollectionView in XAML.

Is there an accepted way of doing this? Any thoughts on the best way?

Grokys
  • 16,228
  • 14
  • 69
  • 101

2 Answers2

33

I do the former (expose CollectionView from the VM) but what really matters is where your filtering logic is. That should definitely be in the VM so that it can be tested, even if the view has to wire up the CollectionViewSource to the VM. That said, I don't think there's anything particularly nasty or anti-MVVM about exposing a CollectionView from your VM.

Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393
  • Do you just create a new CollectionView in the ViewModel? MSDN for CollectionView says you should not be creating a new CollectionView but instead create a CollectionViewSource and get the default view. What's the best way to create a CollectionView? – Cameron MacFarland Jun 22 '09 at 05:04
  • MSDN isn't exactly clear about the best way to do it in code. I just create the CollectionView subclass directly (eg. ListCollectionView), but I suppose you could use CollectionViewSource too. My understanding is that CVS just does the selection of the appropriate CV subclass for you and provides XAML support. I haven't had any issues creating the CV myself, and it seems to make sense when you're doing it in code and already know the type of the collection you're wrapping. – Kent Boogaart Jun 22 '09 at 08:41
  • Don't forget that WPF automatically creates views for you when you bind...You get a ListCollectionView when you bind to IList for example. This already has TONS of sorting/filtering/grouping functionality but relies on you getting the Items collection of the object you're binding to. Instead, you can use var view = CollectionViewSource.GetDefaultView(yourCollection) as ListCollectionView;. You can do all kinds of cool stuff then. – EightyOne Unite Sep 10 '10 at 09:00
  • 2
    +1. The Developer's Guide to Microsoft PRISM recommends this same approach on pg 79 if anyone is interested. – RichardOD Jul 09 '11 at 15:57
  • Agree with Kent, def in the VM so it can be tested. Mark – Mark Cooper Jun 11 '09 at 18:54
  • 1
    I don't like that WindowsBase and PresentationFramewrok dll's should be referenced from ViewModels dll in this aproach, Is there any workaround to expose view without referensing this dll's? – Arsen Mkrtchyan Jan 03 '12 at 17:35
  • Page 58 of the Prism 4 Dev Guide. – dugas Feb 23 '12 at 01:04
  • The dumber the view is the better your life becomes :) +1 – Ignacio Soler Garcia Jul 12 '13 at 08:12
  • Hi, maybe you could help me with this http://stackoverflow.com/questions/38093415/mock-data-not-showing-when-bound-to-icollectionview, I just can't see anything id design time. – Jakub Pawlinski Jul 01 '16 at 13:42
  • 1
    To avoid referencing WPF dll's from a ViewModel, the `ICollectionView` interface (`System.ComponentModel`) can be used without `WindowsBase` and `PresentationFramework.dll`. To create an `ICollectionView` from your `ObservableCollection`, use `myCollectionView = CollectionViewSource.GetDefaultView(myObservableCollection)` then set your Bindings in XAML, `` https://msdn.microsoft.com/en-us/library/system.componentmodel.icollectionview(v=vs.110).aspx @ArsenMkrtchyan – turkinator Aug 19 '16 at 00:21
  • But if I go and use CollectionViewSource.GetDefaultView I HAVE to reference PresentationFramework in my ViewModel which in my case is a no go ... is there any other base implementation for a collectionView ? – D4rth B4n3 Nov 17 '16 at 08:16
  • @D4rthB4n3 there should be no problem injecting the `ICollectionView`s into the VM - e.g. have the UI code call `CollectionViewSource.GetDefaultView` or pass in a CollectionViewService into your VM – Jack Ukleja Feb 03 '17 at 04:05
3

I know I'm a bit late answering your question but I just saw it today.

I have created master/detail viewmodels that use the CollectionViewSource and blogged about it.

I wrote about a viewmodel for master/detail tables here that uses : http://reyntjes.blogspot.com/2009/04/master-detail-viewmodel_24.html

You can also find a viewmodel for the observablecollection class on my blog pages.

Maybe you find it of use to you.

Community
  • 1
  • 1
Robert
  • 924
  • 1
  • 9
  • 20