(WPFS) MVVM Light Toolkit: Soup To Nuts Part I

While I’m not a zealot on the topic, I do believe that MVVM offers one of the bestBreakthrough! patterns for Windows Phone development and so,   moving forward, the Windows Phone From Scratch series will incorporate MVVM in general, and the MVVM Light Toolkit in particular.

I’m more than convinced that MVVM is an essential pattern for Windows Phone Development; and while there are many excellent frameworks to make MVVM development easier, the one I personally prefer to work with is the MVVM Light Toolkit and so it is the one I’ll focus on.

I make the case for MVVM in this article, and so I won’t rehash that material here.   Instructions for installing MVVM Light Toolkit are available here

I will not assume any background with MVVM or with the Toolkit beyond those two links.  That is, I’ll assume you’ve loaded the toolkit and created your very first, single page MVVM application, but not more than that.

In that spirit, let’s begin by creating a two page MVVM application.  This immediately forces us to talk some issues I’ve not found in other introductory tutorials, and will, in the next tutorial bring up even more interesting topics, such as behaviors and messages(!)

Creating the Application

To begin,  open Visual Studio and click on New Project.  In Installed Templates select MVVMLight(WP7), and make sure that you see the option for MvvmLight (WP7). If not, please refer to the resources above to fix your installation.

Select MvvmLight and name the project MvvmLightNavigationBehaviorAndMessages. Run the application before touching the code, you’ll find that the application name and page name have been set for you and that there is a text block proclaiming “Welcome to MVVM Light” (!)  This is Laurent’s way of helping ensure that all is working well.

Linking the View and Its View-Model

Look in MainViewModel.cs and you’ll find three string properties: ApplicationTitle, PageName and WelcomeThese serve as properties to bind to on MainPage.xaml,

<StackPanel x:Name="TitlePanel"
            Grid.Row="0"
            Margin="24,24,0,12">
    <TextBlock x:Name="ApplicationTitle"
               Text="{Binding ApplicationTitle}"
               Style="{StaticResource PhoneTextNormalStyle}" />
    <TextBlock x:Name="PageTitle"
               Text="{Binding PageName}"
               Margin="-3,-8,0,0"
               Style="{StaticResource PhoneTextTitle1Style}" />
</StackPanel>

<Grid x:Name="ContentGrid"
      Grid.Row="1">

    <TextBlock Text="{Binding Welcome}"
               Style="{StaticResource PhoneTextNormalStyle}"
               HorizontalAlignment="Center"
               VerticalAlignment="Center"
               FontSize="40" />
</Grid>

All that is necessary is for MainPage to set MainViewModel to be its DataContext, which is accomplished on the 17th line of the file (at the end of the opening tag for the PhoneApplication page)

<phone:PhoneApplicationPage x:Class="MvvmLightNavigationBehaviorAndMessages.MainPage"
                            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                            xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
                            xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
                            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                            FontFamily="{StaticResource PhoneFontFamilyNormal}"
                            FontSize="{StaticResource PhoneFontSizeNormal}"
                            Foreground="{StaticResource PhoneForegroundBrush}"
                            SupportedOrientations="Portrait"
                            Orientation="Portrait"
                            mc:Ignorable="d"
                            d:DesignWidth="480"
                            d:DesignHeight="768"
                            shell:SystemTray.IsVisible="True"
                            DataContext="{Binding Main, Source={StaticResource Locator}}">

Notice that this does not set the data context directly, but rather uses the StaticResource Locator

ViewModelLocator

It is worth diving into how this works, as the ViewModelLocator is central to the MVVM Light Toolkit.  This is one very good way, though not the only way, that you can set up the relationship between a view (MainPage) and its view model (MainViewModel) 

The static resource Locator is defined in App.xaml  

 <Application.Resources>
     <vm:ViewModelLocator x:Key="Locator"
                          d:IsDataSource="True" />
 </Application.Resources>

Finally, in the ViewModelLocator.cs file (created in the ViewModel folder when you created the application) you’ll find that the ViewModelLocator constructor calls CreateMain() which in turn sets the static property _main which is of type MainViewModel. 

The net effect is to link  (silently and without your intervention) MainPage to its view-model. 

When it is time to add a second page, as you’ll soon see, you have a bit of work to do, but it is all spelled out for you and there are code-snippets that make the work trivial.  Or nearly so.

Adding A Second Page

Let’s go most tutorials on MVVM Light one step further, and actually create that second page, and wire it up (I’m not sure that no other tutorial has done this yet, but I was hard-pressed to find one that did).

