MVVMBlocks

MVVMBlocks is a light-weight framework that allows you to implement the Model-View-ViewModel framework into your Windows Store Applications.

MVVMBlocks is available as a NuGet package. If you want to add MVVMBlocks to an existing application, its recommended that you download the NuGet package and manually add MVVMBlocks to it.

You can visit the MVVMBlocks NuGet page by clicking here.

Very soon I will be creating a Visual Studio 2013 project template for MVVMBlocks that will remove the need to set up your application code to use MVVMBlocks.

Contents

There is a large amount of information contained in this page. These links will help you to quickly navigate to the section you are interested in.

What Does MVVMBlocks Provide?

  1. Pluggable IoC container support. Whilst MVVMBlocks is provided with a very simple IoC container, you can plug in your own container should you wish to. The container provided with MVVMBlocks will ‘auto-discover’ your View Models, removing the need to update the container code when a new ViewModel is added. As long as your View Models derive from ViewModelBase, they will be discovered.
  2. Messaging. MVVMBlocks provides a Message Bus, enabling message passing between ViewModels. If your ViewModel subscribes to a particular message, when the message is published, the ViewModel will receive the message.
  3. The ability to build in a ‘catch all’ default ViewModel which the framework will use should your ViewModel not be implemented.
  4. A navigation service, allowing easy navigation between views.
  5. MVVMBlocks is light-weight. It provides simple MVVM functionality, but will not get in the way of your development.

Getting Started with MVVMBlocks

This section explains how to add MVVMBlocks to a Visual Studio project or to your existing application.

Step 1 – Create the MVVM Folder Structure in your project

There are several folders you can add to your solution to keep a clean separation of the various MVVM components, e.g. Models, ViewModels, Messages, etc. A suggested folder structure within your project is as follows:

  1. Container – This folder will hold your desired IoC Container to use with MVVMBlocks, the demonstration solution uses a simple container called ExampleContainer.cs
  2. Messages – MVVMBlocks provides a messaging bus to allow messages to be passed between View Models. This folder holds all the message definitions used in your project.
  3. Model – This folder holds all of the Models associated with your project.
  4. ViewModel – This folder holds all of the ViewModels associated with your project.

When configured in Visual Studio, the folder structure within your project will look as follows:

MVVMBlocks Folder StructureStep 2 – Adding a Reference to MVVMBlocks Toolkit

There are two ways that this can be done, you can either manually add the reference to MVVMBlocks.dll or you can add MVVMBlocks by downloading the NuGet package, either way, you must have a reference to the MVVMBlocks.dll assembly within your project.

Step 3 – Making Changes to App.xaml and App.xaml.cs

There are additions that need to be made to these files for the Navigation Service, and also to wire up the ViewModelLocator, which as its named, enabled View Models associated with Views to be located.

App.xaml.cs NavigationService Additions

There are three additions that need to be made to this file, these are:

1. Add a using curnow.biz.MVVMBlocks.Navigation declaration, this looks as follows in the file:

App.xaml.cs
2. Just under the App class declaration, add public static NavigationService NavigationService; – this looks as follows:

app.xaml.cs
3. Within the OnLaunched method there is a code block that starts if(rootFrame==null), before the closing curly brace of the if statement, add the line App.NavigationService = new NavigationService(rootFrame); – this looks as follows:

app.xaml.csApp.xaml Changes

Within this file, we need to wire up the ViewModelLocator. This enables the Views to locate their associated View Models. As a minimum, the contents of your App.xaml file needs to be as follows:

App.xaml
You will see that two additional namespaces have been added, these are locator and container. locator points to the namespace curnow.biz.MVVMBlocks.Locator in the MVVMBlocks toolkit. This is the actual ViewModelLocator for MVVMBlocks. container points to the local container implementation responsible for returning concrete ViewModels. We next set up our ViewModelLocator with the local implementation of the container. This example assumes the use of ExampleContainer provided with the example solution.

