The Model-View-ViewModel (MVVM) QuickStart demonstrates how to build an application that implements the MVVM presentation pattern. The following are benefits of using MVVM:
- It incorporates separation of concerns.
- It produces maintainable application code.
- It produces maintainable user interfaces (UIs) for the designer.
- It simplifies unit testing of the application logic.
Business Scenario
The main window of the MVVM QuickStart represents a subset of a survey application. In this window, an empty survey with different types of questions is shown; after the questionnaire is completed, it can be submitted. The user can also choose to reset the answers to the questions.
The following illustration shows the QuickStart main window.
Building and Running the QuickStart
This QuickStart requires Microsoft Visual Studio 2010, Silverlight 4, and the Silverlight 4 Tools for Visual Studio 2010.
To build and run the MVVM QuickStart
- In Visual Studio, open the solution file Quickstarts\MVVM\MVVM.sln.
- On the Build menu, click Rebuild Solution.
- Press F5 to run the QuickStart.
Walkthrough
To explore the scenario, perform the steps to build and run the QuickStart:
- The main window is composed of a view that shows a questionnaire composed of different types of questions. When the questionnaire is fully completed, it can be submitted. The following illustration shows the main window.
Note:Notice that in the UI of the QuickStart there are information icons—you can click them to display/hide information and implementation notes about the different pieces of the QuickStart. QuickStart main window
- Enter information into the Name and Age boxes, and then respond to the questions in the questionnaire. Notice that when you complete open questions, the "chars remaining" count decreases. Also, note that the number of remaining questions, located at the lower-left of the screen, decreases after you respond to each question.
- Enter one or more letters to answer the first question. A validation error will display, as shown in the following illustration, because this question type is numeric. If there are validation errors shown as you complete the questionnaire, fix them before you click Submit. The completed questionnaire with errors

Note:If you choose more than two answers for the multiple selection question, a validation error displays. - After you complete the questionnaire without validation errors, the Submit button is enabled. Click it to submit your answers. An animation is displayed during the processing of the submitted questionnaire, as shown in the following illustration; after that, the form resets.A questionnaire being submitted

