-1

I have read that in MVVM the VM should know nothing about the view and view should not bind directly to the model, but should bind to the VM which forwards on properties from model and manipulates the model as required. So I guess the model classes do not need to implement INotifyProperty changed as this is handled by the view model.

This is all fine when there one of everything but I am not sure how to arrange things when there are parent child relationships. Say we have an Order object which has properties (customer name, address etc.) which are displayed on the order view. So an OrderView binds to an OrderViewModel which has a reference to an Order (model) object. Each Order object has a list of OrderItem (model) objects which has properties like item, quantity total etc.

Now the OrderView needs to display a list of OrderItems (say in a GridView) and so bind to a property called Items on the OrderView. What should the type of this property be? If it’s List then out view is binding directly to model object, which is against the principles I mentioned at the start and, our OrderItem object does implement INotifyPropertyChanged. Should the OrderItem be “wrapped” in some kind of VM object, and if so what should we call it – OrderItemViewModel? I’m not sure this is a good fit as is not the view model of an order item view – its just providing properties for the GridView to bind to, and that name conflicts with OrderItemViewModel class described below

Now lets say we have an OrderItemView which is a UserControl which is a child of the OrderView. Its role is to display the currently selected order item on the OrderView. Am I right is saying that It’s view model should be called OrderItemViewModel and it should have a reference to the currently selected order which is set by the OrderViewModel, so the OrderViewModel has knowledge of the OrderItem view model?

Shane
  • 2,271
  • 3
  • 27
  • 55
  • Just curious, why the down vote? – Shane May 31 '18 at 12:11
  • Guessing the DV is because there are actually a few questions here + no code. Regarding OrderItem, binding directly to the collection of OrderItem is not violating MVVM. Alternativelly, wrapping every OrderItem in an OrderItemViewModel is great if/when the user can for instance make a change to Quantity through view interactions BUT you want to allow “undo” or control when changes are truly pushed to the core OrderItem model. – blins May 31 '18 at 12:33
  • *"and view should not bind directly to the model"* nope. Bind to whatever makes sense. Just don't put UI logic in your view models/models and don't put business logic in your views. That's all you need to worry about with MVVM. The rest is for you to decide what works best for you. –  May 31 '18 at 16:41
  • @Will - by a model I mean a business object as described [here](https://en.wikipedia.org/wiki/Business_object) in Wikipedia, something that might be returned from a web service call for example - so you a saying binding to such an object is ok? Usually objects we bind to need to support INotifyPropertyChanged - if I add support for INotifyPropertyChanged to my model would you consider that UI logic? – Shane Jun 01 '18 at 01:44
  • Objects returned by a web service are (or can be, if you don't rely on a tool to generate them) objects that are completely under your control. Property change notification isn't UI logic. If you think it is, you're only hobbling yourself, not gaining advantages from the MVVM pattern. Remember--the pattern exists to serve us, not the other way around. When you can simply call a web service and deserialize the results into objects that can be directly used by your view models to bind to the UI... yes, make my life easier, please. –  Jun 01 '18 at 12:37

1 Answers1

0

So I guess the model classes do not need to implement INotifyProperty changed as this is handled by the view model.

It depends on how you define a model. A model is typically a service of some kind that you may inject a view model with. Or a server-side domain object that contains business logic.

A type that you bind to in the view may be seen as a "child" view model. For example, if your OrderViewModel class exposes the following property:

public ObservableCollection<Order> Orders { get; }

..it is perfectly fine for the view to bind to properties of the Order class and for the latter to implement the INotifyPropertyChanged and any other client-related stuf. In this case Order is effectively a view model and not an actual model.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • OK, so in your later case, if the Order class is basically a VM then where is the model in this picture? My understanding of VM is that it is a mediator between the view and the (domain) model and as such contains the interaction logic of the view. Would it be better to have an OrderViewModel which has an Order property, the properties of which the view can bind directly to to? I have seen other answers on this and opinion seems to be divided. – Shane May 31 '18 at 13:44
  • The model is the component from which you get the orders, i.e. typically a service, business layer or DAL. I don't understand your second question. The OrderViewModel may expose a collection of Orders or a single one. The Order type may still be a view model. You typically don't expose business object for the view to bind to. – mm8 May 31 '18 at 13:48
  • Maybe we are using different terminology - by a model I mean a business object as described [here](https://en.wikipedia.org/wiki/Business_object) something which _"holds a set of instance variables or properties, also known as attributes, and associations with other business objects"_ and may or may or may not use contain business methods. I would expect these object to returned from the DAL. Would you consider it to be OK to add support to INotifyProperty changed to these objects and bind to them? – Shane Jun 01 '18 at 01:53
  • @Shane: You shouldn't return business object from a DAL but that's another story. Yes, you can implement INotifyPropertyChanged in your "business" object if you want to. This interface is defined in System.dll and is not WPF specific. So that's a perfectly fine thing to do. – mm8 Jun 01 '18 at 11:13
  • Thanks - makes sense. Your comment has piqued my interest - what do you mean when you say "You shouldn't return business object from a DAL"? For me, the DAL could be providing access directly to a database it could be a web-service client for instance. – Shane Jun 01 '18 at 11:30
  • Yes, but these are not "business objects" but rather DTOs. But, as I mentioned, that's another topic. – mm8 Jun 01 '18 at 11:31
  • Fair enough, but could you please point me in the direction of where I can read more about the distinction? To me they both contain properties which model domain concepts. – Shane Jun 01 '18 at 11:37
  • https://stackoverflow.com/questions/4637124/what-is-a-dto-and-bo-what-is-the-difference – mm8 Jun 01 '18 at 11:38
  • Thanks, so back to the topic in hand, then its fine for a DTO to take on the role of a model MVVM? – Shane Jun 01 '18 at 11:47
  • A DTO should be a simple POCO object with no logic including change notifications. You can wrap your DTOs in view models that implement the INotifyPropertyChanged in the client and bind to these. – mm8 Jun 01 '18 at 11:49
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/172241/discussion-between-shane-and-mm8). – Shane Jun 01 '18 at 12:11