<Application.Resources>
        <locator:ViewModelLocator x:Key="ViewModelLocator">
            <locator:ViewModelLocator.Container>
                <container:ExampleContainer DefaultViewModel="DefaultViewModel"/>
            </locator:ViewModelLocator.Container>
        </locator:ViewModelLocator>
</Application.Resources>

This is simply setting the Container property of the ViewModelLocator to point to ExampleContainer, and as we are using the Default View Model functionality (more below on this), we set the DefaultViewModel property to point to a default View Model. Please Note that you must set the correct namespace for the local container. In this example, the ExampleContainer class is contained in the namespace MVVMBlocksExample.Container.

The default view model functionality is a nice feature of MVVMBlocks and I’d recommend using it. If you reference a View Model in any of your Views and then do not create the View Model, when you run the application it will crash. Defining a default View Model means that the application will still run, but when the MVVMBlocks tries to locate the View Model, it won’t be able to find it and will use the default. In my applications I generally make the default View Model display a message to say that the desired View Model cannot be found and I have included this in the example solution.

With the above changes made to your solution, we are now able to start building Models, Views and ViewModels and the following sections will explain how to do this using a simple contact list example.

Models, Views and ViewModels

Now we have the MVVMBlocks ‘plumbing’ in place, its time to build a simple application. We are going to build a simple contact list which will hold a contacts Name, Email Address and Mobile Phone Number. Our model needs to reflect our contact data. When creating Models, you should store these in the Model folder in your solution. Our Model looks as follows:

using curnow.biz.MVVMBlocks.Model;

namespace MVVMBlocksExample.Model
{
    public class Contact : BaseModel
    {
        private string name;
        private string emailAddress;
        private string mobileNumber;

        public string Name
        {
            get { return name; }
            set 
            {
                name = value;
                RaisePropertyChanged("Name");
            }
        }

        public string EmailAddress
        {
            get { return emailAddress; }
            set
            {
                emailAddress = value;
                RaisePropertyChanged("EmailAddress");
            }
        }

        public string MobileNumber
        {
            get { return mobileNumber; }
            set
            {
                mobileNumber = value;
                RaisePropertyChanged("MobileNumber");
            }
        }
    }
}

In your Model class, you need to make sure you add the using to the curnow.biz.MVVMBlocks.Model namespace as the BaseModel class is contained here. All MVVMBlocks Models must inherit from BaseModel. You can see our model implements properties for all of the pieces of information we are going to hold for a single contact, each property setter executes the RaisePropertyChanged method (which is defined in the BaseModel class). This is all we have to do to create our simple Contact model.

The ViewModel

Next we will create our ViewModel. For this simple example, our View will be the MainPage.xaml in our solution, so we will call our ViewModel MainPageViewModel. ViewModels should be stored in the ViewModel folder in our solution. Our ViewModel looks as follows:

using MVVMBlocksExample.Model;

using curnow.biz.MVVMBlocks.ViewModel;
using curnow.biz.MVVMBlocks.Command;
using curnow.biz.MVVMBlocks.Messaging;

namespace MVVMBlocksExample.ViewModel
{
    public class MainPageViewModel : ViewModelBase
    {
        public ObservableCollection<Contact> Contacts
        {
            get;
            set;
        }

        public string pageTitle;
        public override string PageTitle
        {
            get
            {
                return "Contact List";
            }
            set
            {
                pageTitle = value;
            }
        }

        public MainPageViewModel()
        {
            GetContactList();
        }

        private void GetContactList()
        {
            ObservableCollection<Contact> c = new ObservableCollection<Contact>();

            c.Add(new Contact() { Name = "Phil Curnow", 
                                  EmailAddress = "philip@curnow.biz", 
                                  MobileNumber = "07977 123456" });
            c.Add(new Contact() { Name = "Fred Bloggs", 
                                  EmailAddress = "fred@bloggs.biz", 
                                  MobileNumber = "07443 123456" });

            Contacts = c;
        }

    }
}

