Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm currently working on a Silverlight app using Caliburn.Micro.

At present, we have Views (eg: PeopleView) and View Models (eg: PeopleViewModel) that equate to 'pages' of the application.

PeopleView might contain a ListBox ("People") which is bound to an ObservableCollection of Person objects, and has an ItemTemplate assigned to denote how each Person object should be displayed.

However, one of my colleagues has begun to implement a list in another way, where each Person is a View Model (ie: PersonViewModel) and has an associated PersonView to determine how that PersonViewModel should be displayed in the ListBox.

The latter seems more MVVM (or at least has more mention of V and VM!) but I'm not sure whether there's a particularly large advantage to doing one over the other.

Are both of these ways valid? Is either better than the other?

share|improve this question

4 Answers 4

up vote 3 down vote accepted

Yes, both ways are valid. There are pros and cons to each approach.

If the Person can be displayed in several different ways depending on the context - whether it's in a ListBox or on a "page" then using your technique with an ItemTemplate to control how it's displayed in the list is probably the better way to go.

I think you need to look at your overall design and see which fits best. Changing the implementation part way through is a bad idea though. Some "pages" will be the old style and others will be the new, leading to inconsistencies in the user experience and potentially increased effort in maintaining and extending the system. If nothing else, you will have to go through the existing code to make it conform to the new format.

share|improve this answer
    
Thanks Chris - the Person can be displayed in different ways, yes. I believe there's a way to associate multiple Views with a single ViewModel but I haven't looked too far into that. I agree with your last paragraph - although in this instance the UX would be the same, the code would have two possible implementations rather than one, which is about one too many for this particular scenario! –  Town Sep 7 '11 at 14:53

Ok, so assuming Person is your entity (model object)...

You can do it either way, but with some caveat's:

1) Binding directly to a model object works well in read-only screens. If you just return a list of People and you want the user to choose one, great, it's easy to just bind to that list.

2) Binding directly to your domain model can start to suck if you're implementing a screen that allows you to manipulate those objects. The state of the data under edit can represent an invalid model state until validated and saved.

Due to #2, a lot of people make a PersonViewModel that's really for editing. I don't think that's a good idea either. I think you need to define model classes that represent the state during the editing (and mapping operations between the Person and PersonEdit classes, including validation).

Now if you want to go adding a PersonViewModel, it does have some advantages. Let's say your Person has a property DateOfBirth and a derived property Age, and another derived property AgeGroup (perhaps Toddler, Preteen, Teen, etc.). What if you want to display those people highlighted different colors based on their age group? You can either define a ValueConverter (if you still want to bind directly to the Person object), or you can wrap the Person object in a PersonViewModel and add an AgeGroupColor property to the view model. Then you can bind directly to that. Which method you choose is really up to you. A lot of people don't like ValueConverters, and I agree they're a little verbose for what they do, so I'd probably go with the view model option, like your friend.

share|improve this answer
    
Cheers Scott. AgeGroupColour in this scenario sounds to me more like something that should be defined in the View, as it's purely cosmetic. Although it's restricted to two states, I've generally used DataStateBehavior to achieve this in the item's DataTemplate based on model properties, and I think this type of idea could be extended in this way, although I could be wrong! –  Town Sep 7 '11 at 14:51
1  
@Town: It's not that well defined. If the ViewModel is a testable representation of the View, you might have a unit test which cares that AgeGroup.Teen is displayed as Colors.Red so you'd want it in the ViewModel. In my opinion, you want as little "logic" in the View as possible. –  Scott Whitlock Sep 7 '11 at 14:57
    
That's true Scott, although if we were writing tests to confirm that something was a particular colour in the UI then we'd probably be here forever! I get what you're saying though and it's an example that I'm sure would be very relevant for other similar scenarios that aren't so trivial as UI colours. Cheers. –  Town Sep 7 '11 at 15:02

There's no point having a PersonViewModel if it doesn't have any additional properties over and above the Person model. It's just a waste of time.

However, if you're using value converters to convert a Person in any way then I'd have used a PersonViewModel and not bothered with the value converter.

PersonViewModel should simply expose the Person object and any additional properties. I wouldn't proxy every single Person property into the PersonViewModel.

share|improve this answer
    
Cheers Ben, that confirms what Scott said about extending the underlying class with additional properties, and also explains why you hate ValueConverters so much. –  Town Sep 7 '11 at 15:42

If person is in your model, then it seems to violate the separation created by only exposing view model to the view.

My general rule is the ability to create the viewmodel and view without a model. If this can not be accomplished I make changes.

Exposing the Model to the view is perfectly valid, but it is more of a MVC pattern.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.