I am going to assume you know WPF and C# fairly well and going to speak about MVVM design pattern and how these blend together.
I will first expose the reasons behind all the hassle. The reason is that we want to separate between the UI and the functionality and the logic. UI can be very volatile, changing often and can involve complex designing and we don’t want the functionalities and logic to be UI dependent.
Design patterns can provide us the means to do that,however, in simple applications, the use of design pattern can turn into a real useless headache therefore design patterns are particular useful and should be used for business applications, large applications in general.
The MVVM(Model-View-ViewModel) was developed by Microsoft and makes full advantage of the WPF technologies. The keyword in MVVM is binding, as the view bind to properties of a ViewModel which in turn exposes data contained in model objects to the view. If a property value changes in the ViewModel, those new values automatically propagate to the view due to the data binding.
When a button is clicked in the View, a command on the ViewModel performs the requested action. The ViewModel performs data operations, never the View.
This is often called loosely coupled design because the View is not aware of the ViewModel and the ViewModel doesn’t care how the data is displayed and as well as the fact that you don’t have to write extra code to update the view when the data changes.
Another huge advantage of this approach is that writing unit tests are fairly easy, as they are written on the ViewModel and you don’t interact with the UI and makes the testing of functionality easy and natural.
So the ViewModel is basically a class which implements properties and command to which the view can bind and notifies the view of any state change through change notification events.
The properties and commands from the ViewModel define the functionalities to be offered by the UI, but the View determines how the functionality is going to be rendered.
The ViewModel can manipulate the model data so that it can be easily consumed by the View. It can also define additional properties to support the view, but those would normally not belong to the model. For example it can define a property that combines the first name and last name into one property to make it easier for the view to display it.
Another functionality of the ViewModel is validation logic to ensure data consistency.
To summarize, the view model has the following key characteristics:
- The view model is a non-visual class and does not derive from any WPF 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.
The Model is also a class that encapsulates business logic and data. By business logic I mean any rules, restrictions and management of the data that a particular business has.
The Model offers support for property and collection changed notification though the INotifyPropertyChanged and INotifyCollectionChanged interfaces. Model classes that are collections usually derive from the ObservableCollection class which already implements the INotifyCollectionChanged interface.
To wire up everything together WPF uses data bindings and provides really powerful capabilities. Data bindings are either one-way or two-way: one-way refers that the UI simply reflects the value of underlying data but the two-way automatically updates the UI when the data is changed(using the above mentionated interfaces).
WPF data binding supports binding to nested properties via the Path property.
This is just an introduction to the MVVM pattern use within WPF and does not cover a very important chapter: data bindings. Maybe I’ll cover it on another post.