March 2013

Volume 28 Number 03

Windows Store Apps - Windows Store Apps: A Guide for WPF and Silverlight Developers, Part 2

By Joel Fjordén | March 2013

Read Part 1 of this article.

This is my second article for Windows Presentation Foundation (WPF) and Silverlight developers who want to start creating Windows Store apps without compromising on architecture. I assume you’ve read Part 1; this article continues where that one left off and is a lot more practical than the first.

The bulk of this article consists of two tutorials: one for setting up a new project using the Model-View-ViewModel (MVVM) pattern and one for using MVVM navigation. Before getting to the tutorials, however, I want to briefly review some of the key concepts of the MVVM pattern. To get the most out of this article, you should have some knowledge of the MVVM pattern. (Those of you familiar with MVVM can skip right to the tutorials.) If you want to know about MVVM in more detail than what I provide, you can easily find a wealth of information on the Web.

MVVM is a common and popular pattern used in developing apps for WPF/Silverlight, Windows Phone 7 and Windows Store. The MVVM pattern is all about cleanly separating the view, its logic and the model in order to create an architecture that is maintainable, scalable and testable. The following sections describe the various components of MVVM.

View

The View is a graphical presentation of the ViewModel. The ViewModel should be as general as possible so that you can easily interchange different Views. The View can be anything graphical, from a window, user control or page to a simple DataTemplate that presents the ViewModels bound to an ItemsControl, such as a ListBox or a ComboBox.

In pure MVVM, the View’s code-behind file shouldn’t contain any logic other than in its markup (for example, triggers and visual state changes). In some scenarios, however, such as when closing a window, putting view-specific logic in the ViewModel isn’t possible or is cumbersome. In such cases, I think it’s okay to put code in the View—as long as it isn’t vital to test or reuse.

ViewModel

The ViewModel is the glue that holds the View and the Model together; it’s also the only entity allowed to communicate with both of them. The ViewModel often wraps or projects some of the information from the Model, but it also contains view-specific logic that doesn’t belong in the Model, such as an IsSelected property.

There is often a one-to-one relationship between a specific View and its ViewModel, and the ViewModel is preferably set as the DataContext for the whole View. You can pair a View with its ViewModel manually, but some MVVM frameworks connect them for you by using some kind of inversion of control (IoC) container.

In most cases, the View communicates with the ViewModel through bindings to properties and commands. These bindings can be either a one-way communication from the ViewModel to the View or a two-way communication in which data received in the View is also propagated down to the ViewModel. The ViewModel often communicates directly with the Model through methods, properties or events.

A ViewModel reduces the need for explicit binding converters. The conversion can often be made directly within the ViewModel before returning the value from a property.

Model

The Model can be any form of data that is presented in a View. The data can be any domain, business or entity object and can include everything that can be retrieved from the available services or framework APIs. Figure 1 illustrates the MVVM pattern.

MVVM Pattern
Figure 1 MVVM pattern

Commands

Commands are framework-specific representations of what is to be done rather than when something is to be done (as with an event). Commands such as Open, Save, Cut, Copy or Paste can then be data bound from the ViewModel to the View.  A command in Windows Runtime implements the ICommand interface, in which the two important methods are Execute and CanExecute, both accepting an object as an argument. The CanExecute method is queried by the framework and returns a Boolean value that indicates whether the command can currently be executed. The normal behavior for a control that supports commands, such as a button or a menu item, is to disable itself when CanExecute returns false. The Execute method is then invoked when the control is clicked, or tapped, provided that the CanExecute method returns true (that is, the control is enabled).

When a new command is needed, instead of being required to create a new class implementing ICommand, many MVVM frameworks provide something most often called a DelegateCommand or a RelayCommand. This class often exists in both generic and nongeneric versions. The class accepts two delegates, one for the Execute method and one for the CanExecute method. With this class, you don’t have to create new command classes; instead, you can declare the new commands inline using the convenient syntax of lambda expressions.

Property Change Notification

Because a View is data bound directly to properties in a ViewModel, you often need to implement the INotifyPropertyChanged interface to notify the View that a specific property has changed.

MVVM frameworks often provide a base class for the ViewModel that implements this interface. In addition to providing the method that raises the PropertyChanged event in the form of a string, MVVM frameworks typically also provide some overloaded methods that take the property as a lambda expression, making the call refactoring safe. The CallerMemberNameAttribute introduced in .NET 4.5 most often removes the need for an explicit property reference because the compiler injects the calling property for you, also making the code refactoring safe.

In addition to the methods that raise the PropertyChanged event, convenient methods (for example, SetProperty) that set the new property value if different and also raise the event in the same call are also available.

Frameworks

After evaluating the current frameworks that support Windows Runtime, I can recommend the following.

Okra App Framework

