MVVM Technical Description


This is an excerpt from, In the Box – MVVM Training that is posted on the Visual Studio Gallery.

Have a great day,

Karl


The gold standard for learning and describing design patterns is the book, Design Patterns: Elements of Reusable Object-Oriented Software.

Below, I present the MVVM pattern using the chapter format, section titles defined in the book.


Model-View-ViewModel

UI Design


Intent

Provide a clean separation of concerns between the user interface controls and their logic.

Also Known As

MVVM, M-V-VM and ViewModel

Motivation

Development languages like Visual Basic (1-6), Microsoft Access, .NET Windows Forms, WPF, Silverlight and Windows Phone 7 provide a default experience that leads a developer down the path of dragging controls from a Toolbox to a design surface then writing code in the form’s code-behind file. Many software companies and consultants have successfully delivered applications authored using these languages to customers.

As these applications grew in size and scope and were modified over-time, complex maintenance issues began to surface. Some of these issues were limitations of the language; others resulted from the lack of supporting infrastructure like source control or test frameworks. Some were the result of application logic being located in code-behind files and the resulting tight coupling between the UI form controls and the code-behind that increased the cost to make form modifications.

The four top reasons for using the MVVM pattern in Microsoft XAML applications are:

  • Provides separation of concerns
  • It is natural pattern for XAML platforms
  • Enables the developer-designer workflow
  • Increases application testability


Customer Maintenance Form Scenario

Let’s quickly examine a common scenario found in forms over data applications and see how the MVVM pattern is used.

Our application requires a data entry form that allows a customer entity to be displayed, saved and or deleted.

The MVVM pattern addresses separation of concerns by defining that UI application logic be located in a view model class as opposed to the view’s code-behind file. It leverages the rich data binding stack of the XAML platform to expose the view model to the view’s UI controls through the view’s DataContext property. A by-product of the separation of concerns is the enablement of a clean developer-designer workflow. Designers are now emancipated to modify the UI, change or rename controls to suite their requirements without breaking the application. Application testability has been increased because the view model takes its dependencies in the form interfaces, allowing the view model to be individually tested in isolation.

alt

The above UML diagram shows:

  • CustomerView.DataContext is CustomerViewModel
  • CustomerViewModel exposes a Customer property to the View

CustomerViewModel exposes two ICommand properties that the view’s UI controls which support commands can bind to

  • CusomverViewModel has its dependencies injected in the constructor
  • CustomerViewModel private data operation methods call public methods exposed on the ICustomerRespository interface


Applicability

Use the MVVM pattern when developing on Microsoft XAML platforms.

Structure

Components communicate through data bindings and event notification. Additionally, the view can use behaviors to invoke public methods on the view model.

alt

The model is depicted as an entity and the application domain.

alt

Participants

  • Model
    • Responsible is for business logic and data. The model is your client side domain and is represented as data entities, business objects, repositories and services
    • Implements change notification for properties and collections
    • Can implement validation interfaces such as IDataErrorInfo so that validation errors can be surfaced on the view
  • View
    • Defines structure, appearance and interactivity of the user interface
    • Implemented as a Window, UserControl, Page, DataTemplate, or custom control
    • Can be the applications top-level control, a sub-component of a parent view or a DataTemplate for an object in an ItemsControl.
    • Has little or no code-behind
    • DataContext is a view model
    • Controls data bind to view model public properties
    • Behaviors can invoke view model public methods
  • View Model
    • Responsible for UI logic and data for the view.
    • Provides a layer of abstraction between the view and the application domain or model
    • Can play the role of an adapter between the view and the model when required
    • Can expose ICommand properties that view Command properties can data bind to
      • Note: behaviors can also data bind to an ICommand property
    • Can expose public methods that view behaviors can invoke
    • Maintains state for the view. State changes are communicated to the view via data bindings.
    • Implements change notification for properties and collections


Collaborations

The view model is the view’s DataContext.

Consequences

The MVVM pattern has the following benefits and liabilities:

  1. Promotes separation of concerns. The MVVM pattern helps you keep a clean separation of concerns by moving UI logic from a view code-behind to a separate view model class. The result is components that are loosely coupled and can be modified in isolation making the application easier to evolve and maintain over time.
  2. Enables the developer-designer workflow. Developers can now be less territorial with their views because changes in the XAML won’t break the UI logic in the view model. Designers are liberated to be expressive and creative as they use tools like Expression Blend to create modern interactive applications without worrying about breaking the view when they make changes to it.
  3. Improves testability. By moving UI logic to a separate class that UI logic can test tested in isolation. The unit tests execute much faster because UI Automation is not required, which can motivate developers to write more tests and run the tests more often.
  4. View models without empty a constructor cannot be instantiated in XAML. Most view models take arguments in their constructor; these represent the view model’s dependencies. View models without a default empty constructor cannot be instantiated in XAML; which requires an alternate wiring strategy.
  5. Requires wiring up the view and view model. Implementing the MVVM pattern requires additional work over using the view and corresponding code-behind. Developers need to instantiate a view model and assign it to the view DataContext property. Perhaps in the future, Microsoft will provide out-of-the-box strategies for wiring up views and view models.
  6. Enabling designer tooling can require d: designer properties. If the view has no design-time knowledge of the view model, the designer tooling will not be able to determine the shape of its DataContext; which neuters the data binding builder. In order to provide a design-time shape to the designer tooling, the developer or designer needs to set the d:DataContext or d:DesignSource properties to set a design-time DataContext.