Implementation Details
The QuickStart highlights the key elements and considerations to implement the MVVM pattern. For more information about the MVVM pattern, see Chapter 5, "Implementing the MVVM Pattern." This section describes the key artifacts of the QuickStart, which are shown in the following illustration.
Note: |
|---|
| The preceding illustration shows the typical model-view-view model interaction. However, this interaction can be a little different on some applications. For example, in this QuickStart, some elements from the view are bound directly to the model. |
Elements
The MVVM pattern includes the following:
- Model. The model represents the underlying, logical structure of data in a software application and the high-level classes associated with it. This object model does not typically contain any information about the user interface.
- View. A View is typically some form of user interface element that lets users interact with the application. In a Windows Presentation Foundation (WPF) or Silverlight application, typically each view is composed of an Extensible Application Markup Language (XAML) file and its corresponding code behind.
- ViewModel. The view model is an intermediate class between the view and the model. It references the model and calls methods on the model to retrieve domain objects, which are typically exposed to the view as a flat set of properties. The communication between view and view model should be purely through data binding.
In pure MVVM applications, when the user updates the view, data binding pushes these changes to the view model, and when the view model data changes, data binding pushes the changes to the view. However, in some cases, such as this QuickStart, some properties could be directly bound to the model.
Note: |
|---|
| The view model in the QuickStart inherits from the ViewModel base class, which implement the INotifyPropertyChanged interface. For more information about the ViewModel base class, see the section, The ViewModel Base Class, later in this topic. |
Data Binding
To support data binding, the recommend approach is that the view model should implement the INotifyPropertyChanged interface. Similarly, any objects provided to the view through properties should support the INotifyPropertyChanged or INotifyCollectionChanged interfaces when you want to react to changes from the view model or the model. Implementing these interfaces allows the data binding mechanism to monitor the view model or the model for changes so that it can automatically update the UI. To support the INotifyPropertyChanged interface and make the view models easier to develop, the ViewModel base class is provided in the QuickStart. This base class is discussed in the next section.
Typically, the view model is set as the data context for the view so that the binding expressions defined in the view resolve to the corresponding properties on the view model, or on the model if it is exposed by the view model. In the QuickStart, the view model is instantiated and assigned declaratively in the View's XAML. This is shown in the following code of the QuestionnaireView, where, the QuestionaireViewModel is instantiated declaratively in its DataContext property.
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" xmlns:Infra="clr-namespace:MVVM.Infrastructure" xmlns:Views="clr-namespace:MVVM.Views" xmlns:basicvm="clr-namespace:MVVM.ViewModels" mc:Ignorable="d" x:Class="MVVM.Views.QuestionnaireView" d:DesignWidth="640" d:DesignHeight="480" > ... <UserControl.DataContext> <basicvm:QuestionnaireViewModel /> </UserControl.DataContext> ... </UserControl>
To be able to instantiate the ViewModel class declaratively, it must provide a default constructor.
The ViewModel Base Class
The ViewModel base class provides support for the INotifyPropertyChanged interface. The view model classes of the QuickStart inherit from this class. The INotifyPropertyChanged interface is implemented to notify clients, typically binding clients, that a property value has changed and, therefore, update the UI with the new values. The following code is a simplified version of the implementation of the ViewModel base class, where the validation methods are not shown because they are explained in the next section.
public class ViewModel : INotifyPropertyChanged { ... public event PropertyChangedEventHandler PropertyChanged; protected void ExecuteOnUIThread(Action action) { var dispatcher = Deployment.Current.Dispatcher; if (dispatcher.CheckAccess()) { action(); } else { dispatcher.BeginInvoke(action); } } protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpresssion) { var propertyName = PropertySupport.ExtractPropertyName(propertyExpresssion); this.RaisePropertyChanged(propertyName); } protected virtual void RaisePropertyChanged(string propertyName) { var handler = this.PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } }
The INotifyPropertyChanged interface requires the implementation of the PropertyChanged event. The ViewModel base class also contains the RaisePropertyChanged helper method, which raises the event that notifies when a particular property of the view model has changed.
The overloads provided for the RaisePropertyChanged method are based on different approaches used to support the INotifyPropertyChanged interface. One implementation follows the simplest approach, using strings for the property names. A drawback of this approach is that it is error prone, because if the property name is misspelled, no compile time or runtime exception will be thrown, and UI elements that are bound to the changing property will not update because the change notification raised will not match the property name. The second approach accepts lambda expressions as the parameter. The advantage of this is that the parameter is checked at design time and during compilation, but you need to implement more logic to support this.
Note: |
|---|
| For other approaches that can be used to implement the INotifyPropertyChanged interface, see "Implementing INotifyPropertyChanged" in Chapter 5, "Implementing the MVVM Pattern." |
You should call this RaisePropertyChanged method in the property setter for each property that is exposed to the view where you want the view to update based on the change. When you call the method, pass the property name as the parameter or a lambda expression indicating the property, as shown in the following sample code.
public string CurrentState { get { return this.currentState; } set { if (this.currentState == value) { return; } this.currentState = value; // Choose only one of these approaches. // Lambda expression this.RaisePropertyChanged(() => this.CurrentState); // Plain string RaisePropertyChanged("CurrentState"); } }
Note: |
|---|
| In the preceding code, both approaches are shown, but only one should be used. |
For calculated properties, you also need to notify the event for the calculated property whenever its result could have changed (that is, in the setters of other properties).
View/View Model Structure
This QuickStart demonstrates the challenge of having hierarchical view models. The QuestionnaireViewModel is the main view model of the application (the QuestionnaireView view that is contained on the main page), and exposes a collection of child view models, each of which can be of a different type. Each question of the questionnaire has its own view model.
The following illustration shows the class diagram for the view model classes of the QuickStart.

Notice that each question type class inherits from the QuestionViewModel<T> generic abstract class, which inherits from the ViewModel base class. This base class implements the INotifyPropertyChanged interface. Notice that the QuestionnaireViewModel class also inherits from the ViewModel base class.
A questionnaire is composed of several questions; in the same way, the QuestionnaireViewModel class is composed of several question view models. This class has the Questions property, which is an ObservableCollection of QuestionViewModel, and because QuestionViewModel is a generic abstract class, the questions must be instances of the concrete classes (NumericQuestionViewModel, OpenQuestionViewModel, or MultipleSelectionQuestionViewModel).
To determine the visual representation of a question type view model (OpenQuestionViewModel, NumericQuestionViewModel, or MultipleSelectionQuestionViewModel), the DataTemplateSelector custom ContentControl, provided as part of the Prism Library for Silverlight, is used in the QuestionnaireView.xaml file. These visual representations are implemented as separate user controls (the OpenQuestionView, NumericQuestionView, and MultipleSelectionQuestionView views).
Note: |
|---|
| For more information about the DataTemplateSelector, see the section, "Data Templates," later in this topic. |
Validation
The ViewModel base class supports setting validation errors for the properties of the view model or model. Silverlight provides the INotifyDataErrorInfo and the IDataErrorInfo interfaces for that. Typically, the INotifyDataErrorInfo interface is implemented to provide synchronous/asynchronous validation logic, such as server-side validation, and expose the validation results to the UI. The INotifyDataErrorInfo interface also supports custom error objects, multiple errors per property, cross-property errors, and object-level errors. Bindings will query INotifyDataErrorInfo or IDataErrorInfo when a bound property change notification is received or the ErrorsChanged event is triggered.
Note: |
|---|
| For more information about the INotifyDataErrorInfo interface and asynchronous validation in Silverlight, see the INotifyDataErrorInfo Interface. |
The DomainObject class implements the INotifyDataErrorInfo and the INotifyPropertyChanged interfaces, as you can see in the following code, taken from the Infrastructure\DomainObject.cs class file.
public abstract class DomainObject : INotifyPropertyChanged, INotifyDataErrorInfo { private ErrorsContainer<string> errorsContainer; protected DomainObject() { } public event PropertyChangedEventHandler PropertyChanged; public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; public bool HasErrors { get { return this.ErrorsContainer.HasErrors; } } protected ErrorsContainer<string> ErrorsContainer { get { if (this.errorsContainer == null) { this.errorsContainer = new ErrorsContainer<string>(pn => this.RaiseErrorsChanged(pn)); } return this.errorsContainer; } } public IEnumerable GetErrors(string propertyName) { return this.ErrorsContainer.GetErrors(propertyName); } protected void RaisePropertyChanged(string propertyName) { this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) { var handler = this.PropertyChanged; if (handler != null) { handler(this, e); } } protected virtual void ValidateProperty(string propertyName, object value) { } protected void RaiseErrorsChanged(string propertyName) { this.OnErrorsChanged(new DataErrorsChangedEventArgs(propertyName)); } protected virtual void OnErrorsChanged(DataErrorsChangedEventArgs e) { var handler = this.ErrorsChanged; if (handler != null) { handler(this, e); } } }
To implement the INotifyDataErrorInfo, the following members must be implemented: the HasErrors property, the GetErrors method, and the ErrorsChanged event.
The GetErrors method returns an IEnumerable that contains validation errors for the specified property or for the entire object. You can implement this method to report cross-property errors at the object level or for each affected property, depending on your reporting needs. Notice the ErrorsContainer property of the ErrorContainer<T> type. This class implements the members required by the INotifyDataErrorInfo interface and stores the errors in a dictionary, where the key is the property name and the value could be of any type that represents the validation error of that property. The DomainObject abstract class redirects the members of the INotifyDataErrorInfo interface to the actual implementations in the ErrorContainer class.
The errors for a property or entity can change or be replaced as asynchronous validation rules finish processing. Whenever the errors of the ErrorContainer change, the ErrorsChanged event must occur. The DataErrorsChangedEventArgs argument for the event carries the name of the property for which the errors have changed. Event handlers can retrieve new HasErrors and GetErrors values to update the UI validation feedback for the affected property or object. This happens automatically in the data bindings on elements.
Note: |
|---|
| For more information about data validation, see "Data Validation and Error Reporting" in Chapter 5, "Implementing the MVVM Pattern." |
To set the conditions that a property must fulfill to be valid and the validation errors, you must validate the value and set the errors in overriding the ValidateProperty of the corresponding model object.
The following code shows the implementation of the ValidateProperty method of the Questionnaire model class. In this template method, the conditions of each property are verified and the corresponding errors are set in the ErrorContainer instance of the DomainObject base class.
protected override void ValidateProperty(string propertyName, object value) { if (propertyName == "Age") { var response = value as int?; var errors = new List<string>(); if (!response.HasValue) { errors.Add("Age must be completed"); } else if (this.MaxAge.HasValue && (this.MaxAge.Value < response || this.MinAge > response)) { errors.Add(string.Format("Age should be between {0} and {1}.", this.MinAge, this.MaxAge.Value)); } else if (this.MinAge > response) { errors.Add(string.Format("Age should be more than {0}.", this.MinAge)); } this.ErrorsContainer.SetErrors(propertyName, errors); } else if (propertyName == "Name") { var response = value as string; var errors = new List<string>(); if (string.IsNullOrEmpty(response)) { errors.Add("Name should be completed."); } else if (this.NameMaxLength.HasValue && response.Length > this.NameMaxLength.Value) { errors.Add(string.Format("Name should have less than {0} characters.", this.NameMaxLength.Value)); } this.ErrorsContainer.SetErrors(propertyName, errors); } else { base.ValidateProperty(propertyName, value); } }
Notice, from the preceding code, that when a validation criterion is not met, you must set the error using the SetErrors method of this particular implementation of the INotifyDataErrorInfo interface.
The following code shows the Questionnaire partial class, located in the Model\DomainObjects.cs file. In this file, you can see that each class from the model inherits from the DomainObject abstract class and that the validations are triggered in the setter of each property that needs to be validated.
public sealed partial class Questionnaire : DomainObject { private int? age; private string name; private int minAge; private int? maxAge; private int? nameMaxLength; private ICollection<Question> questions; public Questionnaire() { } public int? Age { get { return this.age; } set { if (this.age != value) { this.ValidateProperty("Age", value); this.age = value; this.RaisePropertyChanged("Age"); } } } public string Name { get { return this.name; } set { if (this.name != value) { this.ValidateProperty("Name", value); this.name = value; this.RaisePropertyChanged("Name"); } } } public int MinAge { ... } public int? MaxAge { ... } public int? NameMaxLength { ... } public ICollection<Question> Questions { get { if (this.questions == null) { this.questions = new List<Question>(); } return this.questions; } } }
UI Interaction
When the user interacts with the UI, the view model often needs to take actions. Typically, these actions are in response to events or triggers that fire within the UI. There are two ways these can be handled to get the view model to respond in a loosely coupled fashion. New in Silverlight 4 is the ability to execute commands from certain controls when they are clicked. The other way that works for those scenarios, as well as many others, is to use behaviors. Behaviors allow you to add behavior to an element without needing to modify the element type itself. They can be defined using attached properties as a delivery mechanism or using a behavior base class from the Blend SDK, which provides a delivery mechanism (that uses attached properties like Interaction.Triggers and Interaction.Behaviors) and is integrated with Blend, so all you need is to define your own behaviors and triggers. In the context of MVVM, behaviors can be used to hook up events in the UI to the view model in a loosely coupled fashion.
Note: |
|---|
| At the implementation level, there are behaviors and triggers in the Blend SDK Interaction support. Behaviors are more abstract and just provide a way to "do something" to the object they are attached to (which could be, but does not require, attaching handlers to .NET events). Triggers, on the other hand, represent the occurrence of some change in the application and are typically used with TriggerActions that perform the actual work; this allows decoupling the action from the moment in which it is executed. The Blend SDK does not require Microsoft Expression Blend. The Expression Blend SDK can be downloaded separately and freely distributed with your application. |
The QuickStart uses the CallMethodAction TriggerAction. Blend behaviors are very useful to avoid code behind in views and to create views that work in any editor. They are supported by the Blend tool, and they let you reuse existing components and define new ones just by providing the new functionality, assuming that the attachment mechanism is already implemented. The CallMethodAction behavior receives the name of the method that will be executed when the event that is defined in the EventTrigger is triggered, in this case the Submit method of the view model, which is specified using the TargetObject attribute. Additionally, the IsEnabled property of the button is bound to the CanSubmit property of the view model; the value of this property determines whether the button will be enabled. This is used to simulate the effect of the CanExecute method of the ICommand interface.
Note: |
|---|
| The Command property could also have been bound to a command implementation, such as the DelegateCommand in Prism and the ActionCommand in the Blend SDK. The ButtonBase and Hyperlink classes in WPF and Silverlight expose a Command property, in addition to MenuItem in WPF. For a comparison of commands and behaviors, see "Command-Enabled Controls vs. Behaviors" in Chapter 5, "Implementing the MVVM Pattern." |
You can see how this behavior is associated to a button's click event in the following example taken from the QuestionnaireView.xaml file of the QuickStart.
<Button Content="Submit" Height="23" IsEnabled="{Binding CanSubmit}" HorizontalAlignment="Right" x:Name="button2" Width="75"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <ei:CallMethodAction TargetObject="{Binding}" MethodName="Submit"/> </i:EventTrigger> </i:Interaction.Triggers> </Button>
Note that the behavior specifies in its TargetObject property that it binds to the data context (that stores the view model); therefore, the Submit method must exist in the view model as a public method.
Data Templates
By using data templates, a visual designer can easily define how an object will be rendered in the UI. A data template declares UI controls that will be data bound at run time to the underlying data object. The designer can dramatically modify or change the visual representation of an object without changing the underlying data object type.
When you implement the MVVM pattern in a WPF or Silverlight application, you can define the application's views as a data template. Data templates are flexible and lightweight. The UI designer can use them to easily define the visual representation of a view model without requiring any complex code. Data templates are ideally suited for views that do not require any UI logic.
In the QuickStart, there are templates that render each type of question. They can be seen in the following code, extracted from the QuestionnaireView.xaml file. Additionally, the QuickStart defines a DataTemplateSelector class that maps the data context (which happens to be each question view model in the QuickStart) to data templates by mapping the data context's type to a data template defined as a resource local to the selector, using the data context's type as the key. This is an example of using conventions to hook up things instead of configuration. The different question view-model instances are the data bound collection for the ItemsControl used to render the questions. The DataTemplateSelector uses the view model type names as keys to look for the corresponding template.
<ItemsControl Grid.Row="1" IsTabStop="False" ItemsSource="{Binding Questions}"> <ItemsControl.ItemTemplate> <DataTemplate> <Infra:DataTemplateSelector Content="{Binding}" HorizontalContentAlignment="Stretch" IsTabStop="False"> <Infra:DataTemplateSelector.Resources> <DataTemplate x:Key="OpenQuestionViewModel"> <Views:OpenQuestionView DataContext="{Binding}"/> </DataTemplate> <DataTemplate x:Key="MultipleSelectionQuestionViewModel"| <Views:MultipleSelectionView DataContext="{Binding}"/> </DataTemplate> <DataTemplate x:Key="NumericQuestionViewModel"> <Views:NumericQuestionView DataContext="{Binding}"/> </DataTemplate> </Infra:DataTemplateSelector.Resources> </Infra:DataTemplateSelector> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>
As seen in the preceding code, there are three data templates, one each for the Open Questions, Multiple Selection Questions, and Numeric Questions view models. These templates just reference custom controls.
Service Calls
In the QuickStart, service calls are implemented asynchronously, that is to simulate real scenarios, where the services are remote. The AsyncResult class of the QuickStart (located in the Infrastructure/Model folder) is an implementation of the IAsyncResult interface of the System namespace. This class encapsulates the results of an asynchronous operation. The Questionnaire view model has a repository layer that transforms the standard Async programming model into a simpler one, and uses it to retrieve the questions for a questionnaire. The Questionnaire view model is responsible for calling the repository, which in turn gets the questions, as shown in the following code.
public QuestionnaireViewModel(IQuestionnaireRepository questionnaireRepository) { this.questionnaireRepository = questionnaireRepository; this.Questions = new ObservableCollection<QuestionViewModel>(); this.GetNewQuestionnaireInstance(); } private void GetNewQuestionnaireInstance() { this.UpdateCurrentState("Loading"); if (this.Questionnaire != null) { this.Questionnaire.PropertyChanged -= this.OnQuestionnairePropertyChanged; } this.questionnaireRepository.GetQuestionnaireAsync( (result) => { this.Questionnaire = result.Result; this.Questionnaire.PropertyChanged += OnQuestionnairePropertyChanged; this.ResetQuestionnaire(); this.UpdateCurrentState("Normal"); }); }
The preceding code shows the constructor of the QuestionnaireViewModel class, which obtains the repository through dependency injection and then calls the GetNewQuestionnaireInstance method. This method changes the status to "Loading," and then it invokes the GetQuestionnaireAsync method, which starts retrieving the questions in a separate thread. When the service completes retrieving the questionnaire, the callback is executed in the UI thread. As shown in the preceding code, the callback gets a questionnaire, resets it, and updates the status back to "Normal."
Custom Behaviors
Behaviors are a self-contained unit of functionality. A behavior does not have the concept of invocation; instead, it acts more like an add-on to an object. They are additional functionality that can be attached to an object. They can react to handle an event or a trigger in the user interface.
The following behaviors are used in the QuickStart (they are located at the Infrastructure/Behaviors folder):
- SynchronizeSelectedItems. This custom behavior synchronizes the selections in a multiple selection ListBox to the contents of a collection.
- UpdateTextBindingOnPropertyChanged. This custom behavior updates the source of a binding on a text box as the text changes. In this way, the input can be validated whenever a new character is entered or deleted.
- ValidateObject. This custom behavior links a ValidationSummary control to an object that implements the INotifyDataErrorInfo interface to display errors.
Unit and Acceptance Tests
The MVVM QuickStart includes unit tests within the solution. Unit tests verify if individual units of source code work as expected.
To run the MVVM QuickStart unit tests
- In Solution Explorer, right-click MVVM.Test, and then click Set as StartUp Project.
- Press F5.
The MVVM QuickStart includes a separate solution that includes acceptance tests. The acceptance tests describe how the application should perform when you follow a series of steps; you can use the acceptance tests to explore the functional behavior of the application in a variety of scenarios.
To run the MVVM QuickStart acceptance tests
- In Visual Studio, open the solution file QuickStarts\MVVM\MVVM.Tests.AcceptanceTest\MVVM.Tests.AcceptanceTest.sln.
- Right-click MVVM.Tests.AcceptanceTest, and then click Set as StartUp Project.
- Press F5.
Outcome
You should see the QuickStart window and the tests automatically interact with the application. At the end of the test run, you should see that all tests have passed.
More Information
The MVVM Reference Implementation (MVVM RI) has a more complete implementation of this scenario that includes a richer model that does not have to be wrapped as much by the view model and some basic navigation between multiple views backed with view models.
For more information about implementing the MVVM pattern, see the following chapters:
- Chapter 5, "Implementing the MVVM Pattern"
- Chapter 6, "Advanced MVVM Scenarios"
To learn about other QuickStarts included with Prism, see the following topics:
- Modularity QuickStarts for WPF
- Modularity QuickStarts for Silverlight
- Basic MVVM QuickStart
- Commanding QuickStart
- UI Composition QuickStart
- State-Based Navigation QuickStart
- View-Switching Navigation QuickStart
- Event Aggregation QuickStart
- Multi-Targeting QuickStart
Last built: August 28, 2012