The Okra App Framework is my favorite. So far, it has been the backbone of all my MVVM projects for Windows Store apps. It simplifies virtualized access to data and allows an easy application of the MVVM pattern. By default, the Okra App Framework utilizes the Managed Extensibility Framework (MEF) for View and ViewModel association, through export attributes, which I really like. Discovering and injecting services using the standard MEF attributes for import and export is straightforward. The Okra App Framework also contains common MVVM classes such as DelegateCommand and a base class implementation of INotifyPropertyChanged, called NotifyPropertyChangedBase. This base class supports property changed notification using either a refactoring safe lambda expression or the new CallerMemberNameAttribute that automatically generates the calling member to code.

The Okra App Framework also supports and simplifies navigation as well as lifetime management. It makes handling serialization and deserialization of an app’s state and data when the application is activated, suspended or resumed easy and straightforward. The framework also provides support for adding custom settings pages for an app to the standard settings pane. It manages navigation among these custom pages in the same MVVM-friendly style as with in-app navigation. Navigation events for the settings pages and events for when the settings pane is presented are also part of the framework.

Work is also in progress for Windows Phone 8 support so that sharing code between Windows Store app projects and Windows Phone 8 projects will be easier. Until the Okra App Framework is officially released for Windows Phone 8, there is a Windows Phone 8 fork that I have published on the project’s web site. I can’t guarantee the full functionality or quality of this fork. Feel free to contribute improvements and fix bugs if you find any.

Fody

Fody with the PropertyChanged add-in (formerly NotifyPropertyWeaver) is an optional tool that uses IL weaving to inject INotifyPropertyChanged code into properties. It eliminates the need for explicit and repetitive calls for notification of property changes. (Neither of the tutorials uses this tool.)

Callisto

 Callisto is an open source project containing some extensions, helper functions, converters and controls that can be helpful when you’re designing a Windows Store app with a consistent new Windows UI. I find controls such as Menu, Flyout, SettingsFlyout and WatermarkTextBox useful in my own projects.

WinRT XAML Toolkit

I haven’t yet used the WinRT XAML Toolkit in any of my projects, but from what I’ve seen it looks promising. It has a unique set of controls, extensions and helper functions.

Tutorial for Setting Up a New MVVM Project

My goal with this tutorial is to set up a new Windows Store project that uses the MVVM pattern. To simplify the View and ViewModel association, I rely on the Okra App Framework. I can use any IoC container I want in the Okra App Framework, and as I mentioned earlier, the framework also has built-in support for MEF. The only thing I have to do so that the View knows about the ViewModel is to add specific export attributes.

I start by creating a new blank Windows Store app project in Visual Studio 2012, as shown in Figure 2. I would have used one of the other templates, such as Grid App or Split App, if it had been a better fit for my application.

Creating a new Blank App for Windows Store
Figure 2 Creating a new Blank App for Windows Store

I then add Views and ViewModels folders to my project. After that, I remove the MainPage.xaml file from the root of my project and add a new Basic Page, named MainView, to my Views folder, as shown in Figure 3.

Adding a new Basic Page as the MainView to the Views folder
Figure 3 Adding a new Basic Page as the MainView to the Views folder

If the message in Figure 4 shows up, asking whether or not to add the missing files automatically, I select Yes.

Message asking whether to add dependent template files
Figure 4 Message asking whether to add dependent template files

I then add a new class, MainViewModel, to the ViewModels folder. After that, I install the Okra App Framework as a NuGet package by choosing Manage NuGet Packages from the Project menu, as shown in Figure 5.

Installing the Okra App Framework as a NuGet package
Figure 5 Installing the Okra App Framework as a NuGet package

My project now contains all the Views, ViewModels and References I need (so far). Figure 6 shows the current project structure in Solution Explorer.

Project structure in Solution Explorer
Figure 6 Project structure in Solution Explorer

Next I add the ViewModelExport attribute from the Okra App Framework to the MainViewModel class, using the Home constant as a special export name.

[ViewModelExport(SpecialPageNames.Home)]
public classMainViewModel : ViewModelBase

I do the same thing for the MainView class, but instead using the PageExport attribute from the Okra App Framework.

[PageExport(SpecialPageNames.Home)]
public sealed partial class MainView : LayoutAwarePage

I then add a new folder, Utilities, to my project. After that, I add a new class named AppBootstrapper, which inherits OkraBootstrapper, to the Utilities folder.

public class AppBootstrapper : OkraBootstrapper

Then I remove everything within the App.xaml.cs file except the constructor that creates and initializes the bootstrapper I just added.

public App()
{
  this.InitializeComponent();
  AppBootstrapper appBootstrapper = new AppBootstrapper();
  appBootstrapper.Initialize();
}

Everything should now be set up correctly for building and running the project. The MainView should present itself upon execution, correctly instantiating and associating the MainViewModel with the DataContext of the MainView.

Tutorial for Using MVVM Navigation

My goal with this tutorial is to introduce navigation between views from the MVVM perspective. This tutorial continues where the previous one ended. The Okra App Framework simplifies navigation by handling the View-ViewModel instantiation and association. It also manages the navigation stack and gives easy access to back and forward navigation as well as to events for those scenarios. A NavigationCommands class contains some common navigation commands that can be exposed from a ViewModel and then used by a View.