The first using is the namespace where our Model resides, if you have used the default namespace for the solution, you will not need to include this. The next 3 usings are for MVVMBlocks. Initially we only need to include the curnow.biz.MVVMBlocks.ViewModel namespace as our ViewModel needs to inherit from ViewModelBase and its contained in this namespace. I have included the others for future examples on commands and message passing.

As our ViewModel inherits from ViewModelBase, it must include the following overridden property:

public string pageTitle;
public override string PageTitle
{
    get
    {
        return "Contact List";
    }
    set
    {
        pageTitle = value;
    }
}

This property holds a title that will be displayed by our View. In the example above the setter is really doing nothing, as the getter returns a hard coded page title.

Normally our application data source would be a database or web service, etc. For our simple example I am putting together some test data in the ViewModel, but in a real world application I would split this out into its own ‘layer’ and not implement this in the ViewModel. I have read several articles where programmers do implement this in their ViewModels, but my preference would be to move this code out of the ViewModel. Within the constructor, the GetContactList method is executed and data added to an ObservableCollection of type Contact. We have a property in our ViewModel called Contacts which is also an ObservableCollection and is used to pass our contact data to the View.

MVVMBlocks does support the concept of Design Time and Run Time. If you want to display some ‘canned’ data during design time and then data from your data source during run time, you could code the method as follows:

private void GetContactList()
{
    if(InDesignMode)
        ... set design time data ...
    else
        ... get run time data ....
}

The InDesignMode property functionality is part of the ViewModelBase class and returns true if your are within Blend or Visual Studio and false if the application is being executed.

The final piece of the jigsaw is the View. Our goal is to have no code behind our View, all data is passed via data binding. I am not going to include all of the View code here (you can view this in the accompanying Visual Studio Solution example), but I will show the important parts of the view that makes it aware of the ViewModel and how we bind the data we would like to display. Anybody who has developed an application using the Split App template will recognise most of the XAML in our View. For the solution we will ultimately produce through this tutorial, the Split App is ideal for our purposes and there is not point reinventing the wheel if there is code available that can be used.

The View

As already mentioned, we are going to try and avoid adding anything in the code behind our View, everything we do here will be done in the XAML markup.

The first thing we need to do is make our View aware of its associated ViewModel. We can do this by using the following binding:

x:Class="MVVMBlocksExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MVVMBlocksExample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid DataContext="{Binding Source={StaticResource ViewModelLocator}, 
          Path=[MainPageViewModel]}" 
          Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

The DataContext is used to make our View aware of its ViewModel. The MVVMBlocks ViewModelLocator is used (in association with our ExampleContainer) to derive the ViewModel MainPageViewModel.

In our example, we have a ListView that is displaying our contact data, so we need to make our ListView aware of the source for the contact data and also display the contact information. If you look at the snippet of code for defining the ListView below, the bold section of code shows how me make the ListView aware of the source of the contact data.

<ListView
            x:Name="contactsListView"
            AutomationProperties.AutomationId="ContactsListView"
            AutomationProperties.Name="Items"
            TabIndex="1"
            Grid.Row="1"
            Margin="-10,-10,0,0"
            Padding="120,0,0,60"
            ItemsSource="{Binding Contacts}"
            IsSwipeEnabled="False">

When we set up the ViewModel, we included the property Contacts which is an ObservableCollection, and in our simple ViewModel, data was added via the GetContactList method. We now need to be able to display the contact data within the ListView. In our ListView, we have set up an ItemTemplate that contains a StackPanel with three TextBlocks to display the Name, Email Address and Mobile Phone Number for a contact, this code is as follows (some property setting has been removed from the TextBlocks for clarity of code):

<StackPanel Grid.Column="1" Margin="10,0,0,0">
    <TextBlock Text="{Binding Name}" ..../>
    <TextBlock Text="{Binding EmailAddress}" ..../>
    <TextBlock Text="{Binding MobileNumber}" ..../>