Implementation

Consider the following when implementing the MVVM pattern:

  1. Wiring strategies. Wiring strategy refers to a technique for connecting the view and view model at run-time. The selected wiring strategy is typically tied to the application’s strategy for dependency resolution; for example an IOC container, MEF or a Service Locator. Wiring strategies can be implemented in XAML, code-behind, IOC container extension, screen conductor or coordinator. How view model dependencies are resolved reflects on the available wiring strategy choices.
  2. Commands, behaviors or convention. There are several techniques for view controls to communicate UI gestures so that view mode code can be executed. Developers need to choose whether to expose public ICommand properties or public methods on their view models. The view controls can then data binding to the ICommand properties or can use behaviors to invoke methods on the view model. Additionally, a screen conductor or coordinator or IOC container extension can employ a convention technique to wire up the UI controls to their view model counterparts.
  3. Design-time Sample Data. Evaluate the various strategies for displaying sample data and determine the most appropriate technique. Design-time sample data can be surfaced on the UI using the d:DesignData markup extension, d:DesignInstance markup extension or can be emitted by the view model implementing a design-time repository that returns sample data dynamically created in code or loaded from a file. Not all views require sample data, for the ones that do, provide good rich sample data for your designer.
  4. Enable designer tooling. In order for the designer tooling to provide maximum benefit to both developers and designers, the tooling must be able to determine the shape of the DataContext. If the view has no design-time knowledge of the view model either through the view model being instantiated in XAML or through sample data being applied, the designer tooling will not be able to determine the shape of its DataContext; which neuters the data binding builder. In order to provide a design-time shape to the designer tooling, the developer or designer needs to use the d:DataContext or d:DesignSource properties to set a design-time DataContext.


Sample Code

The below XAML snippet shows wiring up the view model in XAML. Remember, view models wired up like this must have a default empty constructor.

<Window 
    xmlns:local="clr-namespace:Acme.MVVM"  
    x:Class="Acme.MVVM.MainWindow">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>

The below PublisherView shows how property injection can be used to wire up the view model.

public partial class PublisherView : UserControl {

    [Dependency]
    public PublisherViewModel ViewModel {
        get { return this.DataContext as PublisherViewModel; }
        set { this.DataContext = value; }
    }

    public PublisherView() {
        InitializeComponent();
    }
}

The below App class shows how a view model is added to a view during construction. This sample pattern can also be automated by authoring an IOC container extension to create the view and view model combination and wire them up as illustrated below.

public partial class App : Application {

    protected override void OnStartup(StartupEventArgs e) {
        IUnityContainer container = new UnityContainer();

        container.RegisterType<IDialogService, ModalDialogService>(
            new ContainerControlledLifetimeManager());
        
        container.RegisterType<IEventRepository, EventRepository>(
            new ContainerControlledLifetimeManager());

        MainWindow window = container.Resolve<MainWindow>();
        window.DataContext = container.Resolve<MainWindowViewModel>();
        window.Show();
    }
}

The below XAML snippet shows the view Button controls binding to properties on their DataContext. The C# code snippet shows the ICommand properties that the view is binding to.

<StackPanel Orientation="Horizontal" Grid.Row="5" Grid.ColumnSpan="2">
    <Button Content="New" Command="{Binding Path=NewCommand}" />
    <Button Content="Save" Command="{Binding Path=SaveCommand}" />
    <Button Content="Delete" Command="{Binding Path=DeleteCommand}" />
</StackPanel>

public ICommand DeleteCommand {
    get { return new RelayCommand(DeleteExecute, CanDeleteExecute); }
}

public ICommand SaveCommand {
    get { return new RelayCommand(SaveExecute, CanSaveExecute); }
}

public ICommand NewCommand {
    get { return new RelayCommand(NewExecute); }
}

Known Issues

There are numerous XAML applications around the world that use the MVVM pattern. This pattern is heavily promoted by the XAML platform community, Microsoft MVP’s and respected technology leaders.

Expression Blend and the Visual Studio 2010 Designer both use the MVVM pattern.

Related Patterns