I start by adding an auto-implemented property of type ICommand ShowAnotherViewCommand,  to the MainViewModel class.

public ICommand ShowAnotherViewCommand { get; private set; }

I then add a private method, ShowAnotherView, to the MainViewModel class. After that, I initialize the ShowAnotherViewCommand in the MainViewModel constructor, with a new instance of the DelegateCommand passing in a reference to ShowAnotherView.

ShowAnotherViewCommand = new DelegateCommand(() => ShowAnotherView());

Next I add a Button to the MainView and bind its Command property to the ShowAnotherViewCommand property of the MainViewModel. This works because the bootstrapper will correctly initialize the DataContext of the View with the correct ViewModel, utilizing MEF and the previously specified export attributes.

<Button Content="Another Screen" 
              Command="{BindingShowAnotherViewCommand}" />

Now I add a new Basic Page called AnotherView to the Views folder, as shown in Figure 7.

Adding a new Basic Page as AnotherView to the Views folder
Figure 7 Adding a new Basic Page as AnotherView to the Views folder

I then change the Title of the AnotherView page to display “Another View” instead of the application name. After that, I add a new class, AnotherViewModel, to the ViewModels folder. I also need to add the ViewModelExport attribute from the Okra App Framework to the AnotherViewModel class by using either a string constant or a Type (for example, the type of the AnotherViewModel class).

[ViewModelExport(typeof(AnotherViewModel))]
public class AnotherViewModel

Now I do the same for the AnotherView class, instead using the PageExport attribute from the Okra App Framework together with the type of the AnotherViewModel class as a reference.

[PageExport(typeof(AnotherViewModel))]
public sealed partial class AnotherView : LayoutAwarePage

I then add a property of type INavigationManager, from the Okra App Framework, with an Import attribute instructing MEF to inject the dependency when creating an instance of this ViewModel. You could replace the property with a constructor parameter of type INavigationManager, but you would then have to add the ImportingConstructor attribute from MEF to the constructor.

[Import]
public INavigationManager NavigationManager { get; set; }

Next I need to add logic to the ShowAnotherView method for navigating to the AnotherView page using the previously imported navigation manager.

private voidShowAnotherView()
{
  NavigationManager.NavigateTo(typeof(AnotherViewModel));
}

Everything should now be set up correctly for building and running the project. The AnotherView should present itself when the button in the MainView is clicked.

I now refactor the code, first by creating a base class for the ViewModels, called ViewModelBase, and making sure that both MainViewModel and AnotherViewModel inherit from this new base class. It’s a good idea to let the ViewModelBase class inherit from NotifyPropertyChangedBase, from the Okra App Framework, later on to be able to notify bindings of changes in property values. The PropertyChanged Fody add-in could also be used here.

I start by moving the imported navigation manager property from the MainViewModel into the ViewModelBase class. I then add an auto-implemented property, GoBackCommand, of type ICommand, to the ViewModelBase class.

public ICommand GoBackCommand { get; private set; }

Now I initialize the GoBackCommand in the ViewModelBase constructor, with a new instance of the DelegateCommand passing in a reference to GoBack for the Execute action and CanGoBack for the CanExecute action. Both members are located in the imported navigation manager.

GoBackCommand = new DelegateCommand(() => NavigationManager.GoBack(), 
    () => NavigationManager.CanGoBack);

I then update the existing “backButton” element in MainView and AnotherView by replacing the binding for IsEnabled with a binding for the Command property of Button to the GoBackCommand in the inherited ViewModelBase class. I also remove the Click attribute, registering an event handler with the event.

<Button x:Name="backButton" Command="{Binding GoBackCommand}" 
                Style="{StaticResource BackButtonStyle}"/>

Once again, everything should be set up correctly for building and running the project. The back button should now be available only when back navigation is possible, and navigating back from AnotherView should now show the MainView.

Conclusion

Many different frameworks support the development of Windows Store apps in numerous ways. My recommendations in this article are based on my personal preferences for the Windows Store apps I’ve developed so far. The pure MVVM frameworks vary in size and complexity. As I mentioned earlier, I favor the Okra App Framework because of its simplicity and because it was built from the ground up with Windows Store app development in mind. The Okra App Framework will also make sharing code, especially ViewModels, easier when the expected version for Windows Phone 8 is released.

I hope the two tutorials I’ve provided in this article have shown you how easy it is to use existing MVVM frameworks to jump-start your Windows Store app development.

Read Part 1 of this article


Joel Fjordénworks as a senior .NET developer and architect forCenito Software*in Malmö, Sweden. His area of expertise is application development targeting WPF/Silverlight, Windows Phone 7 and recently Windows 8 in the form ofWindows Store apps. Joel currently works mainly as a developer, but he is also involved as a mentor, an architect and an instructor in various .NET-related courses.

Thanks to the following technical experts for reviewing this article: Karl Erickson has been involved in XAML developer education for the past six years, working with WPF, Silverlight, Windows Phone and Windows 8. His most recent project is the Reversi XAML/C# sample board game app.