tags:

views:

87

answers:

3

Hi,

We're designing a WPF / MVVM application that allows the user to search and manipulate contact records.

We have a MainViewModel that contains an observable collection of ContactViewModel objects, each one of which wraps a Contact entity returned from our business layer. The UI displays these in a list, with the SelectedItem property bound to a corresponding SelectedContact property on the MainViewModel.

We'll also have a button or something where the command is bound to a 'ProcessContact' ICommand exposed by MainViewModel.

ProcessContact needs to takes the selected contact and do something with it, it doesn’t really matter what.

My question is: What would be the correct way of getting at the underlying Contact object wrapped by the selected ContactViewModel? I could just expose a Contact property on my view model, but that then means the view could potentially bind to properties directly off the model.

I've found myself passing ViewModel instances around a lot, which feels wrong when what I really want is the entity it's wrapping.

Am I missing something obvious?

Edit: A couple of suggestions thrown around by colleagues:

  • Expose the entity as a protected property on the ViewModel, which would stop the view binding to it (assuming the view classes are in a separate assembly)

  • Stop trying to access the model altogether. If we want to process the underlying entity in some way, we call a method on the ViewModel. In my example we might have a .Process method off ContactViewModel. ( ‘SelectedContact.Process()’ )

The second option feels like a better solution to me, but not sure if we should be putting that much logic into the ViewModel (but if not there, then where?)

A: 

I would suggest to have an observable collection of Contact objects in your MainViewModel. Framework will automatically support the change notification for entity properties and you don't even ned to implement INotifyPropertyChanged in your entity.

In case you have any specific reason for wrapping your Contact entity in viewmodel(I am curious to know them) you will have to expose the Contact object(through a property ) and use it.

akjoshi
What if I want to bind to, for example, the Surname of the contact. My Contact entity doesn't support INotifyPropertyChanged ( nor should it, being a POCO business object ) but ContactViewModel *does*, and can marshall property updates to the contact, raising NotifyPropertyChanged at the same time. See Josh Smiths MVVM article on msdn: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx - Replace his Customer / CustomerViewModel with my Contact / CntactViewModel and you'll have pretty much the same situation.
Pj
A: 

Do not wrap your Model inside your ViewModel. Atleast do not expose it as a public property.

You can make your Presenter an observer of the Model so that it gets notified when the Model changes. Your Presenter can then call the View and pass it the ViewModel.

Unmesh Kondolikar
@Unmesh: I don’t think wrapping the model in the ViewModel in uncommon in MVVM. See Josh Smiths article on msdn: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx where each of his CustomerViewModel classes has a reference to the underlying Customer object ). In this case the model classes are just containers of data, and don’t expose anything that would make them observable ( property change notifications etc ), that’s kinda what the VM is there for...
Pj
+1  A: 

Your second suggestion seems more correct to me. I usually wrap my data in a view model which is like a controller anyway... It should be controlling what happens to your data by the user's actions in the view. So i would go with wrapping your data and then attach the appropriate behaviors to your view model. I don't know why you would be worried about adding too much logic to your view model, that is its job!

David Rogers