First, right-click on the project and create a new folder named Views.  Then  right click on Views and click on Add->New Item.  Select MVVM Page (WP7) and name the new page Page2.xaml. 

Hey! Page 2 is identical to MainPage.  That is because the bindings are the same and if you look closely you’ll see that it was “born” with the datacontext set to main.  Let’s fix that. 

Create a View-Model page for Page 2 named Page2ViewModel in the ViewModel folder (of type MvvmViewModel (WP7) ). 

Add the following public properties to the new View Model file:

 public string ApplicationTitle
 {
    get
    {
       return "MVVM LIGHT";
    }
 }

 public string PageName
 {
    get
    {
       return "Page 2";
    }
 }

 public string Welcome
 {
    get
    {
       return "Welcome to Page 2";
    }
 }

 

Now let’s connect them up.  Start by changing the name in the Datacontext in the view from Main to Page2ViewModel

Using the Code Snippets

Next, open the ViewModelLocator.cs file and scroll down to just below the constructor.  Here you can add most of the necessary code by using the mvvmlocatorproperty snippet.  Just type in the word and hit tab.  Overwrite with the name of the new type and the name of the local instance (in this case Page2ViewModel and _page2ViewModel.   Nearly all the code you need is created for you. Just add CreatePage2ViewModel() to the constructor.

Return to Page2.xaml and note that the page now reflects the new properties in the View Model. 

Next Step: Navigation with Behaviors and Messaging

What remains is to add a button on the first page that will cause a navigation to page 2.  This can certainly done in code-behind, but there is a better way: using behaviors and messages.  We’ll take that up in the next mini-tutorial.

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in Patterns & Skills. Bookmark the permalink.

32 Responses to (WPFS) MVVM Light Toolkit: Soup To Nuts Part I

  1.   11月12日《中国青年报》报道了安徽黄山市国税局,花60多万买茶叶的“杯中”奇观。60多万的茶叶想来一定让人津下生香,不过,那是过去,现在黄 现货茶叶 山市国税局恐怕是要流汗脊背了。  新闻中说:一份公开转让说明书泄露惊天秘密,黄山市国税局今年1到7月花费61.99万成为黄山六百里猴魁茶业股份有限公司的主要客户。黄山市国税局回应称,购茶的相关数据,涉事公司并未与他们沟通过,他们认为“严重失实”。  是“百里猴魁”数据造假,还是国税局“好茶”不怕开水烫?  这份公开说明书,其实是“新三板”的申报稿。很多人不太明白“新三板”是个啥意思,极简言之,“新三板”是主要针对中小企业的,一个全国性的非上市股份有限公

  2. c says:

    your page is out of date compared to what appears in mvvm light as of today.
    Your very first code does not appear in MainViewModel.cs. Those three properties, whatever. Consider updating this or pulling it until then.

  3. mcalex says:

    public string ApplicationTitle
    { get
    { return “MVVM LIGHT”; }
    }
    … etc
    in the ViewModel???

    Shouldn’t there be a Page2DataItem holding the model information?

  4. Gustavo says:

    After following all the steps it worked. When I tried to create a third page it didn’t and now I’m trying to start from scratch and not working 🙁

  5. Rod Falanga says:

    Addendum: First of all, we’re trying to do what you’ve done here, but in a WPF project instead of a WP7 project.

    We’ve got another question. In the traditional MVVM pattern, each view has it’s own view-model, containing the “code-behind” for that view. After completing your tutorial, clicking the button takes us to page 2, which fires off the relay command, which fires off the MessageBox, but the code-behind is all in the view-model for the main page. So, what are we missing?

  6. Rod Falanga says:

    “Type in the word”? What do you mean? When I type in “mvvmlocatorproperty” and press tab, all I get is: MvvmLightNavigationBehaviorAndMessages. I don’t get any code snippet doing anything for me. Perhaps I don’t have code snippets enabled? I don’t know, as I’ve never used them before.

  7. Diego vin says:

    “Hey! Page 2 is identical to MainPage. That is because the bindings are the same and if you look closely you’ll see that it was “born” with the datacontext set to main. Let’s fix that. ”

    I have recently downloaded the mmvlight v3 and whenever I create a new mvvmView, the new file is not like the main. In addition, the text properties are already set with the WP default text…

    Any ideias?

    • Zain says:

      I had the same problem. I looks like they’ve removed the MVVM Page template from the MVVM light installation and replaced it with just a MVVM View template.

      To match the original MVVM Page template you’ll want to copy and paste the grid from Main.xaml into page 2 (replacing the previous grid there) and change hte Page2.xaml databinding at line 17 to Main

  8. Ed S says:

    Holy boilerplate code… yuck, I’ll stick to non-ui work…

  9. Andre van der Plas says:

    Hi Jesse,

    I would like to give a suggestion about when to initialize the viewmodellocator.
    When you add it as an application resource by inserting the xaml:

    Then the viewmodel is initialized before the Application_Launching method is executed.
    Inside this method however, you normally would like to add code to initialize your model that you deserialize from isolated storage.
    The problem arises when constructors inside your viewmodel classes are trying to use the Model, which at that time isn’t initialized yet.

    Therefore I would like to suggest to postpone the addition of the ViewModelLocator to the resources after the model has been initialized and loaded.

    private void Application_Launching(object sender, LaunchingEventArgs e)
    {
    ToyBankModel.Load();
    Resources.Add(“Locator”, new ViewModelLocator()); // Now, the constructors of the viewmodels have access to a initialized model state
    }

    –Andre

    • Andre van der Plas says:

      As a remark on my own reply I would suggest to leave the resource where it resides in the App.xaml but only start creating the viewmodels after you have loaded the model from isolated storage:

      private void Application_Launching(object sender, LaunchingEventArgs e)
      {
      ToyBankModel.Load();
      ViewModelLocator.CreateViewModels(); // create the viewmodels after the model has been loaded
      }

  10. Michael says:

    This walk through of MVVM Light is GOLD! Thanks Jesse

  11. steven says:

    @Richie Scott
    you need to add the itemtemplates to the template location in visual studio as you did with the project templates…

  12. Dave says:

    Good Article – Is there a part two? If so please would someone indicate such.

  13. @Matthias
    Yes, you are supposed to combine the cleanup methods.

  14. Matthias says:

    A quick note: In the version of MVVMLite I’m learning on, for the mvvmlocatorproperty, in addition to “Page2ViewModel” and “_page2ViewModel”, I had to type Page2ViewModel one more time in order to get the “CreatePage2ViewModel” method.

    The other problem I’m having is that the mvvmlocatorproperty snippet adds a “Cleanup()” method for each property, which of course throws a “Type [etc] already defines a member called “Cleanup” w/ the same parameter types” error.

    I *think* I’m supposed to add the “ClearPage2ViewModel()” to the single “Cleanup” method, but I would love it if that were spelled out for me.

  15. nhwilly says:

    Finally, someone taking it step by step for us beginners.

    Really hoping to see the next step very soon.

    Great stuff and thanks from Indy.

  16. Richie Scott says:

    When adding a new page or a new viewmodel I don’t see the items MVVM Page (WP7) or MvvmViewModel (WP7).

    Any ideas? Everything else (templates and snippets) work fine.

    Thanks

  17. Matt Stroshane says:

    FYI: Under Using the Code Snippets, per:

    “Overwrite with the name of the new type and the name of the local instance (in this case Page2ViewModel and _page2ViewModel.”

    Just wanted to note that it appears you also need to overwrite the corresponding comment, replacing “ViewModelPropertyName” with “Page2ViewModel.” Otherwise there will be no CreatePage2ViewModel() -just a CreateViewModelPropertyName() method.

  18. Shoaib Shaikh says:

    Really helped understanding MVVMLight and Behaviors.

  19. Christopher Kellner says:

    Hey Jesse,
    please keep up your nice work! 🙂

    Greetings from Germany

  20. Joe Suchy says:

    Jesse,

    I also can’t wait for the next installment. Your piece of the “Firestarter” was great and now I’m hooked! Keep up the great work!

    Thanks and Happy New Year!

  21. @Bryon Barnard
    Byron, add it to the constructor for the Locator.

    • Gustavo says:

      Where is the constructor for the locator ? Also, what _main does ? I still don’t understand whats the purpose of the underscore. Thanks in advance.

  22. Bryon Barnard says:

    Jesse, you add “CreatePage2ViewModel()” to which constructor?

  23. Great write up Jessie. The only problem with reading part 1, is that I already want to go on to part 2 and it’s not out yet! I had the same problem watching 24. Much easier to wait for it to come out on DVD and watch it all at once. Maybe I’ll wait for your blog’s “boxed set” edition. 😉

    As always – keep up the great work!

Comments are closed.