The following links are from Martin Fowlers web site.

Comments (14)

  1. Very Happy Developer says:

    This kind of integrated training is a godsend.  Thanks so much for all of your hard work on this.

    Is a future In The Box training module for WCF RIA Services coming soon ?

  2. karl140.6 says:

    Thank you for your kind words.

    I don't think I'll have time to produce WCF RIA Services training.  Please send a message to Jeff Handley here:  jeffhandley.com/contact.aspx

    Have a great day,

    Karl

  3. Developer says:

    I've gone through your In The Box – MVVM Training and could clear almost all confusion regarding MVVM. Thank you for providing such an innovative training.

    I say almost all because of the following wishlist in 'MVVM Scenario' such as

    1. Screen Conductor and IOC (Unity) with configuration/convention

    2. Behaviors invoking view model public methods

    3. Behaviors data binding to an ICommand property (Silverlight 5 will allow built in support for command extensions  but final release is end of 2011)

    Since you have worked on the Prism 4 guidance project I'm just wondering, are you preparing an In The Box – Prism 4 Training? Please do … I eagerly anticipate

    Your Prism session at Dallas Day Dot Net is in March 2011 … way too long to wait

  4. karl140.6 says:

    Thank you for your comments.  The training was scoped specifically to MVVM, otherwise I would have never released it.  Your items 1, 2, & 3 are not specific to the MVVM pattern.

    Yes, in the blog post I mentioned I would be doing a Prism In the Box.

    Cheers,

    Karl

  5. Developer says:

    item 2,3 is not specific to MVVM pattern then why does it appear in this blog post under Participants subsection View and ViewModel respectively which is an extract from "The gold standard for learning and describing design patterns is the book, Design Patterns: Elements of Reusable Object-Oriented Software."

    I thought these were integral.

  6. karl140.6 says:

    Please reread the goals and nongoals section the in the training.  This covers what it is in scope and out of scope for the training material.

    Karl

  7. Andolasoft says:

    Thanks so much for all of your good work on this topic.

  8. T Rex says:

    Excellent job on the MVVM In-the-box add-in – an insane amount of work must have gone into it. I would be keen to purchase more modules if you are thinking of creating a commercial venture.

  9. karl140.6 says:

    Andolasoft & T Rex,

    Thank you both for your kind words.

    We are planning several more of these inside Microsoft.  Prism is next.  We have also added cool features like content searching, bookmarking and a much better experience for navigating code.

    Best to you,

    Karl

  10. Hi Karl,

    absolute cool Stuff. I'm a Devolper, tried to found a new way of devoloping MS WPF Desktop Applications for my Company (actually Delphi, but now licenced TS, VS Prof + MSDN, all perfect updated) , but not so experienced on VS. I learned and evaluated a lot of stuff last weeks. Actualy I favorisite Prism. In the search I found you exelent Tool "In the Box".

    I thought I'm at the end of my evaluation process. Fantastic Solution. I install your "In the Box". All works fine.

    But for the build of your examples I got this two Errors:

    MVVMTraining1Acme CommonAcme.PrismInteractionRequestConfirmationLocalModalInteractionDialog.xaml(38,26): error MC3074: Das Tag "Interaction.Triggers" ist im XML-Namespace "schemas.microsoft.com/…/interactivity" nicht vorhanden. Zeile 38 Position 26.

    MVVMTraining1Acme CommonAcme.PrismInteractionRequestNotificationLocalModalInteractionDialog.xaml(37,22): error MC3074: Das Tag "Interaction.Triggers" ist im XML-Namespace "schemas.microsoft.com/…/interactivity" nicht vorhanden. Zeile 37 Position 22.

    Maybe this is a trivial Error for you and your blog readers. But  I'm  in the phase of learning to found the best solution to start with developing. For that  I'm actually not familar to slolve the problem in VS.

    It woud be nice if you can help me (Sorry for bad english).

    Best Regards

    Reiner

  11. karl140.6 says:

    Reiner,

    Sorry you had a problem.

    Did you install the Blend SDK?

    http://www.microsoft.com/…/details.aspx

    This is required.

    Karl

  12. Gil Yoder says:

    Karl,

    I just finished your "In the Box" training and wanted to write and say "thanks" for making it available. I have been wanted to get started with WPF and learn its binding capabilities, but for some reason could not get my head around it all, especially when I tried to work out the binding aspects. Your MVVM training helped to open my eyes to it though, so I think I can start putting something together with it.

    I hope you put out more "In the Box" stuff. Having the training in Visual Studio is a great help.

    Gil

  13. Per Eklund says:

    "In the box" is one of the best training methods I have used! I would love to se more of this from you or someone else.

    –Per Eklund

  14. karl140.6 says:

    Gil & Per,

    Many thanks for your kind words.

    Best

    Karl