Home .NET Prism Developer’s Guide – Part 5, MVVM Pattern Implementation

Prism Developer’s Guide – Part 5, MVVM Pattern Implementation

by admin

Table of contents

  1. Introduction
  2. Initializing Prism applications
  3. Managing dependencies between components
  4. Modular application development
  5. MVVM pattern implementation
  6. Advanced MVVM scripts
  7. Creating a user interface
  1. Recommendations for user interface design
  • Navigation
    1. View-Based Navigation
    2. Interaction between loosely coupled components
    3. Pattern Model-View-ViewModel (MVVM, Model-View-View-Model)helps you separate the business logic and view logic from the UI.Supporting the separation of responsibility between application logic and UI can make your application easier to test, maintain, and develop.It can also greatly improve code reusability and make it easier for developers and designers to collaborate on developing the relevant parts of the application.
      Using the MVVM pattern, the application UI, view logic, and business logic are separated into three separate classes. These are the view, which encapsulates the UI and its logic, the view model, which encapsulates the view logic and its states, and the model, which encapsulates the application business logic and data.
      Prism includes examples and sample implementations that show how to implement the MVVM pattern in Silverlight or in WPF applications. The Prism library also provides functions that can help you implement this pattern. These functions embody the most common methods for implementing the MVVM pattern and are designed to ensure testability and compatibility with Expression Blend and Visual Studio.
      This chapter gives a brief overview of the MVVM pattern and describes how to implement it. Chapter 6 describes how to implement more complex MVVM scenarios using the Prism library.

      Duties and characteristics of classes

      The MVVM pattern is a close variation of the Presentation Model , optimized for better alignment with some basic WPF and Silverlight features, such as data binding, data patterns, commands, and behaviors.
      In the MVVM pattern, the view encapsulates the UI and any UI logic, the view model encapsulates the view logic and its states, and the model encapsulates the business logic and data. The view interacts with the view model by binding data, commands, and notification events. The view model requests data from the model, or subscribes to change notifications, and coordinates model state updates, and converts, validates, and aggregates data, if necessary, to display it in the view.
      The following illustration shows the three parts of the MVVM template and their interaction.
      Prism Developer's Guide - Part 5, MVVM Pattern Implementation

      As with all split view patterns, the key to using the MVVM pattern effectively is understanding how to divide your application code into the correct classes, and understanding the ways in which those classes interact in different scenarios. The following sections describe the responsibilities and characteristics of each of the classes in the MVVM pattern.

      Presentation class ( View )

      A view is responsible for defining what the user sees on the screen. Ideally, the code-behind view contains only a constructor that calls the InitializeComponent In some cases, code-behind may contain UI logic code that implements visual behavior that is difficult or inefficient to express in XAML, such as complex animations, or when the code must directly control the visual elements that are part of the view. It is unacceptable to put logic code that needs to be tested in a view. Generally, code in the code-behind a view can be tested through UI automation.
      In Silverlight and WPF, data binding expressions in a view are computed relative to its data context. In MVVM, the view model is set as the view’s data context. The view model implements the properties and commands to which the view can be bound, and notifies the view of any state changes through change notification events. There is usually a direct relationship between a view and its view model.
      Typically, views are inherited from the Control or UserControl However, in some cases, a view can be represented by a data template that defines the UI elements that will be used to visually represent the object. Using data templates, the developer can easily specify how the view model will be rendered, or can change its default visual representation without changing the underlying object or its behavior directly.
      Data templates can be considered views that have no code-behind. They are designed to bind to certain types of view models when they are to be displayed in the UI. At runtime, a view as defined by a template is automatically created and the corresponding view model is set by its data context.
      In WPF, you can associate a data template with a view model at the application level. Then WPF will automatically apply this data template to any view model objects of the specified type whenever they appear in the UI. This is known as implicit data patterns. In Silverlight, you need to explicitly define a data template for a view model object within the control that is to display it. The data template can be defined as embedded in the control that uses it, or defined in a resource dictionary outside the parent view and declaratively merged with the view’s resource dictionary.
      To summarize, the performance has the following key characteristics :

      • A view is a visual element, such as a window, a page, a custom control, or a data template. A view defines the controls, their layout, and their style.
      • The view refers to the view model through its property DataContext The controls in the view are linked to the properties and commands of the view model.
      • A view can customize the data binding behavior between the view and the view model. For example, the view can use value converters to format the data to be shown in the UI, or use validation rules to provide additional validation of user input.
      • The view defines and handles the visual behavior of the UI, such as animations or transitions, which can be triggered by a change in the state of the view model, or through user interaction with the UI.
      • Code-behind a view can define UI logic to implement some visual behavior that is difficult to express in XAML, or that requires direct references to certain UI controls defined in the view.

      Presentation model class ( View Model )

      The representation model in the MVVM pattern encapsulates the representation logic and data for display. It has no direct reference to the representation or knowledge of the implementation or type of representation. The view model implements properties and commands to which the view can bind data and notifies the view of any state changes through notification events. The properties and commands that the view model provides define the functionality relied upon by the UI, but the view defines how that functionality will be presented to the user.
      The view model is responsible for coordinating the interaction of the view with the necessary model classes. Often, there is a one-to-many relationship between the view model and the model classes. The view model can substitute model classes directly into views so that the controls in the view can bind data directly to them. In this case, the model classes must be designed to support data binding and associated change notification events. For more information about this scenario, see "Data binding" later in this topic.
      A view model can transform or manipulate model data so that the view can easily use it. A view model can have additional properties for the specific needs of a view. These properties usually cannot be part of the model. For example, a view model can combine the value of two fields to make them easier to display, or it can calculate the number of characters remaining when entering for fields with a limited string length. The view model can also implement data validation logic to ensure that the data is consistent.
      The view model can also define logical states that the view can use for visual changes to the UI. The view can define markup or style changes that reflect the state of the view model. For example, a view model can have a state that indicates that data is being transmitted asynchronously to a Web service. The view might show an animation during this state to provide visual feedback to the user.
      Typically, a view model defines commands or actions that can be represented in the UI and invoked by the user. A typical example is when a view model provides a command Submit which allows the user to send data to a web service or repository. The view can present this command as a button so that the user can click it to transmit data. Typically, when a command becomes unavailable, its associated view in the UI becomes disabled. Commands allow user actions to be encapsulated and separated from their visual representation.
      In summary, the representation model has the following key characteristics :

      • Is not a visual class and is not inherited from any WPF or Silverlight base class. It encapsulates the view logic needed to support user actions in the application. The view model is tested independently of the view and model.
      • Normally does not directly reference a view. It implements properties and commands to which the view can bind data. It notifies the view of any state changes through interface notification events INotifyPropertyChanged and INotifyCollectionChanged
      • Coordinates the interaction of the view with the model. It can transform or manipulate data so that it can be easily used by the view, and it can implement additional properties that may not be present in the model. It can also implement data validation through interfaces IDataErrorInfo or INotifyDataErrorInfo
      • Can define logical states that the view can visually represent to the user.

      Note. Representation or representation model?
      Often the definition of where a certain functionality should be implemented is not obvious. The general rule states : Anything about a particular visual display that can be upgraded later (even if you don’t currently plan to upgrade it)must go into the view; anything that is important to the logic of the application must go into the view model.In addition, since the view model should not have any explicit knowledge of certain visual elements in the view, the code to programmatically control the visual elements within the view should be in code-behind the view or encapsulated in behaviors ( Behaviors ).Similarly, the code for retrieving or controlling data items that are to be shown in a view through data binding must reside in the view model.For example, the highlight color of a selected item in a list box must be defined in the view, but the list of items to be displayed and the link to the selected item must be defined in the view model.

      ModelClass ( Model )

      The model in the MVVM pattern encapsulates business logic and data.Business logic is defined as any application logic that is concerned with retrieving and managing application data and making sure that business rules are satisfied to ensure consistency and validity of the data.To maximize reusability, models should not contain representation-specific information, logic, or behavior.
      Typically, a model represents the subject matter entity of the client side of an application. It can contain data structures based on the application data model and any business and validation logic. The model may also have data and cache access, although usually a separate data repository, or service, is used for this purpose. Often, the model and data access layer are auto-generated, as part of the ADO.NET Entity Framework, WCF Data Services, or WCF RIA Services infrastructure.
      Typically, a model implements means to facilitate binding to a view. This usually means that notifications of changes to properties or collections through interfaces INotifyPropertyChanged and INotifyCollectionChanged Model classes that provide object sets are usually inherited from the ObservableCollection<T> . which provides an implementation of the interface INotifyCollectionChanged The model can also support data validation and error reporting through the interfaces IDataErrorInfo (or INotifyDataErrorInfo ).These interfaces allow you to send WPF and Silverlight notifications to update the UI when bound data values change. They also provide support for data validation and UI-level error messages.

      Note
      What if your model classes don't implement the required interfaces?
      Sometimes you will have to work with model objects that do not implement interfaces INotifyPropertyChanged , INotifyCollectionChanged , IDataErrorInfo , or INotifyDataErrorInfo In these cases, the view model may have to wrap the model objects and provide the necessary properties to the view. The values for these properties will be provided directly by the model objects. The view model will be able to implement the necessary interfaces for the properties it provides so that the view can easily bind data to them.

      The model has the following key characteristics :

      • Model classes are non-visual classes that encapsulate application data and business logic. They are responsible for managing the application data and for ensuring its consistency and validity by encapsulating the necessary business rules and data validation logic.
      • Model classes do not directly reference view classes or view models and have no dependency on how those classes are implemented.
      • Model classes typically provide notifications of changes to properties or collections through interfaces INotifyPropertyChanged and INotifyCollectionChanged This allows them to be easily bound to a view. Model classes that represent collections of objects are usually inherited from the ObservableCollection<T>.
      • Model classes usually provide data validation and error reporting via interfaces IDataErrorInfo , or INotifyDataErrorInfo
      • Model classes are usually used in conjunction with a service or repository that encapsulates data access and caching.

      Class Interaction

      The MVVM pattern provides a clean division of responsibility between your application’s user interface, its presentation logic, and its business logic and data by separating each element into separate classes. So when you implement MVVM, it’s important to separate the code into the correct classes, as described in the previous section.
      Well-designed view classes, view models, and models will not only encapsulate the correct logic and behavior, they will also be designed to easily interact with each other through data binding, commands, and data validation interfaces.
      The interactions between a view and its view model are probably the most important to consider, but the interactions between model classes and the view model are also important. The following sections describe the different types of these interactions and describe how to develop them by implementing the MVVM pattern.

      Data binding ( Data Binding )

      Data binding plays a very important role in the MVVM pattern. WPF and Silverlight provide powerful capabilities for data binding. Your view model and (ideally) your model classes should be designed to support data binding. Typically, this means that they should implement the correct interfaces.
      Silverlight and WPF data binding supports a variety of modes. With one-way data binding, UI controls can be linked to the view model so that they reflect the underlying data values when rendered. Two-way data binding will automatically update the underlying data when the user changes it in the UI.
      To ensure that the UI is updated when data changes in the view model, it must implement an appropriate change notification interface. If it defines properties to which data can be bound, it must implement the interface INotifyPropertyChanged If the view model represents a collection, it must implement INotifyCollectionChanged or inherit from the class ObservableCollection<T> which implements this interface. Both of these interfaces define an event that is generated whenever the underlying data changes. Any associated controls will be automatically updated when these events are generated.
      In many cases, a view model contains properties that return objects (which, in turn, may contain properties that return additional objects). WPF and Silverlight data binding supports binding to nested properties via the Path Therefore, the view model inherently returns references to other view model classes or models. All view model classes and models available to the view must implement the interface INotifyPropertyChanged or INotifyCollectionChanged
      The following sections describe how to implement the necessary interfaces to support data binding within the MVVM pattern.

      Implementation INotifyPropertyChanged

      Interface Implementation INotifyPropertyChanged in view or model classes allows them to notify related controls in the view about changes in values. The implementation of this interface is relatively simple, as shown in the following example (see class Questionnaire in Basic MVVM QuickStart ).

      public class Questionnaire : INotifyPropertyChanged{private string favoriteColor;public event PropertyChangedEventHandler PropertyChanged;...public string FavoriteColor {get { return this.favoriteColor; }set {if (value != this.favoriteColor) {this.favoriteColor = value;if (this.PropertyChanged != null) {this.PropertyChanged(this, new PropertyChangedEventArgs("FavoriteColor"));}}}}}

      Interface Implementation INotifyPropertyChanged in many view model classes can be repetitive and error-prone because of the need to define a property name. The Prism library provides a convenient base class from which you can inherit your view model classes that implement the INotifyPropertyChanged in a type-safe way, as shown below.

      public class NotificationObject : INotifyPropertyChanged {public event PropertyChangedEventHandler PropertyChanged;...protected void RaisePropertyChanged<T> (Expression<Func<T> > propertyExpression) {...}protected virtual void RaisePropertyChanged(string propertyName) {...}}

      An inherited view model class can generate a property change event by both calling RaisePropertyChanged with a specific property name, or by using a lambda expression that accesses the property, as shown below.

      public string CurrentState {get { return this.currentState; }set {if (this.currentState != value) {this.currentState = value;this.RaisePropertyChanged(() => this.currentState);}}}

      Note
      Using lambda expressions in this way causes a small performance loss because the lambda expression must be computed for each query. The advantage is that this approach provides type safety at compile time and support for refactoring when you rename a property. Although the performance loss is small and usually does not affect your application, costs can accumulate if you have a lot of change notifications. In that case, you should consider using a method overload that accepts the string.

      Note
      Fresh versions Resharper support refactoring even with an overload accepting the property name as a string.

      Often your model or view model will contain properties whose values are computed depending on other model or view model properties. When generating a property change event, make sure that you also generate notification events for any dependent properties. For example, if you have Price1, Price2, and SumPrice fields that represent the sum of the first two fields, the setters of the Price1 and Price2 method RaisePropertyChanged("SumPrice")

      Implementation INotifyCollectionChanged

      Your view or model class may be a collection of items, or may have one or more properties that return a collection. Otherwise, you might want to display the collection in one of the ItemsControl Such as ListBox , or DataGrid These controls can be linked to a view model that provides a collection or a property that returns a collection via the property ItemSource

      <DataGrid ItemsSource="{Binding Path=LineItems}" />

      In order to properly support change notification requests for a collection of objects, the model classes of a view or model that is a collection must implement the .. INotifyCollectionChanged (in addition to the interface INotifyPropertyChanged ).If a view or model class defines a property that returns a reference to a collection, the returned collection class must implement the INotifyCollectionChanged
      However, the implementation of the interface INotifyCollectionChanged is quite complex, because it must send notifications when items are added, removed, moved, or changed within the collection.Instead of implementing the interface directly, it is often easier to use directly, or inherit from a collection class that already implements it.Class ObservableCollection<T> implements this interface and is usually used either as a base class or in properties representing a collection of items.
      If you must build a collection to bind data to a view, and you don’t need to track user selection of items, or support filtering, sorting, or grouping of items in the collection, you can simply define a property in your view model that returns a reference to an instance of ObservableCollection<T>

      public class OrderViewModel : INotifyPropertyChanged {public OrderViewModel(IOrderService orderService) {this.LineItems = new ObservableCollection<OrderLineItem> (orderService.GetLineItemList());}public ObservableCollection<OrderLineItem> LineItems { get; private set; }}

      If you get a reference to a collection class (for example, from another component or service that does not implement INotifyCollectionChanged ), you can wrap that collection in an instance of ObservableCollection<T> using one of the constructors that take as a parameter IEnumerable<T> or List<T>

      Implementation ICollectionView (collection view)

      The previous code example shows how to implement a simple view model property that returns a collection of items that can be shown through linked controls in the view.Since ObservableCollection<T> implements the interface INotifyCollectionChanged , the controls in the view will be automatically updated when items are added or removed.
      Often you want to more precisely control how a collection of items is displayed in a view, or track a user’s interaction with a displayed collection of items directly within the view model. For example, you may want to filter or sort the item collection according to the view logic implemented in the view model, or track the currently selected item in the view so that commands implemented in the view model can only affect the selected item.
      WPF and Silverlight support such scripts by providing different classes that implement the interface ICollectionView This interface provides properties and methods that allow a collection to be filtered, sorted, or grouped, and allows you to track or change the item currently selected. Both Silverlight and WPF provide implementations of this interface, Silverlight gives the class PagedCollectionView , and WPF gives the class ListCollectionView
      The collection view classes work by wrapping the underlying collection of items so that they can provide automatic tracking of the selected item, sorting, filtering, and alerting. An instance of these classes can be created programmatically or declaratively in XAML, using the class CollectionViewSource

      Note
      In WPF, a CollectionView will automatically be created by default whenever a control is bound to a collection. In Silverlight, it will only be automatically created if the linked collection supports the ICollectionViewFactory

      Collection view classes can be used by the view model to track important state information for the underlying collection, supporting the separation of duties between the UI in the view and the underlying data in the model. In fact, CollectionViews are view models that are specifically designed to support collections.
      Therefore, if you need to implement filtering, sorting, grouping, or item selection tracking in a collection from within your view model, then your view model must create an instance of the collection view class for each collection to be given to the view. It will then be possible to subscribe to selection events, such as CurrentChanged , or control filtering, sorting, or grouping using the collection view class methods within your view model.
      The view model must implement a read-only property that returns a reference to ICollectionView so that the controls in the view can bind data to and interact with the collection view. All WPF and Silverlight controls that come from the base class ItemsControl , can automatically interact with the ICollectionView
      The following example shows the use of PagedCollectionView in Silverlight to track the currently selected client.

      public class MyViewModel : INotifyPropertyChanged {public ICollectionView Customers{ get; private set; }public MyViewModel(ObservableCollection<Customer> customers) {Customers = new PagedCollectionView(customers);Customers.CurrentChanged +=new EventHandler(SelectedItemChanged);}private void SelectedItemChanged(object sender, EventArgs e) {Customer current = Customers.CurrentItem as Customer;...}}

      In the view, it is possible to link ItemsControl such as ListBox , with the property Customers in the view model via the property ItemsSource , as shown below.

      <ListBox ItemsSource="{Binding Path=Customers}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding Path=Name}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>

      When a user selects a client in the UI, the view model will be informed and can only execute commands relating to the selected client. The view model can also programmatically change the current selection in the UI by calling methods on the collection view object, as shown in the following example.

      Customers.MoveCurrentToNext();

      When a selected item changes in the collection view, the UI automatically updates to visually indicate the selected state of the item. The implementation is similar for WPF, although PagedCollectionView in the previous example would usually be replaced by the class ListCollectionView , or BindingListCollectionView , as shown below.

      Customers = new ListCollectionView(_model);Customers.CurrentChanged += new EventHandler(SelectedItemChanged);

      Teams

      In addition to providing access to the data to be displayed or edited in the view, the view model is likely to define one or more actions or operations that can be performed by the user. In WPF and Silverlight, actions or operations that the user can perform through the UI are usually defined as commands. Commands provide a convenient way to represent actions or operations that can be easily mapped to controls in the UI. They encapsulate the code that implements the required action and help keep it separate from the visual representation.
      Commands can be visually represented and invoked by the user in many different ways. In most cases, they are invoked by a mouse click, but they can also be invoked by keyboard shortcuts, touch gestures, or any other input event. The controls in the view are linked to commands in the view model so that they can be invoked by the user using any input event defined by the control. The interaction between the UI controls in the view and the command can be two-way. In this case, the command can be invoked by the user’s interaction with the UI, and the control can be automatically unlocked or locked when the underlying command is enabled or disabled.
      The representation model can implement commands as CommandMethod , or as Command Object (an object that implements the interface ICommand ). In any case, a view’s interaction with a command can be defined declaratively without requiring complex event handling code in the code-behind the view. For example, certain controls in WPF and Silverlight support commands and provide the property Command , which can be associated with a property of the type ICommand in the representation model. In other cases, it may use CommandBehavior to associate a control with a command method or command object in the view model.

      Note
      Behaviors are a powerful and flexible extensibility mechanism that can be used to encapsulate interaction logic and behavior that can be declaratively associated with controls in a view. CommandBehavior can be used to link command objects or methods to controls that were not specifically designed to interact with commands.

      The following sections describe how to implement commands in your view as methods or command objects, and how to associate them with controls in the view.

      Implementation Command Objects

      The command object is an object that implements the interface ICommand This interface defines a method Execute which encapsulates the necessary actions, and the method CanExecute which shows if the command can be called at a certain time. Both of these methods take a single argument as a command parameter. Encapsulating the logic in the command object means that it can be more easily tested and maintained.
      Interface Implementation ICommand is relatively simple. However, there are many implementations of this interface that you can readily use in your application. For example, you can use the class ActionCommand from the Expression Blend SDK, or the class DelegateCommand provided by Prism.
      Class DelegateCommand encapsulates two delegates, each referring to a method implemented within your view model class. It is inherited from the class DelegateCommandBase which implements the methods of Execute and CanExecute interfaces ICommand by calling these delegates. You define delegates in your view model methods in the class constructor DelegateCommand , which looks like this.

      public class DelegateCommand<T> : DelegateCommandBase {public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod):base((o) => executeMethod((T)o), (o) => canExecuteMethod((T)o)) { ... }}

      For example, the following code shows how an instance of DelegateCommand which represents the command Submit is created by creating delegates to methods of the representation model OnSubmit and CanSubmit The command is passed to the view via the read-only property, which returns a reference to ICommand

      public class QuestionnaireViewModel {public QuestionnaireViewModel() {this.SubmitCommand= new DelegateCommand<object> (this.OnSubmit, this.CanSubmit);}public ICommandSubmitCommand{ get; private set; }private void OnSubmit(objectarg) {...}private bool CanSubmit(object arg) { return true; }}

      When method Execute is called on the object DelegateCommand , the call is simply redirected to a method in your view model class via the delegate you defined in the constructor.Likewise, when a call is made to a method CanExecute is called, the corresponding method in your view model class is called.Delegate to method CanExecute in the constructor is optional.If the delegate is not defined, the DelegateCommand will always return true for CanExecute
      Class DelegateCommand is a universal type. The type parameter defines the type of the command parameter passed to the Execute and CanExecute In the preceding example, the command parameter has the type object Not a universal version of the class DelegateCommand is also provided by Prism for use when the command parameter is not required.
      The representation model can indicate a change in the state of the method CanExecute commands by calling the method RaiseCanExecuteChanged on the object DelegateCommand This will trigger the event CanExecuteChanged Any controls in the UI that are associated with the command will update their state to reflect the availability of the associated command.
      Other interface implementations available ICommand Class ActionCommand in the Expression Blend SDK, is similar to the Prism class DelegateCommand described earlier, but only supports the single delegate method Execute Prism also provides a class of CompositeCommand which allows the grouping of DelegateCommands for execution. For more information about using the CompositeCommand , see. "Composite Commands" in Chapter 6, "Advanced MVVM Scripts."

      Calling command objects from a view

      There are many ways in which controls in a view can be associated with a command object provided by the view model. WPF and Silverlight 4 controls, especially those inherited from ButtonBase , such as Button , RadioButton , Hyperlink , or inherited from MenuItem , can be easily associated with the command object through the property Command WPF also supports binding ICommand to KeyGesture

      <ButtonCommand="{Binding Path=SubmitCommand}" CommandParameter="SubmitOrder"/>

      Additionally a command parameter can be set using the property CommandParameter The type of the expected parameter is defined in the target methods Execute and CanExecute The control will automatically call the target command when the user interacts with that control, and the command parameter, if any, will be passed as a parameter to the Execute command. In the previous example, the button will automatically call the SubmitCommand when it is clicked. Additionally, if a handler is defined CanExecute , the button will be automatically disabled if CanExecute will return false and will be turned on if true
      An alternative approach should use Expression Blend interaction triggers and behavior InvokeCommandAction

      <Button Content="Submit" IsEnabled="{Binding CanSubmit}"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:InvokeCommandActionCommand="{Binding SubmitCommand}"/> </i:EventTrigger> </i:Interaction.Triggers> </Button>

      This approach can be used for any control that you can attach an interaction trigger to. This is especially useful if you want to attach a command to a control that is not a descendant of ButtonBase , or when you want to call a command on an event other than a click event. Note again that if you have to pass parameters for your command, you can use the property CommandParameter
      Unlike controls, which can be linked directly to a command, InvokeCommandAction does not automatically enable or disable the control based on the value of CanExecute command. To implement this behavior, you must bind the IsEnabled controls to a suitable property in the view model, as shown above, or write your own specialized behavior to disable controls, depending on the availability of the command.

      Note
      Command-supporting controls in WPF and Silverlight 4, allow you to declaratively bind a control to a command. These controls will invoke the specified command when the user interacts with them. For example, for a control Button , the command will be invoked when the user presses the button. This command-related event is fixed and cannot be changed.

      Behaviors also allow you to connect a control to a command object in a declarative way. However, behaviors can be associated with various events generated by the control, and they can be used to invoke the associated command object or command method in the view model when a given condition is met. In other words, behaviors can implement many of the same scenarios as supported command controls, and they can provide a greater degree of flexibility and control.
      You will have to choose when to use command-supporting controls and when to use behaviors, and which type of behavior to use. If you prefer to use a single mechanism to link controls in the view to functionality in the view model or for consistency, you should consider using behaviors, even for command-supporting controls.
      If you only need to use command-supporting controls, and if you are happy with the standard command call events, behaviors may not even be necessary. Likewise, if your developers or UI developers will not use Expression Blend, you may choose to use only command-supporting controls (or custom attached behaviors) because of the additional syntax required to use Expression Blend behaviors.

      Calling command methods from view

      An alternative approach to implementing commands as objects ICommand is to implement them simply as methods in the view model and then use behavior to invoke those methods directly from the view.
      This can be achieved in a similar way to calling commands from behavior, as shown in the previous section. However, instead of using InvokeCommandAction is used, the CallMethodAction The following example calls a method (without parameters) Submit on the underlying representation model.

      <Button Content="Submit" IsEnabled="{Binding CanSubmit}"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:CallMethodActionTargetObject="{Binding}" Method="Submit"/> </i:EventTrigger> </i:Interaction.Triggers> </Button>

      TargetObject is associated with the underlying data context (which is the representation model) using the expression {Binding} Parameter Method defines the method to call.

      Note
      CallMethodAction does not support parameters. If you must pass parameters to the target method, you must pass a value to the view model property, switch to use the command with InvokeCommandAction , or write your own version of CallMethodAction , which takes parameters.

      Data validation and error messages

      Your view model or model will often be required to perform data validation and signal any data validity errors to the view so that the user can correct them.
      Silverlight and WPF provide support for managing data validation errors that occur when individual properties associated with controls in a view change. For individual properties that are associated with a control, the view model or model can signal a data validation error within the property’s set method, rejecting the incoming bad value and throwing an exception. If the property ValidatesOnExceptions on the data binding object will be equal to true , the data binding mechanism in WPF and Silverlight will handle the exception and show the user a visual indicator that there is a validation error.
      However, throwing exceptions by properties should thus be avoided wherever possible. An alternative approach is to implement the interface IDataErrorInfo or INotifyDataErrorInfo in the representation model or model classes. These interfaces allow the view or model to perform validation for values of one or more properties and return an error message to the view so that the user can be notified of the error.

      IDataErrorInfoimplementation

      Interface IDataErrorInfo provides basic support for data validation and error reporting. It defines two read-only properties : the indexer property, with the property name as the indexer parameter, and the Error Both properties return a string value.
      The indexer property allows a view model or model class to provide an error message defined for a named property. An empty string or a null return value indicates to the view that the modified property value is valid. The Error property allows the view model or model class to provide an error message for the entire object. Note that this property is not currently called by the Silverlight or WPF data binding mechanism.
      Indexer property IDataErrorInfo is called when a data-related property is displayed and whenever it is subsequently changed. Since the indexer property is called for all properties that change, every effort should be made to ensure that data validation is as fast and efficient as possible.
      When you bind controls in a view to properties, you want to check them via the IDataErrorInfo , set the property ValidatesOnDataErrors in the data binding in the true This ensures that the data binding mechanism requests error information from the associated property.

      <TextBox Text="{Binding Path=CurrentEmployee.Name, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True }"/>

      Implementation of INotifyDataErrorInfo

      Interface INotifyDataErrorInfo is more flexible than the interface IDataErrorInfo It supports multiple errors for a property, asynchronous data validation, and the ability to notify the view of an error state change for an object.However, INotifyDataErrorInfo is currently only supported in Silverlight 4 and is not available in WPF 4.

      Note
      This interface started to be supported in WPF in .NET Framework 4.5.

      Interface INotifyDataErrorInfo defines the property HasErrors which allows the view model to indicate if there is an error (or multiple errors) for any of the properties, and the GetErrors which allows the view model to return a list of error messages for a particular property.
      Interface INotifyDataErrorInfo also defines the event ErrorsChanged It supports asynchronous validation scenarios, allowing the view or model to signal a change in the error condition for a certain property via the event ErrorsChanged The value of a property can be changed in different ways, not only through data binding, but also, for example, as a result of a web service request or a background calculation. Event ErrorsChanged allows the view model to report an error to the view as soon as a data validation error has been identified.
      For support INotifyDataErrorInfo , you will need to store an error list for each property. Model-View-ViewModel Reference Implementation (MVVM RI) demonstrates one way to do this using the collection class ErrorsContainer which keeps track of all validation errors in the object. It also generates notification events if the error list changes. The following example shows DomainObject (model root object) and the implementation of INotifyDataErrorInfo using the class ErrorsContainer

      public abstract class DomainObject : INotifyPropertyChanged, INotifyDataErrorInfo{private ErrorsContainer<ValidationResult> errorsContainer =new ErrorsContainer<ValidationResult> (pn => this.RaiseErrorsChanged(pn));public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;public bool HasErrors {get { return this.ErrorsContainer.HasErrors; }}public IEnumerable GetErrors(string propertyName) {return this.errorsContainer.GetErrors(propertyName);}protected void RaiseErrorsChanged(string propertyName) {var handler = this.ErrorsChanged;if (handler != null) {handler(this, new DataErrorsChangedEventArgs(propertyName));}}...}

      In Silverlight, any control data associated with the properties of the view model will automatically subscribe to the INotifyDataErrorInfo and will show error information in the control if the property contains an error.

      Creation and aggregation

      The MVVM pattern helps you separate UI from presentation, business logic, and data, so putting the right code in the right class is an important first step in using this pattern effectively. Managing the interaction between the view and view model classes through data and command binding is also an important aspect to consider. The next section will show how the view, view model, and model classes are created and interact with each other at runtime.

      Note
      Choosing the right strategy in this step is especially important if you use a dependency implementation container in your application. Managed Extensibility Framework (MEF) and Unity Application Block (Unity) and provide the ability to define dependencies between a view, a view model, and model classes and execute their container. For more advanced scenarios, see Chapter 6, Advanced MVVM Scenarios.

      There is usually a direct relationship between a representation and its representation model. The view model and the view are loosely related through the view data context property. This allows the visual elements and behaviors in the view to be related to the properties, commands, and methods of the view model. You will have to decide how to manage the creation of view and view model classes and their association through the DataContext At runtime.
      Care must also be taken when creating and linking the view and view model to ensure that weak connectivity is preserved. As noted in the previous section, the view model should not depend on any particular implementation of the view. Similarly, a view should not depend on any particular implementation of a view model.

      Note
      However, it should be noted that a view will implicitly depend on certain properties, commands, and methods of the view model because of data binding. If the view model does not implement the required property, command, or method, a runtime exception will be generated and displayed in the Visual Studio output window during debugging.

      There are many ways in which a view and a view model can be created and linked at runtime. Choosing the most appropriate way for your application will depend largely on whether you create the view or the view model first, and whether you do it programmatically or declaratively. The following sections describe common ways that view classes and view models can be created and related to each other at runtime.

      Creating a representation model via XAML

      Perhaps the easiest approach for a view is to declaratively create its corresponding view model in XAML. When the view is created, the corresponding view model object will also be created. You can also specify in XAML that the view model will be set as the view data context.
      The XAML approach is demonstrated in the file QuestionnaireView.xaml in Basic MVVM QuickStart. In that example, the instance of QuestionnaireViewModel is defined in XAML QuestionnaireView , as shown below.

      <UserControl.DataContext> <my:QuestionnaireViewModel/> </UserControl.DataContext>

      When QuestionnaireView will be created, an instance of QuestionnaireViewModel will automatically be created and set up as a view data context. This approach requires your view model to have a default constructor (no parameters).
      The declarative creation and assignment of a view model by a view has the advantage that it is simple and works well in design time tools such as Microsoft Expression Blend or Microsoft Visual Studio. The disadvantage of this approach is that the view is aware of the corresponding view model.

      Creating a representation model programmatically

      A view creates an appropriate instance of a view model programmatically in the constructor. It can set it as its data context, as shown in the following example.

      public QuestionnaireView() {InitializeComponent();this.DataContext = new QuestionnaireViewModel();}

      Programmatically creating and assigning a view model within a code-behind view has the advantage that this method is simple and works well in design time tools such as Expression Blend or Visual Studio. The disadvantage of this approach is that the view must be aware of the appropriate view model type, and that it requires code within the code-behind view. Using a dependency implementation container, such as Unity or MEF, you can provide a weak link between the view model and the view. For more information, see Chapter 3, "Managing Dependencies Between Components."

      Creating a view defined as a data template

      A view can be defined as a data template and associated with a view model type. Data patterns can be defined as resources, or as embedded, within a control that displays a view model. "Content" of a control is an instance of the view model, and the data template is used to represent it visually. WPF and Silverlight will automatically create the data template, and set its data context to an instance of the view model at runtime. This method is an example of a situation in which the view model is created first, and then the view.
      Data templates are flexible and lightweight. A UI developer can use them to easily define a visual representation of a view model, without any complicated code. Data templates are limited to views that do not require any UI logic (code-behind). For visual development and editing of data templates, Microsoft Expression Blend can be used.
      The following example shows ItemsControl , which is associated with a list of customers. Each customer object in the underlying collection is an instance of the view model. The representation for a customer is defined by the built-in data template. In the following example, the representation for each consumer representation model consists of StackPanel with a label and a text field associated with the property Name of the representation model.

      <ItemsControl ItemsSource="{Binding Customers}"> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock VerticalAlignment="Center" Text="Customer Name: " /> <TextBox Text="{Binding Name}" /> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>

      You can also define a data template as a resource. The following example shows a data template defined as a resource and applied to a control via the markup extension StaticResource

      <UserControl...> <UserControl.Resources> <DataTemplate x:Key="CustomerViewTemplate"> <local:CustomerContactView /> </DataTemplate> </UserControl.Resources> <Grid> <ContentControl Content="{Binding Customer}"ContentTemplate="{StaticResource CustomerViewTemplate}" /> </Grid> </Window>

      Here, the data template wraps a specific view type, which allows the view to define code-behind behavior. In this way, the data template mechanism can be used to surface the relationships between the view and the view model. Although the previous example shows a template in the resources UserControl , it is often placed in application resources or in ResourceDictionary for reuse. You can see that an example of using data patterns creates views and associates them with their view models in the QuickStart MVVM. QuestionnaireView.xaml

      Key solutions

      When you decide to use the MVVM pattern when building your application, there are certain design decisions you will need to make that will be difficult to change later. Typically, these are decisions for the entire application, and their consistent use throughout the application will improve developer and designer performance. The following are the most important decisions when implementing the MVVM pattern:

      • Choose the approach for creating views and view models that you will use.You must decide whether your application creates views or view models first, and whether to use a dependency implementation container such as Unity or MEF.It is usually desirable to be consistent across the entire application.For more information, see the section, "Advanced Construction and Wire-Up" in this chapter and the section, "Advanced MVVM Scenarios" in Chapter 6, "Advanced MVVM Scenarios."
      • Decide whether you will represent commands as command methods or command objects.Commandmethods are simple to implement and can be invoked through behaviors in the view. Command objects can neatly encapsulate command and on/off logic and can be invoked via behavior or via the Command in ButtonBase controls. To make the work of your developers and designers easier, it would be a good idea to make this a choice for the entire application. For more information, see "Commands" in this chapter.
      • Decide how your view models and models will report errors to the view. Your models can either support the interface IDataErrorInfo , or INotifyDataErrorInfo It is possible that not all models will need to report error information, but for those that do, it is preferable to have a non-controversial approach for your developers. For more information, see "Validation and Error Reporting" in this chapter.
      • Decide whether supporting Microsoft Expression Blend design-time information is important to your team. If you will be using Expression Blend for UI development and want to see data at design time, make sure that your views and view models have constructors without parameters, and that your views set the data context at design time. Alternatively, consider using the design time functions provided by Microsoft Expression Blend that use design time attributes such as d:DataContext and d:DesignSource For more information, see "Guidelines for Creating Designer Friendly Views" in Chapter 7, "Composing the User Interface".

      Additional information

      For more information about data binding in WPF, see "Data Binding" on MSDN: http://msdn.microsoft.com/en-us/library/ms750612.aspx .
      About Data Binding in Silverlight, check out "Data Binding" on MSDN: http://msdn.microsoft.com/en-us/library/cc278072(VS.95).aspx
      For more information about Binding to Collections in WPF, see "Binding to Collections" in the Data Binding Overview on MSDN: http://msdn.microsoft.com/en-us/library/ms752347.aspx
      For more information about Binding to Collections in Silverlight, see "Binding to Collections" in "Data Binding" on MSDN: http://msdn.microsoft.com/en-us/library/cc278072(VS.95).aspx
      For more information on the Presentation Model pattern, see "Presentation Model" on Martin Fowler’s website : http://www.martinfowler.com/eaaDev/PresentationModel.html
      For more information on data templates, see "Data Templating Overview" on MSDN: http://msdn.microsoft.com/en-us/library/ms742521.aspx
      For more information about MEF, see "Managed Extensibility Framework Overview" on MSDN: http://msdn.microsoft.com/en-us/library/dd460648.aspx
      For more information about Unity, see "Unity Application Block" on MSDN: http://www.msdn.com/unity
      For more information about DelegateCommand and CompositeCommand , see part 9, " Communicating Between Loosely Coupled Components "

      You may also like