</StackPanel>

If you remember when we implemented our Model, it contained three public properties Name, EmailAddress and MobileNumber. Think of the Model as a single contact and the ObservableCollection Contacts set up in the ViewModel as the complete contact list, a collection of Contact objects. In our stack panel we are referencing an individual contact to display their information.

To display the title, we are again simply using a TextBlock bound to the PageTitle property in our ViewModel, if you examine the XAML code in MainPage.xaml in the accompanying example solution, you will see the following:

<TextBlock x:Name="pageTitle" 
           Text="{Binding PageTitle}" 
           Style="{StaticResource 
           HeaderTextBlockStyle}" 
           Grid.Column="1"

Again, through binding to our ViewModel, we are able to obtain the page title defined in our ViewModel. Looking at the screenshot below, we can see our example application implementing MVVMBlocks running and displaying the contact list.

ViewExample

You can click here to download the Visual Studio 2013 solution that implements what we have covered above.

So whats Next?

Obviously there isn’t a large amount of functionality in this simple example, but it explains how to implement MVVM in your applications using MVVMBlocks. The next sections will focus on using multiple Views, ViewModels, page navigation and passing data between ViewModels (messaging).

Passing Data Between ViewModels

Passing data between ViewModels is a topic that is covered a lot in blog posts and forum questions. Almost all MVVM tool kits provide a mechanism to pass data between ViewModels, and MVVMBlocks is no different. Passing data is usually achieved by the implementation of whats commonly referred to as a Message Bus or Event Aggregator. A ViewModel that wants to receive data subscribes to a message type and a ViewModel that passes data ‘publishes’ or sends a message. All ViewModels that have subscribed to the specific message type will receive the message that contains the required data.

MVVMBlocks implements this functionality through its MessageBus, defined in the namespace curnow.biz.MVVMBlocks.Messaging. The message bus is an application wide message bus (implemented as a singleton) and contains the following methods:

  • public void Register<TEvent>(Action<TEvent> eventAction) – Used in a ViewModel to ‘subscribe’ to a specific message type TEvent.
  • public void Raise<TEvent>(TEvent ev) – Used to ‘publish’ or send a message to any subscribers of the message type TEvent.

So how do we use this? We are going to extend our original example to add a new View and ViewModel that will allow the contact details to be edited. For simplicity the second View will be implemented as a user control. Our first view will incorporate a button called Edit that will allow the contacts details to be edited. This view will also ‘publish’ a message to pass the selected contact object to views that have subscribed.

Our second view will subscribe to the message and when the message is received, populate a set of text boxes with the contacts data ready for editing. This example will also show how to use the CommandHandler (defined in the curnow.biz.MVVMBlocks.Command namespace).

MainPage View Edit Button

We first need to add a button to our UI defined in MainPage.xaml. This is done by adding the code

<Button x:Name="btnEdit" Content="Edit" 
        Command="{Binding EditCommand}" 
        CommandParameter="{Binding ElementName=contactsListView,Path=SelectedItem}" ... />

We are binding our button to the EditCommand property that will be defined in the MainPageViewModel, passing over the selected item from our contact list.

MainPageViewModel – Wiring up the button

In the MainPageViewModel, we need to wire up the button, this is done as follows:

  • We need to create the EditCommand property which is of type ICommand as follows:
private CommandHandler editCommand;
public ICommand EditCommand
{
    get { return editCommand; }
}
  • In the constructor for we will wire up the command to a method that defines the behaviour of the command:
public MainPageViewModel()
{
    editCommand = new CommandHandler(ExecuteEditCommand, 
                      new Func<object, bool>((object parm) =>
                      {
                          return true;
                      }));

    GetContactList();
}
  • Finally, we define the ExecuteEditCommand method:
private void ExecuteEditCommand(object param)
{
    Contact c = param as Contact;
    MessageBus.Instance.Raise<Contact>(c);
}

