The Model, View, ViewModel (MVVM pattern) is all about guiding you in how to organize and structure your code to write maintainable, testable and extensible applications.
Model − It simply holds the data and has nothing to do with any of the business logic.
ViewModel − It acts as the link/connection between the Model and ViewModel, and makes stuff look pretty.
View − It simply holds the formatted date and essentially delegates everything to the Model.
The key benefit is allowing true separation between the View and Model beyond achieving separation and the efficiency that you gain from having that. What it means in real terms is that when your model needs to change, it can be changed easily without the view needing to and vice-versa.
There are three key things that flow out of applying MVVM −
In general, model is the simplest one to understand. It is the client side data model that supports the views in the application.
It is composed of objects with properties and some variables to contain data in memory.
Some of those properties may have reference to other model objects and create the object graph which as a whole is the model objects.
Model objects should raise property change notifications which in WPF means data binding.
The last responsibility is validation which is optional, but you can embed the validation information on the model objects by using the WPF data binding validation features via interfaces like INotifyDataErrorInfo/IDataErrorInfo.
The main purpose and responsibilities of views is to define the structure of what the user sees on the screen. The structure contains static and dynamic parts.
Static parts are the XAML hierarchy that defines the controls and layout of controls that a view is composed of.
Dynamic part is like animations or state changes that are defined as part of the View.
The primary goal of MVVM is that there should be no code behind in the view.
In view you at least need the constructor and a call to initialize component.
The event handling, action and data manipulation logic code shouldn’t be in the code behind in View.
There are also other kinds of code that have to go in the code behind any code that's required to have a reference to UI element. It is inherently view code.
ViewModel is the main point of MVVM application. The primary responsibility of ViewModel is to provide data to the view, so that view can put that data on the screen.
It also allows the user to interact with data and change the data.
The other key responsibility of ViewModel is to encapsulate the interaction logic for a view, but that does not mean all of the logic of the application should go into ViewModel.
It should be able to handle the appropriate sequencing of calls to make the right thing happen based on user or any changes on the view.
ViewModel should also manage any navigation logic like deciding when it is time to navigate to a different view.
There are two ways to construct views. You can use any one of them.
One way is to simply add your ViewModel as a nested element in the setter for the DataContext property as shown in the following code.
<UserControl.DataContext> <viewModel:StudentViewModel/> </UserControl.DataContext>
Another way is that you can do view first construction by simply constructing the view model yourself in the code behind of your View by setting the DataContext property there with the instance.
Typically, the DataContext property is set in the constructor method of view, but you could also defer the construction until the Load event of the view fires.
using System.Windows.Controls; namespace MVVMDemo.Views { /// <summary> /// Interaction logic for StudentView.xaml /// </summary> public partial class StudentView : UserControl { public StudentView() { InitializeComponent(); this.DataContext = new MVVMDemo.ViewModel.StudentViewModel(); } } }
The main reason of constructing ViewModel in code-behind instead of XAML is that the view model constructor takes parameters, but XAML parsing can only construct elements if defined in default constructor.
ViewModelLocator provides a standard, consistent, declarative and loosely coupled way to do view first construction which automates the process of getting ViewModel hooked up to the View. Following are the high level process of ViewModelLocator.
Data binding is the key feature that differentiates MVVM from other UI separation patterns like MVC and MVP.
Data bindings can either be OneWay or TwoWay to flow data back and forth between the View and ViewModel.
Implicit data templates can automatically select an appropriate template from the current resource dictionary for an element that uses data binding. They do this based on the type of the data object which is rendered by data binding. First you need to have some element that is binding to a data object.
There are two main actors, the invoker and the receiver in Command pattern.
Invoker
Invoker is a piece of code which can execute some imperative logic. Typically, it is a UI element that the user interacts with in the context of a UI framework. But it could just be another chunk of logic code somewhere else in the application.
Receiver
Receiver is the logic that is intended for execution when the invoker fires. In the context of MVVM, the receiver is typically a method in your ViewModel that needs to be called.
In between the invoker and the receiver you have an obstruction layer that does not allow the invoker and the receiver to explicitly know about each other. This is typically represented as an interface abstraction exposed to the invoker and a concrete implementation of that interface is capable of calling the receiver.
No, if the chunk of content just provides the structure to render something to the screen and does not support any input or manipulation by the user for that content. It may not need a separate ViewModel, but it could just be a chunk XAML that renders based on properties exposed by the parents ViewModel.
When your application starts accepting data input from end users you need to consider validating that input. To make sure it conforms to your overall requirements.
You can use the following ways of expressing validation that are supported by WPF data binding −
Inversion of Control (IoC) and dependency injection are two design patterns that are closely related and the container is basically a chunk of infrastructure code that does both of these patterns for you. IoC pattern is about delegating responsibility for construction and the dependency injection pattern is about providing dependencies to an object that's already been constructed.
An event is a programming construct that reacts to a change in state, notifying any endpoints that have registered for notification. Primarily, events are used to inform a user input via the mouse and keyboard, but their usefulness is not limited to that. Whenever a state change is detected, perhaps when an object has been loaded or initialized, an event can be fired to alert any interested third parties.