Building a Universal Application for Windows Phone 8.1 and Windows 8.1 with MVVM Light
In the previous article, we talked about the new Universal apps which can be created for Windows Phone 8.1 and Windows 8.1. This offers a nice way to structure your app in order to share as much code and other files (artwork, etc) as possible. It makes it easier than ever to create apps which target both the Windows Phone and the Windows RT devices like Surface.
The new concepts can be a little confusing and overwhelming at first, but practice will help a lot. In this article, we will see how a new Universal app can be created with MVVM Light support. That should be fun!
Creating the app and adding MVVM Light support
Let’s start by creating a new universal application:
- In Visual Studio 2013 Update 2, select the menu File, New Project.
- Expand Templates, Visual C#, Universal Apps (see screenshot below).
- This create 2 new applications (Windows Phone 8.1 and Windows 8.1) and one Shared node, as shown below.
- Right click on the References folder in the Windows 8.1 app, and select Manage Nuget Packages.
- Select the Online source for Nuget and search for MVVM Light.
- Select the package MVVM Light Libraries only. Alternatively you can select the package named MVVM Light Libraries Only (PCL). This will install the exact same binaries and eventually I will remove this package and keep only the main one.
- Repeat steps 4 to 6 for the Windows Phone 8.1 application.
At this point, you have added MVVM Light support to both your applications. Now we can add the files that will bring the full support for the ViewModel layer and the design support.
Figure 1: New Universal app template
Figure 2: Universal application project structure
Adding the viewmodel layer
The next step in this article is to add two files: the ViewModelLocator and the MainViewModel. As usual in MVVM Light, this step is not compulsory and you can use all the MVVM Light components without any additional constraint. But if you want full designer support, it’s probably a good idea to follow the guidance.
- Right click on the Shared node and select Add, New Folder. Name this folder ViewModel.
- Right click on the new ViewModel folder, select Add, New Item. Add a class and name it MainViewModel.cs.
- Modify the MainViewModel class to look like code segment 1 below. Of course you can add a bunch of new methods, observable properties and commands to this ViewModel as usual in MVVM.
- Right click on the new ViewModel folder again and select Add, New Item. Select a Class, and name it ViewModelLocator.cs.
- Modify the ViewModelLocator code to look like in the code segment 2 below.
- Open the App.xaml file in Visual Studio and modify it to look like code segment 3 below. This creates a new resource with the ViewModelLocator, which we will use in the designer. Notice the addition of the “d” and “mc” XML namespaces so that we can mark the ViewModelLocator as a DataSource, which will make it show up in the Data panel in Blend.
public class MainViewModel : ViewModelBase { private string _helloWorld; public string HelloWorld { get { return _helloWorld; } set { Set(() => HelloWorld, ref _helloWorld, value); } } public MainViewModel() { HelloWorld = IsInDesignMode ? "Runs in design mode" : "Runs in runtime mode"; } }
Code segment 1: MainViewModel class
public class ViewModelLocator { public MainViewModel Main { get { return ServiceLocator.Current.GetInstance<MainViewModel>(); } } static ViewModelLocator() { ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); SimpleIoc.Default.Register<MainViewModel>(); } }
Code segment 2: ViewModelLocator class
<Application x:Class="App2.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App2" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:vm="using:App2.ViewModel"> <Application.Resources> <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" /> </Application.Resources> </Application>
Code segment 3: App.xaml with Locator resource
Wiring the DataContext
Blend is always my preferred tool for this kind of things. It is just so easy! Follow the steps:
- Build the application.
- Right click on the MainPage.xaml (either in the Windows Phone or in the Windows app) and select Open in Blend.
- In Blend, select the Data panel on the far right.
- Expand the Project node. You should see the ViewModelLocator. If you expand it, you will see the MainViewModel (property named “Main”).
- Grab the Main property in the ViewModelLocator and drag it all the way to the Objects and Timeline panel on the left. Drop it on the Page node in Objects and Timeline. This will set the DataContext of the Page to the MainViewModel.
- Back in the DataPanel, expand the Main node.
- Grab the HelloWorld property and drag it on the Page’s surface in the designer area. Because this property is of type string, this will automatically add a new TextBlock and set a Binding on its Text property. On the designer surface, you should now see “Runs in design mode”, which is the text that we set in the MainViewModel for design time.
- Now open the other MainPage.xaml. If you had started in the Windows Phone app, do that for the Windows 8 app now.
- Repeat steps 3 to 7 for this page.
- Back in Visual Studio, right click on the phone app and select “Set as Startup”.
- Run the application. This will start the Windows Phone version of the app. You should see the text “Runs in runtime mode”.
- Go back in Visual Studio and this time set the Windows 8.1 app as startup. Run it, and you will see the same result, but this time in Windows 8.1.
Of course you can also set your page up in XAML directly, as usual.
Conclusion
In this article, we saw how to create a new Universal app for Windows Phone 8.1 and Windows 8.1 with MVVM Light support. We also saw how to create a shared viewmodel layer (admittedly a simple one), how to detect design mode and what the result is in Blend and at runtime. This should get you started with universal apps, and hopefully make the previous article clearer with a practical example.
Upcoming features
While I was able to add Nuget support quite fast, there are still a few things I need to do to offer full MVVM Light support to the new application framework. Here are a few things I have on my mind:
- Updating the “MVVM Light” package in Nuget. This is the package that installs a ViewModelLocator and a MainViewModel file in addition to the libraries, and which modifies the App.xaml to “wire” the ViewModelLocator for easy usage in Blend.
- Creating new project templates for the new application frameworks
- Windows Phone 8.1
- Universal apps
Once this is done, this will be full support for the new Windows Phone and universal apps.
Please test the new features as described in this article and the previous one, and let me know if you have feedback.
Happy coding
Laurent