As we defined in our button definition the CommandParameter is a selected item from the contacts list, we need to cast the parameter passed in to the method to the type Contact. We now need to make our ViewModel ‘publish’ or raise a message to any ViewModel ‘listening’ for our message type. We could define a custom message type and pass over whatever data we like, but for this example, it seems sensible just to pass over the contact object, so this will be our message type. We then pass our recast method parameter, which contains our selected contact:

MessageBus.Instance.Raise<Contact>(c);

Subscribing or Listening for Messages

This is all we have to do to the MainPage and MainPageViewModel. Our second View and ViewModel is called EditContactsView.xaml and EditContactsViewModel.cs in the accompanying example. I am not going to cover how this is put together, as its exactly the same as already discussed for Views and ViewModels, I will however show the important parts of the View and ViewModel.

EditContactsView

<Grid DataContext="{Binding Source={StaticResource ViewModelLocator}, 
      Path=[EditContactsViewModel]}">
    <Grid DataContext="{Binding Contact}">
        <TextBlock HorizontalAlignment="Left" Text="Contact Name:" .../>
        <TextBox HorizontalAlignment="Left" Text="{Binding Name, Mode=TwoWay}" .../>
        <TextBlock HorizontalAlignment="Left" Text="Email Address:" .../>
        <TextBox HorizontalAlignment="Left" Text="{Binding EmailAddress, Mode=TwoWay}" .../>
        <TextBlock HorizontalAlignment="Left" Text="Mobile Number:" .../>
        <TextBox HorizontalAlignment="Left" Text="{Binding MobileNumber, Mode=TwoWay}" .../>
    </Grid>
</Grid>

You’ll recognise the bindings for wiring up the View to the associated ViewModel. We then have a further grid where the DataContext is set to a property called Contact which is defined in the ViewModel. The bindings for the text boxes are then set to the individual properties within the contact object

EditContactsViewModel

We first need to create a property called Contact which we mentioned above. This is simply:

private Contact contact;
public Contact Contact
{
    get { return contact; }
    set
    {
        contact = value;
        RaisePropertyChanged("Contact");
    }
}

We then need to subscribe or ‘listen’ for any messages of the type Contact. In the constructor for the ViewModel, we do the following:

public EditContactsViewModel()
{
    ....
    MessageBus.Instance.Register<Contact>(HandleMessage);
}

When a message is received, the HandleMessage method will be executed. Our implementation of the method is as follows:

private void HandleMessage(Contact c)
{
    Contact = c;
}

The method is expecting a parameter of our specified message type, which in this instance is Contact. We then simply set our Contact property (which again is of type Contact) to be the selected contact. You do not have to define a property on the ViewModel if you don’t require it, I have simply used this to make the binding to the text boxes in the view easier. The screenshot below shows the example running.

MessagePassing
That’s all there is to using the MVVMBlocks MessageBus and message passing between ViewModels. Your ViewModels can subscribe to and send as many message types as required.

You can click here to download the Visual Studio 2013 solution that implements the messaging we have covered above.

MVVMBlocks provides the facility to easily navigate between views (pages) and using the MessageBus, you can also pass data between the associated ViewModels.

View navigation is provided by the NavigationService defined in the curnow.biz.MVVMBlocks.Navigation namespace.

If you consider the message passing example above, but think of the EditContactView as a separate page, you would modify the ExecuteEditCommand in the MainPageViewModel as follows:

private void ExecuteEditCommand(object param)
{
    Contact c = param as Contact;
    MessageBus.Instance.Raise<Contact>(c);

    App.NavigationService.Navigate<EditContactView>(null);
}

The NavigationService contains the generic method Navigate<T>, where T is the type of the View you wish to navigate to. You can also pass parameters to the View should this be required, but its recommended that you use the MessageBus. As with the MessageBus, the NavigationService is application wide.

Advertisements

One thought on “MVVMBlocks

  1. Pingback: MVVMBlocks .NET MVVM Framework | Curnow.biz

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s