Reputation: 3241
Trying to grasp the concepts of MVVM, I have already read several blogs and looked at a few projects.
From what I understand, a View is dumb, it just knows how to present something that is passed to it.
Models are just the plain data, and a ViewModel is something that acts like a padding in between the two, that it should get information from the Model and pass it onto the View, and the View should know how to present it. Or the other way around, if the information in the View changes, it should pass on the change to the Model.
But I still have no idea how to apply the concept. Can someone explain a very simple scenario so I can grasp the concept? I've already looked at several projects, but it still doesn't make complete sense, so if someone could write it out in plain English, that would be nice.
Upvotes: 104
Views: 50276
Reputation: 519
A great intro to MVVM can be found in Jason Dolinger's video here. I kept the video with me for quite a while when I was starting, it's really useful.
Upvotes: 2
Reputation: 40461
Using this incredibly helpful article as the source, here is a summary for View, ViewModel, and Model.
The view is a visual element, such as a window, page, user control, or data template. The view defines the controls contained in the view and their visual layout and styling.
The view references the view model through its DataContext
property. The controls in the view are data bound to the properties and commands exposed by the view model.
The view may customize the data binding behavior between the view and the view model. For example, the view may use value converters to format the data to be displayed in the UI, or it may use validation rules to provide additional input data validation to the user.
The view defines and handles UI visual behavior, such as animations or transitions that may be triggered from a state change in the view model or via the user's interaction with the UI.
The view's code-behind may define UI logic to implement visual behavior that is difficult to express in XAML or that requires direct references to the specific UI controls defined in the view.
NOTE:
Because the view model should have no explicit knowledge of the specific visual elements in the view, code to programmatically manipulate visual elements within the view should reside in the view's code-behind or be encapsulated in a behavior.
The view model is a non-visual class and does not derive from any WPF or Silverlight base class. It encapsulates the presentation logic required to support a use case or user task in the application. The view model is testable independently of the view and the model.
The view model typically does not directly reference the view. It implements properties and commands to which the view can data bind. It notifies the view of any state changes via change notification events via the INotifyPropertyChanged
and INotifyCollectionChanged
interfaces.
The view model coordinates the view's interaction with the model. It may convert or manipulate data so that it can be easily consumed by the view and may implement additional properties that may not be present on the model. It may also implement data validation via the IDataErrorInfo
or INotifyDataErrorInfo
interfaces.
The view model may define logical states that the view can represent visually to the user.
NOTE:
Anything that is important to the logical behavior of the application should go into the view model. Code to retrieve or manipulate data items that are to be displayed in the view through data binding should reside in the view model.
Model classes are non-visual classes that encapsulate the application's data and business logic. They are responsible for managing the application's data and for ensuring its consistency and validity by encapsulating the required business rules and data validation logic.
The model classes do not directly reference the view or view model classes and have no dependency on how they are implemented.
The model classes typically provide property and collection change notification events through the INotifyPropertyChanged
and INotifyCollectionChanged
interfaces. This allows them to be easily data bound in the view. Model classes that represent collections of objects typically derive from the ObservableCollection<T>
class.
The model classes typically provide data validation and error reporting through either the IDataErrorInfo
or INotifyDataErrorInfo
interfaces.
The model classes are typically used in conjunction with a service or repository that encapsulates data access and caching.
Upvotes: 33
Reputation: 6514
I like to think of it this way:
Views, as you say, are dumb. Josh Smith, writer of the seminal and often linked MSDN article on MVVM, has said that views are "the clothes that data wears." Views never actually contain data or directly manipulate it, they are just bound to properties and commands of your viewmodels.
Models are objects that model the domain of your application, as in business objects. Is your application a music store? Perhaps your model objects will be artists, albums and songs. Is your application an org-chart browser? Perhaps your model objects will be managers and employees. These model objects are not related to any kind of visual rendering, and they aren't even directly related to the application you're putting them into - your model objects should make sense completely on their own as a family of objects that represent some kind of domain. The model layer also typically includes things like service accessors.
This brings us to Viewmodels. What are they? They are objects that model a GUI application, meaning they provide data and functionality to be used by views. They are what define the structure and behavior of the actual application you are building. For the model objects, the domain is whatever domain you choose (music store, org-chart browser, etc.), but for the viewmodel, the domain is a graphical application. Your viewmodels are going to encapsulate the behavior and the data of everything your application does. They are going to expose objects and lists as properties, as well as things like Commands. A command is just a behavior (at its simplest, a method call) wrapped up into an object that carries it around - this idea is important because views are driven by databinding, which attaches visual controls to objects. In MVVM, you don't give a button a Click handler method, you bind it to a command object (served up from a property in a viewmodel) that contains the functionality you want to run when you click it.
For me, the most confusing bits were the following:
The rabbit hole goes deeper - there are lots of idioms to figure out like ValueConverters that keep MVVM working, and there's a lot to apply when you start thinking about things like Blendability, testing, and how to pass data around in your app and ensure that each viewmodel has access to the behavior it needs (this is where dependency injection comes in), but hopefully the above is a good start. The key is to think about your visuals, your domain, and the structure and behavior of your actual application as three different things.
Upvotes: 194
Reputation: 564333
I've written this out in about as "plain english" as I can think of in this series on MVVM. In particular, this diagram is likely the simplest, short explanation.
That being said, basically, the "model" is your data or business rules. It really shouldn't know about how or where it's going to be used, and especially not which technology is going to use it. The "model" is the core guts of the application - and it shouldn't need to worry about whether the application is WPF, Silverlight, Windows Forms, ASP.NET, etc - it's just "itself" in a pure form.
The "View" is the part that is completely technology specific. In MVVM, ideally, the View should be nearly 100% XAML, as this provides some huge gains for flexibility.
However, there needs to be something that translates the information from the Model into some form where it's usable by the technology at hand - this is where the ViewModel comes into play. For example, this often "wraps" up the model classes into a "ViewModel" for that specific data that includes Commands (for running logic), implements INotifyPropertyChanged
(for data binding support), etc. That's it - it's the bridge that makes the Model usable by the View.
Upvotes: 23