The MVVM pattern – The practice

Let’s continue our journey to learn the MVVM pattern, applied to Universal Windows apps development. After we’ve learned the basic concepts in the previous post, now it’s time to start writing some code. As already mentioned in the previous post, we’re going to leverage MVVM Light as toolkit to help us implementing the pattern: since it’s the most flexible and simple to use, it will be easier to understand and apply the basic concepts we’ve learned so far.

The project

The goal of the MVVM pattern is to help developers to organize their code in a better way. As such, the first step is to define the structure of a project in a way that, also from a logical point of view, it can follow the principles of the pattern. Consequently, usually the first thing to do is to create a set of folders where to place our classes and files, like:

  • Models, where to store all our basic entities.
  • ViewModels, where to store the classes that will connect the Model with the View.
  • Views, where to store the Views, which are the XAML pages in case of a Universal Windows app.

In a typical MVVM project, however, you will end up to have more folders: one of the assets, one for the services, one for the helper classes, etc.

The second step is to install in the project the library we have chosen to help us implementing the pattern. In our case, we chose MVVM Light, so we can leverage NuGet to install it. We will find two different versions:

For the moment, my suggestion is to use the second package: this way, we will do everything from scratch, giving us the chance to better learn the basic concepts. In the future, you’re free to use the first package if you want to save some time.

As a sample project, we’re going to create a very simple Universal Windows app that it’s likely you would be able to develop in no time using code behind: a Hello World app with a TextBox, where to insert your name, and a Button that, when it’s pressed, will display a hello message followed by your name.

Linking the View and ViewModel

The first step is to identify the three components of our application: Model, View and ViewModel.

  • The model isn’t necessary in this application, since we don’t need to manipulate any entity.
  • The view will be made by a single page, which will show to the user the TextBox where to insert his name and the Button to show the message.
  • The ViewModel will be a class, which will handle the interaction in the view: it will retrieve the name filled by the user, it will compose the hello message and it will display it in the page.

Let’s start to add the various components: let’s create a Views folder and add, inside it, the only page of our application. As default behavior, when you create a new Universal Windows app the template will create a default page for you, called MainPage.xaml. You can move it to the Views folder or delete it and create a new one in Solution Explorer by right clicking on the folder and choosing Add –> New item –> Blank page.

Now let’s create the ViewModel that will be connected to this page. As explained in the previous post, the ViewModel is just a simple class: create a ViewModels folder, right click on it and choose Add –> New Item –> Class.

Now we need to connect the View and the ViewModel, by leveraging the DataContext property. In the previous post, in fact, we’ve learned that the ViewModel class is set as DataContext of the page; this way, all the controls in the XAML page will be able to access to all the properties and commands declared in the ViewModel. There are various ways to achieve our goal, let’s see them.

Declare the ViewModels as resources

Let’s say that you have created a ViewModel called MainViewModel. You’ll be able to declare it as a global resource in the App.xaml file this way:

<Application
    x:Class="MVVMSample.MVVMLight.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:viewModel="using:MVVMSample.MVVMLight.ViewModel">

    <Application.Resources>
        <viewModel:MainViewModel x:Key="MainViewModel" />
    </Application.Resources>

</Application>

The first step is to declare, as attribute of the Application class, the namespace which contains the ViewModel (in this sample, it’s MVVMSample.MVVMLight.ViewModel). Then, in the Resources collection of the Application class, we declare a new resource which type is MainViewModel and we associate it to a key with the same name. Now we can use this key and the StaticResource keyword to connect the DataContext of the page to the the resource, like in the following sample:

<Page
    x:Class="MVVMSample.MVVMLight.Views.MainPage"
    DataContext="{Binding Source={StaticResource MainViewModel}}"
    mc:Ignorable="d">

    <!-- your page content -->

</Page>

The ViewModelLocator approach

Another frequently used approach is to leverage a class called ViewModelLocator, which has the responsability of dispatching the ViewModels to the various pages. Instead of registering all the ViewModels as global resources of the application, like in the previous approach, we register just the ViewModelLocator. All the ViewModels will be exposed, as properties, by the locator, which will be leveraged by the DataContext property of the page.

This is a sample definition of a ViewModelLocator class:

public class ViewModelLocator
{
    public ViewModelLocator()
    {
    }

    public MainViewModel Main
    {
        get
        {
            return new MainViewModel();
        }
    }
}

Or, as an alternative, you can simplify the code by leveraging one of the new C# 6 .0 features:

public class ViewModelLocator
{
    public ViewModelLocator()
    {
    }

    public MainViewModel Main => new MainViewModel();
}

After you’ve added the ViewModelLocator class as global resource, you’ll be able to use it to connect the Main property to the DataContext property of the page, like in the following sample:

<Page
    x:Class="MVVMSample.MVVMLight.Views.MainPage"
    DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
    mc:Ignorable="d">

    <!-- your page content -->

</Page>

The syntax is very similar to the one we’ve seen with the first approach; the main difference is that, since the ViewModelLocator class can expose multiple properties, we need to specify with the Path attribute which one we want to use.

The ViewModelLocator’s approach adds a new class to maintain, but it gives you the flexibilty to handle the ViewModel’s creation in case we need to pass some parameters to the class’ constructor. In the next post, when we’ll introduce the dependeny injection’s concept, it will be easier for you to understand the advantages in using the ViewModelLocator approach.

Let’s setup the ViewModel

No matter which approach we decided to use in the previous step, now we have a View (the page that will show the form to the user) connected to a ViewModel (the class that will handle the user’s interactions).

Let’s start to populate the ViewModel and to define the properties that we need to reach our goal. In the previous post we’ve learned that ViewModels need to leverage the INotifyPropertyChanged interface; otherwise, every time we change the value of a property in the ViewModel, the View won’t be able to detect it and the user won’t see any change in the user interface.

To make easier to implement this interface, MVVM Light offers a base class which we can leverage in our ViewModels using inheritance, like in the following sample:

public class MainViewModel : ViewModelBase
{

}

This class gives us access to a method called Set(), which we can use when we define our propeties to dispatch the notifications to the user interface when the value changes. Let’s see a sample related to our scenario. Our ViewModel has to be able to collect the name that the user has filled into a TextBox control in the View. Consequently, we need a property in our ViewModel to store this value. Here is how it looks like thanks to the MVVM Light support:

private string _name;

public string Name
{
    get
    {
        return _name;
    }

    set
    {
        Set(ref _name, value);
    }
}

The code is very similar to the one we’ve seen in the previous post when we introduced the concept of the INotifyPropertyChanged interface. The only difference is that, thanks to the Set() method, we can achieve two goals at the same time: storing the value in the Name property and dispatching a notification to the binding channel that the value has changed.

Now that we have learned how to create properties, let’s create another one to store the message that we will display to the user after he has pressed the button.

private string _message;

public string Message
{
    get
    {
        return _message;
    }

    set
    {
        Set(ref _message, value);
    }
}

In the end, we need to handle the interaction with the user. When he presses the Button in the view, we have to display a hello message. From a logical point of view, this means:

  1. Retrieving the value of the Name property.
  2. Leveraging the string interpolation APIs to prepare the message (something like “Hello Matteo”).
  3. Assign the result to the Message property.

In the previous post we’ve learned that, in the MVVM pattern, you use commands to handle the user interactions in a ViewModel. As such, we’re going to use another one of the classes offered by MVVM Light, which is RelayCommand. Thanks to this class, instead of having to create a new class that implements the ICommand interface for each command, we can just declare a new one with the following code:

private RelayCommand _sayHello;

public RelayCommand SayHello
{
    get
    {
        if (_sayHello == null)
        {
            _sayHello = new RelayCommand(() =>
            {
                Message = $"Hello {Name}"; 
            });
        }
            
        return _sayHello;
    }
}

When you create a new RelayCommand object you have to pass, as parameter, an Action, which defines the code that you want to execute when the command is invoked. The previous sample declares an Action using an anonymous method. It means that, instead of defining a new method in the class with a specific name, we define it inline in the property definition, without assigning a name.

When the command is invoked, we use the new C# 6.0 feature to perform string interpolation to get the value of the property Name and add the prefix “Hello”. The result is stored into the Message property.

Create the view

Now that the ViewModel is ready, we can move on and create the View. The previous step should have helped you to understand one of the biggest benefits of the MVVM pattern: we’ve been able to define the ViewModel to handle the logic and the user interaction without writing a single line of code in the XAML file. With the code behind approach, it would have been impossible; for example, if we wanted to retrieve the name filled in the TextBox property, we should have first added the control in the page and assign to it a name using the x:Name property, so that we would have been able to access to it from code behind. Or if we wanted to define the method to execute when the button is pressed, we would have needed to add the Button control in the page and subscribe to the Click event.

From a user interface point of view, the XAML we need to write for our application is more or less the same we would have created for a code behind app. The UI, in fact, doesn’t have any connection with the logic, so the way we create the layout doesn’t change when we use the MVVM pattern. The main difference is that, in a MVVM app, we will use binding a lot more, since it’s the way we can connect the controls with the properties in the ViewModel. Here is how our View looks like:

<Page
    x:Class="MVVMSample.MVVMLight.Views.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
    mc:Ignorable="d">

    <Grid>
        <StackPanel Margin="12, 30, 0, 0">
            <StackPanel Orientation="Horizontal" Margin="0, 0, 0, 30">
                <TextBox Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="300" Margin="0, 0, 20, 0" />
                <Button Command="{Binding Path=SayHello}" Content="Click me!" />
            </StackPanel>

            <TextBlock Text="{Binding Path=Message}" Style="{StaticResource HeaderTextBlockStyle}" />
        </StackPanel>
    </Grid>

</Page>

We have added to the page three controls:

  1. A TextBox, where the user can fill his name. We have connected it to the Name property of the ViewModel. There are two features to higlight:
    1. We have set the Mode attribute to TwoWay. It’s required since, for this scenario, we don’t just need that when the property in the ViewModel changes the control displays the updated value, but also the opposite. When the user fills some text in the control, we need to store its value in the ViewModel.
    2. We have set the UpdateSourceTrigger attribute to PropertyChanged. This way, we make sure that, every time the text changes (which means every time the user adds or remove a char in the TextBox), the Name property will automatically update to store the changed value. Without this attribute, the value of the property would be updated only when the TextBox control loses the focus.
  2. A Button, that the user will click to see the hello message. We have connected it to the SayHello command in the ViewModel.
  3. A TextBlock, where the user will see the hello message. We have connected it to the Message property of the ViewModel.

If we have done everything properly and we launch the app, we should see the application behaving as we described at the beginning of this post: after filling your name and pressing the button, you will see the hello message.

Let’s improve the user interaction

Our application has a flaw: if the user presses the button without writing anything in the TextBox, he would see just the “Hello” prefix. We want to avoid this behaviro by disabling the button if the TextBox control is empty. To achieve our goal we can leverage one of the features offered by the ICommand interface: we can define when a command should be enabled or not. For this scenario the RelayCommand class allows a second parameter during the initialization, which is a function that returns a boolean value. Let’s see the sample:

private RelayCommand _sayHello;

public RelayCommand SayHello
{
    get
    {
        if (_sayHello == null)
        {
            _sayHello = new RelayCommand(() =>
            {
                Message = $"Hello {Name}";
            },

            () => !string.IsNullOrEmpty(Name));
        }

        return _sayHello;
    }
}

We’ve changed the initialization of the SayHello command to add, as a second parameter, a boolean value: specifically, we check if the Name property is null or empty (in this case, we return false, otherwise true). Thanks to this change, now the Button control connected to this command will be automatically disabled (also from a visual point of view) if the Name property is empty. However, there’s a catch: if we try the application as it is, we would notice that the Button will be disabled by default when the app starts. It’s the expected behavior, since when the app is launched the TextBox control is emtpy by default. However, if we start writing something in the TextBox, the Button will continue to be disabled. The reason is that the ViewModel isn’t able to automatically determine when the execution of the SayHello command needs to be evaluated again. We need to do it manually every time we do something that may change the value of the boolean function; in our case, it happens when we change the value of the Name property, so we need to change the property definition like in the following sample:

private string _name;

public string Name
{
    get
    {
        return _name;
    }

    set
    {
        Set(ref _name, value);
        SayHello.RaiseCanExecuteChanged();
    }
}

Other than just using the Set() method to store the property and to send the notification to the user interface, we invoke the RaiseCanExecuteChanged() method of the SayHello command. This way, the boolean condition will be evaluated again: if the Name property contains some text, than the command will be enabled; otherwise, if it should become empty again, the command will be disabled.

In the next post

In this post we’ve finally started to apply with a real project the concepts we’ve learned in the first post and we have started to write our first application based on the MVVM pattern. In the next posts we’ll see some advanced scenario, like dependency injection, messages or how to handle secondary events. Meanwhile, you can play with the sample app we’ve created in this post, which is published on my GitHub repository https://github.com/qmatteoq/UWP-MVVMSamples. Together with the sample created in this post, you will find also the same sample created using Caliburn Micro as MVVM framework instead of MVVM Light. Happy coding!

Introduction to MVVM – The series

  1. Introduction
  2. The practice
  3. Dependency Injection
  4. Advanced scenarios
  5. Services, helpers and templates
  6. Design time data
Posted in Universal Apps, UWP, wpdev | Tagged , , | Leave a comment

The MVVM pattern – Introduction

Model-View-ViewModel (from now on, just MVVM) is a “love and hate” topic when it comes to Universal Windows app development. If you have never used it and you try it for the first time, you’ll probably find yourself a little bit confused, since it’s a completely different approach than the standard one based on the code behind. On the other side, if you’re a long time MVVM user, probably you won’t be able anymore to create a new project using any other approach. This is the reason why I’ve decided to write the following series of posts: what’s MVVM? Why is it so widely adpoted when it comes to Universal Windows apps development and, generally speaking, by any XAML based technology? I hope that, at the end of the journey, you’ll find an answer to all your questions and you’ll be able to start using the MVVM pattern in your apps without being scared anymore Smile

The MVVM pattern

The first thing you have to understand is that MVVM isn’t a framework or a library, but a pattern: it isn’t a set of APIs or methods, but a way to define the architecture of an application. Probably you’ve already heard about MVVM LIght or Caliburn Micro, but you don’t have to confuse them with MVVM: they’re tools that helps developers to adopt the MVVM pattern, they don’t represent the pattern itself.

The purpose of a pattern is to help developers to define the architecture of an application. Why is so important to do it? Why we cant’t simply continue to develop an application in the way we are used to, which is writing all the code in the code-behind class? The standard approach is very quick and simple to understand but it has many limitations when it comes to more complex projects, that needs to be maintained over time. The reason is that the code-behind class has a very tight dependency with the XAML page. Consequently, most of the code can’t be isolated and we end up to mix business logic and the presentation layer.

In the long run, the code behind approach introduces many problems:

  1. It’s more complicated to maintain the code and evolve the project. Every time we need to add a new feature or solve a bug, it’s hard to understand where precisely we need to it, since there isn’t a clear distinction between the various components of the app. This becomes even more true if we need to resume working on a project which has been “on hold” for a long time.
  2. It’s complex to perform unit testing. When it comes to complex projects, many developers and companies are adopting the unit test approach, which is a way to perform automatic tests that validate small pieces of code. This way it becomes easier to evolve the project: every time we add a new feature or we change some existing code, we can easily verify if the work we’ve done has broken the already existing features of the app. However, having a tight dependency between the logic and the user interface makes nearly impossible to write unit tests, since the code isn’t isolated.
  3. It’s complex to design the user interface: since there’s a tight relationship between the user interface and the business logic, it isn’t possible for a designer to focus on the user interface without knowing all the implementation details behind it. Questions like “where the data is coming from? A database? A cloud service?” shouldn’t be asked by a designer.

The goal of the MVVM pattern is to “break” this strong connection between the code behind and the user interface, making easier for a developer to understand which are the different components of the application. More precisely, it’s fundamental to distinguish the components which take care of the business logic and the ones that handle the data presentation.

The name of the pattern comes from the fact that the project is split into three different components, which now we’re going to explore in details.

The model

The model is the component of the application that defines and handles all the basic entities of the application. The goal of this layer is to remove any dependency from the way the data is represented. Ideally, you should be able to take the classes that belong to this component and use them in another application without applying any change. For example, if you’re working on an application to handle orders and customers of a company, the model could be defined by all the classes which define the base entities, like a customer, an order, a product, etc.

The view

The view is at the opposite side of the model and it’s represented by the user inteface. In the Universal Windows apps world, views are made by the XAML pages, which contain all the controls and animations that define the visual layout of the application. Recyicling the already mentioned sample of an app to handle orders and customers, we can have multiple views to display the list of customers, the available products in the warehouse, the orders made by a customer, etc.

The ViewModel

The ViewModel is the connection point between the view and model: it takes care of retrieving the raw data from the model and to manipulate it so that it can be properly displayed by the view. The huge difference with a code behind class is that the ViewModel is just a plain simple class, without any dependency from the View. In an application based on the MVVM pattern, typically you create a ViewModel for every View.

Why the MVVM pattern?

After this brief introduction, it should be easier to understand why the MVVM pattern is so important and how, by adopting it, we can solve all the problems mentioned at the beginning of the post.

  1. By splitting the code in three different layers it becomes easier, especially if you’re working in a team, to maintain and evolve the application. If you need to add a feature or to solve a bug, it’s easier to identify which layer has to be manipulated. Moreover, since there is no dependency between each layer, the work can be also done in parallel (for example, a designer can start working on the user interface while another developer can create the services which will be used by the page to retrieve the data).
  2. To properly perform unit testing, the code to test has to be as simple and isolated as possible. When you work with the code-behind approach, this is simply not possible: often the logic is connected to an event handler (for example, because the code has to be executed when you press a button) and you would need to find a way to simulate the event in order to trigger the code to test. By adopting the MVVM pattern we break this tight dependency: the code included in a ViewModel can be easily isolated and tested.
  3. Since we have broken the tight connection between the user interface and the business logic, for a designer it’s easy to define the interface without having to know all the implementation details of the application. For example, if the designer has to work on a new page which displays a list of orders, we can easily swap the real ViewModel (which retrieves the data from a real data source, like a cloud service or a database) with a fake one, which can generate fake data that allows to the designer to easily understand which kind of information the page should display.

Why in the Universal Windows app world most of the developers tend to use the MVVM pattern and not other popular patterns like MVC or MVP? Mainly, because the MVVM pattern is based on many features which are at the core of the XAML runtime, like binding, dependency properties, etc. In this series of post we’re going to talk a bit more about these features. You can notice how I’ve just mentioned XAML runtime and not the Universal Windows Platform: the reason is that most of the things we’re going to see in these posts aren’t specific of the Universal Windows app world, but they can be applied to any XAML based technology, like WPF, Silverlight, Windows Phone, Xamarin, etc.

Let’s see now, in details, which are the basic XAML features leveraged by the MVVM pattern.

The binding

Binding is one of the most important XAML features and allows to create a communication channel between two different properties. They can be properties that belong to different XAML controls, or a property declared in code with a control’s property. The key feature leveraged by the MVVM pattern is the second one: View and ViewModels are connected thanks to binding. The ViewModel takes care of exposing the data to show in the View as properties, which will be connected to the controls that will display them using binding. Let’s say, for example, that we have a page in the application that displays a list of products. The ViewModel will take care of retrieving this information (for example, from a local database) and to store it into a specific property (like a collection of type List<Order>):

public List<Order> Orders { get; set; }

To display the collection in a traditional code behind app, at some point, you would manually assign this property to the ItemsSource property of a control like ListView or GridView, like in the following sample:

MyList.ItemsSource = Orders;

However, this code creates a tight connection between the logic and the UI: since we’re accessing to the ItemsSource property using the name of the control, we can perform this operation only in the code behind class.

With the MVVM pattern, instead, we connect properties in the ViewModel with controls in the UI using binding, like in the following sample:

<ListView ItemsSource="{Binding Path=Orders}" /> 

This way, we have broken the dependency between the user interface and the logic, since the Orders property can be defined also in a plain simple class like a ViewModel.

As already mentioned, binding can be also bidirectional: this approach is used when not just the ViewModel needs to display some data in the View, but also the View should be able to change the value of one of the ViewModel’s properties. Let’s say that your application has a page where he can create a new order and, consequently, it includes a TextBox control where to set the name of the product. This information needs to be handled by the ViewModel, since it will take care of interacting with the model and adding the order to the database. In this case, we apply to the binding the Mode attribute and we set it to TwoWay, so that everytime the user adds some text to the TextBox control, the connected property in the ViewModel will get the inserted value.

If, in the XAML, we have the following code, for example:

<TextBox Text="{Binding Path=ProductName, Mode=TwoWay}" /> 

it means that in the ViewModel we will have a property called ProductName, which will hold the text inserted by the user in the box.

The DataContext

In the previous section we’ve seen how, thanks to the binding, we are able to connect the ViewModel’s properties to the controls in the XAML page. You may be wondering how the View model is able to understand which is the ViewModel that populates its data. To understand it, we need to introduce the DataContext’s concept, which is a property offered by any XAML Control. The DataContext property defines the binding context: every time we set a class as a control’s DataContext, we are able to access to all its public properties. Moreover, the DataContext is hierarchical: properties can be accessed not only by the control itself, but also all the children controls will be able to access to them.

The core of the implementation of the MVVM pattern relies on this hierarachy: the class that we create as ViewModel of a View is defined as DataContext of the entire page. Consequently, every control we place in the XAML page will be able to access to the ViewModel’s properties and show or handle the various information. In an application developed with the MVVM pattern, usually, you end up to have a page declaration like the following one:

<Page x:Class="Sample.MainPage" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      DataContext="{Binding Source={StaticResource MainViewModel}}" 
      mc:Ignorable="d"> 

    <!-- page content goes here -->

</Page> 

The DataContext property of the Page class has been connected to a new instance of the MainViewModel class.

The INotifyPropertyChanged interface

If we try to create a simple application based on the MVVM pattern applying the concepts we’ve learned so far, we would quickly hit a big issue. Let’s use the previous sample of the page to add a new order and let’s say that we have, in the ViewModel, a property which we use to display the product’s name, like the following one:

public string ProductName { get; set; } 

According to what we have just learned, we expect to have a TextBlock control in the page to display the value of this property, like in the following sample:

<TextBlock Text="{Binding Path=ProductName}" /> 

Now let’s say that, during the excecution of the app, the value of the ProductName proeprty changes (for example, because a data loading operation is terminated). We will notice how, despite the fact that the ViewModel will properly hold the new value of the property, the TextBlock control will continue to show the old one. The reason is that binding isn’t enough to handle the connection between the View and the ViewModel. Binding has created a channel between the ProductName property and the TextBlock, but no one notified both sides of the channel that the value of the property has changed. For this purpose, XAML offers the concept of dependency properties, which are special properties that can define a complex behavior and, under the hood, are able to send a notification to both sides of the binding channel every time its value changes. Most of the basic XAML controls use dependency properties (for example, the Text property of the TextBlock control is a dependency property). However, defining a new dependency property isn’t very straightforward and, in most of the cases, it offers features which aren’t needed for our MVVM scenario. Let’s take the previous sample based on the ProductName property: we don’t need to handle any special behavior or logic, we just need that, every time the ProductName property changes, both sides of the binding channel receive a notification, so that the TextBlock control can update its visual layout to display the new value.

For these scenarios, XAML offers a specific interface called INotifyPropertyChanged, which we can implement in our ViewModels. This way, if we need to notify the UI when we change the value of a property, we don’t need to create a complex dependency property, but we just need to implement this interface and invoke the related method every time the value of the property changes.

Here is how a ViewModel that implements this interface looks like:

public class MainViewModel: INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    [NotifyPropertyChangedInvocator] 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

You can notice how the implementation of this interface allows us to call a method called OnPropertyChanged(), that we can invoke every time the value of a property changes. However, to reach this goal, we need to change the way how we define the properties inside our ViewModel. When it comes to simple properties, usually we define them using the short syntax:

public string ProductName { get; set; } 

Hower, with this syntax we can’t change what happens when the value of the property is written or read. As such, we need to go back to use the old approach, based on a private variable which holds the value of the property. This way, when the value is written, we are able to invoke the OnPropertyChanged() method and dispatch the notification. Here is how a property in a ViewModel looks like:

private string _productName; 

public string ProductName 
{ 
    get { return _productName; } 
    set 
    { 
        _productName = value; 
        OnPropertyChanged(); 
    } 
} 

Now the property will work as expected: when we change its value, the TextBlock control in binding with it will change his appearance to display it.

Commands (or how to handle events in MVVM)

Another critical scenario when it comes to develop an application is to handle the interactions with the user: he could press a button, choose an item in a list, etc. In XAML, these scenarios are handled using events which are exposed by various controls. For example, if you want to handle that the button has been pressed, we need to subscribe to the Click event, like in the following sample:

<Button Content="Click me" Click="OnButtonClicked" /> 

The event is managed by an event handler, which is a method that includes, among the various parameters, some information which are useful to understand the event context (for example, the control which triggered the event or which item of the list has been selected), like in the following sample:

private void OnButtonClicked(object sender, RoutedEventArgs e) 
{ 
    //do something 
} 

The problem of this approach is that event handlers have a tight dependency with the View: they can be declared, in fact, only in the code behind class. When you create an application using the MVVM pattern, instead, all the data and logic is usually defined in the ViewModel, so we need to find a way to handle the user interaction there.

For this purpose, the XAML has introduced commands, which is a way to express a user interaction with a property instead that with an event handler. Since it’s just a simple property, we can break the tight connection between the view and the event handler and we can define it also in an independent class, like a ViewModel.

The framework offers the ICommand interface to implement commands: with the standard approach, you end up having a separated class for each command. The following example shows how a command looks like:

public class ClickCommand : ICommand 
{ 
    public bool CanExecute(object parameter) 
    { 
    } 

    public void Execute(object parameter) 
    { 
    } 

    public event EventHandler CanExecuteChanged; 

} 

The core of the command is the Execute() method, which contains the code that is executed when the command is invoked (for example, because the user has pressed a button). It’s the code that, in a traditional application, we would have written inside the event handler.

The CanExecute() method is one of the most interesting features provided by commands, since it can be used to handle the command’s lifecycle when the app is running. For example, let’s say that you have a page with a form to fill, with a button at the end of the page that the user has to press to send the form. Since all the fields are required, we want to disable the button until all the fields have been filled. If we handle the operation to send the form with a command, we are able to implement the CanExecute() method in a way that it will return false when there’s at least one field still empty. This way, the Button control that we have linked to the command will automatically change his visual status: it will be disabled and the user will immediately understand that he won’t be able to press it.

clip_image002

In the end, the command offers an event called CanExecuteChanged, which we can invoke inside the ViewModel every time the condition we want to monitor to handle the status of the command changes. For example, in the previous sample, we would call the CanExecuteChanged event every time the user fills one of the fields of the form.

Once we have define a command, we can link it to the XAML thanks to the Command property, which is exposed by every control that are able to handle the interaction with the user (like Button, RadioButton, etc.)

<Button Content="Click me" Command="{Binding Path=ClickCommand}" /> 

As we’re going to see in the next post, however, most of the toolkits and frameworks to implement the MVVM pattern offers an easier way to define a command, without forcing the developer to create a new class for each command of the application. For example, the popular MVVM Light toolkit offers a class called RelayCommand, which can be used to define a command in the following way:

private RelayCommand _sayHello; 

public RelayCommand SayHello 
{ 
    get 
    { 
        if (_sayHello == null) 
        { 
            _sayHello = new RelayCommand(() => 
            { 
                Message = string.Format("Hello {0}", Name); 
            }, () => !string.IsNullOrEmpty(Name)); 
        } 

        return _sayHello; 
    } 
} 

As you can see, we don’t need to define a new class for each command but, by using anonymous methods, we can simply create a new RelayCommand object and pass, as parameters:

  1. The code that we want to excecute when the command is invoked.
  2. The code that evaluates if the command is enabled or not.

We’re going to learn more about this approach in the next post.

How to implement the MVVM pattern: toolkits and frameworks

As I’ve mentioned at the beginning of the post, MVVM is a pattern, it isn’t a library or a framework. However, as we’ve learned up to now, when you create an application based on this pattern you need to leverage a set of standard procedures: implementing the INotifyPropertyChanged interface, handling commands, etc.

Consequently, many developers have started to work on libraries that can help the developer’s job, allowing them to focus on the development of the app itself, rather than on how to implement the pattern. Let’s see which are the most popular libraries.

MVVM Light

MVVM Light (http://www.mvvmlight.net) is a library created by Laurent Bugnion, a long time MVP and one of the most popular developers in the Microsoft world. This library is very popular thanks to its flexibility and simplicity. MVVM Light, in fact, offers just the basic tools to implement the pattern, like:

  • A base class, which the ViewModel can inherit from, to get quick access to some basic features like notifications.
  • A base class to handle commands.
  • A basic messaging system, to handle the communication between different classes (like two ViewModels).
  • A basic system to handle dependency injection, which is an alternative way to initialize ViewModels and handle their dependencies. We’ll learn more about this concept in another post.

Since MVVM Light is very basic, it can be leveraged not just by Universal Windows apps, but also in WPF, Sivlerlight and even Android and iOS thanks to its compatibility with Xamarin. Since it’s extremely flexible, it’s also easy to adapt it to your requirements and as a starting point for the customization you may want to create. This simplicity, however, is also the weakness of MVVM Light. As we’re going to see in the next posts, when you create a Universal Windows app using the MVVM pattern you will face many challenges, since many basic concepts and features of the platform (like the navigation between different pages) can be handled only in a code behind class. From this point of view, MVVM Light doesn’t help the developer that much: since it offers just the basic tools to implement the pattern, every thing else is up to the developer. For this reasons, you’ll find on the web many additional libraries (like the Cimbalino Toolkit) which extend MVVM Light and add a set of services and features that are useful when it comes to develop a Universal Windows app.

Caliburn Micro

Caliburn Micro (http://caliburnmicro.com) is a framework originally created by Rob Eisenberg and now maintained by Nigel Sampson and Thomas Ibel. If MVVM Light is a toolkit, Caliburn Micro is a complete framework, which offers a completely differnent approach. Compared to MVVM Light, in fact, Caliburn Micro offers a rich set of services and features which are specific to solve some of the challenges provided by the Universal Windows Platform, like navigation, storage, contracts, etc.

Caliburn Micro handles most of the basic features of the pattern with naming conventions: the implementation of binding, commands and others concepts are hidden by a set of rules, based on the names that we need to assign to the various components of the project. For example, if we want to connect a ViewModel’s property with a XAML control, we don’t have to manually define a binding: we can simply give to the control the same name of the property and Caliburn Micro will apply the binding for us. This is made possible by a boostrapper, which is a special class that replaces the standard App class and takes care of intializing, other than the app itself, the Caliburn infrastructure.

Caliburn Micro is, without any doubt, very powerful, since you’ll have immediate access to all the tools required to properly develop a Universl Windows app using the MVVM pattern. However, in my opinion, isn’t the best choice if you’re new to the MVVM pattern: since it hides most of the basic concepts which are at the core of the pattern, it can be complex for a new developer to understand what’s going on and how the different pieces of the app are connecte together.

Prism

Prism (http://github.com/PrismLibrary/Prism) is another popular framework which, in the beginning, was created and maintaned by the Pattern & Practises division by Microsoft. Now, instead, it has become a community project, maintained by a group of independent developers and Microsoft MVPs.

Prism is a framework and uses a similar approach to the one provided by Caliburn Micro: it offers naming convention, to connect the different pieces of the app together, and it includes a rich set of services to solve the challenges provded by the Universal Windows Platform.

We can say that it sits in the middle between MVVM Light and Caliburn Micro, when it comes to complexity: it isn’t simple and flexible like MVVM Light but, at the same time, it doesn’t use naming convention in an aggressive way like Caliburn Micro does.

Coming soon

In the next posts we’re going to turn what we’ve learned so far int oa realy project and we’re going to leverage MVVM Light for this purpose: the reason is that, as I’ve already mentioned, I think MVVM Light is the easiest one to understand, especially if you’re new to the pattern, since it will help us to learn all the basic concepts which are at the core of the pattern. If you want to start looking at a real project, you’ll find many samples (which we’re going to explain in a more detailed way) on my GitHub repository at https://github.com/qmatteoq/UWP-MVVMSamples. Stay tuned!

P.S.= this post has been written with OpenLiveWriter, the new open source version of Windows Live Writer, which has now become a community driven project. In my opinion (and not just mine Smile) Open Live Writer is the best tool in the world to write blog posts, so thanks to Microsoft for making this happen and thanks to all the great developers that are contributing to the project and keeping it alive!

Introduction to MVVM – The series

  1. Introduction
  2. The practice
  3. Dependency Injection
  4. Advanced scenarios
  5. Services, helpers and templates
  6. Design time data
Posted in Universal Apps, UWP, wpdev | Tagged , | 1 Comment

Template10: a new template to create Universal Windows apps – MVVM

The Model-View-ViewModel pattern (from now on, just MVVM) is, without any doubt, the most widely used pattern when it comes to develop XAML based applications. In this post, we won’t learn all the inner details of the pattern: I’ve already talked about it many times in this blog, when I presented some of the most popular MVVM frameworks like Caliburn Micro and Prism.  The goal of the MVVM pattern is to improve testability and maintainability of an application, since it helps the developer in reaching one of the key goals that drives any complex development project: keeping the different layers separated, so that the code that handles the user interface doesn’t mix with the one that handles the business logic (like retrieving the data from the cloud or from a database).

The MVVM pattern is heavily used in the Universal Windows app world and, generally speaking, also in all the XAML based technologies, since it relies on the basic XAML feature like binding, dependency properties, the INotifyPropertyChanged interface, etc. When you use this pattern, you typically split the project into three components:

  1. The model, which are the entities and the services that are used to handle the raw data of the application, without dependencies on how they are presented.
  2. The view, which is the user interface presented to the user. In Universal Windows apps, the Views are identified with the XAML pages.
  3. The ViewModel, which is the connection between the view and the model. ViewModel are simple classes that takes care of retrieving the data handled by the model and of preparing them to be presented by the View using binding.

The MVVM pattern gives to developers a lot of benefits but, however, it requires some time to be configured into a new project: the problem is that when you create a new Universal Windows app there are a lot of scenarios (navigation, the application’s lifecycle, contracts, etc.) which are simple to implement when you use code-behind, but that need to be reviewed when you use the MVVM pattern, since most of the code is written in a ViewModel, which is an independent class. A good example of this problem is the page lifecycle management: typically, in a Universal Windows app you use the OnNavigatedTo() and OnNavigatedFrom() events to handle the navigation from one page to another. However, these events are exposed only by the code behind class, since it inherits from the Page class; you can’t use them in a ViewModel, which doesn’t have any dependency from it.

For this reason, many developers have created libraries and frameworks which makes the developer’s life easier, by providing all the needed tools. The most popular ones are MVVM Light by Laurent Bugnion, Caliburn Micro by Rob Esieneberg and Prism, originally developed by the Microsoft Pattern & Practice division and now turned in to a community project. Every framework has its own pros and cons: MVVM Light is the simplest and most flexible one, but it lacks any helper to handle the typical scenarios of a Universal Windows app. Caliburn Micro and Prism, on the other side, are more complex to master and a little bit “rigid”, but they offer many tools to handle common scenarios like navigation, page lifecycle, etc.

Template10 doesn’t act as another MVVM framework (even if, as we’re going to see, it offers some classes to implement it without having to rely on another library), but it helps developers to make the implementation of the MVVM pattern easier. Let’s see in details which are these facilities: it’s important to remember that what we have described in the previous posts (bootstrapper, extended splash screen, the new controls, etc.) can be applied also on MVVM based projects.

The basic tools to implement the pattern

Even if Template10 doesn’t behave as a complete alternative to the existing libraries, it offers any way the basic tools required to implement it in the proper way. You aren’t forced to use them: you can choose, for example, to add MVVM Light to your project and to use its helpers in replacement of the ones that I’m going to describe.

The first important helper offered by Template10 is the ViewModelBase class, which is the base class which your ViewModels should inherit from. Other than offering a set of useful features that we’re going to see later in this post, it offers the basic tools to implement the pattern. The most important one is the Set() method, which can be used to propagate the changes to the ViewModel properties to the user interface, by implementing the INotifyPropertyChanged interface. Here is how you can use it to define a property in the ViewModel:

public class MainViewModel : Template10.Mvvm.ViewModelBase 
{ 
    public MainViewModel() 
    { 

    } 

    private string _name; 

    public string Name 

    { 
        get { return _name; } 
        set { Set(ref _name, value); } 
    } 
} 

The Set() method, invoked inside the property’s setter, allows to send a notification to the view that the value has changed, other than just effectively changing the value of the property. This way, if in the View you have one or more controls connected to this property through binding, they will update their visual state to reflect the changes. For example, here is how you can connect a TextBlock control placed in the XAML page to the property we’ve just declared:

<TextBlock Text="{Binding Path=Name}" /> 

If you already have some experience with MVVM Light, this approach will be familiar to you: also this toolkit offers a method called Set(), which has the same purpose.

Another important feature that Template10 implements is the DelegateCommand class, which can be used to easily create commands. Which is the purpose of commands? When it comes to handle the user interaction in a traditional application created using the code-behind approach, you rely on event handlers: they’re methods that are connected to an event that is raised by a control, like pressing a button or selecting an item from a list. These event handlers have a tight dependency with the view and, as such, they can be declared only in the code-behind class. In a MVVM application, instead, most of the logic is handled by the ViewModel and, consequently, we would need to handle the user interaction in a ViewModel. This is exactly the purpose of commands: a way to handle an event using a property, so that we can connect it to a control using binding. This way, we can “break” the dependency that traditional event handlers have with the view and we can declare commands in any class, including ViewModels.

A command is defined by:

  1. The actions to perform when the command is invoked.
  2. The condition that needs to be satisfied to enable the command. This feature is very useful, because it makes sure that the control connected to the command automatically changes his visual status based on the command status. For example, if a command is connected to a Button control and, during the execution, the command is disabled, also the button will be disabled: it will be displayed in grey and the user won’t be able to tap on it.

The Windows Runtime offers a base class to implements commands, called ICommand: however, it’s just an interface, the concrete implementation is up to the developer, who would need to create a class for every command. To reduce the footprint and speed up the development, Template10 offers a class called DelegateCommand, which implements this interface and that can be initialized simply by passing to the constructor the two required information. Here is an example:

private DelegateCommand _setNameCommand; 

public DelegateCommand SetNameCommand 
{ 
    get 
    { 
        if (_setNameCommand == null) 
        { 
            _setNameCommand = new DelegateCommand(() => 
            { 
                Result = $"Hello {Name}"; 
            }, () => !string.IsNullOrEmpty(Name)); 

        } 

        return _setNameCommand; 

    } 
} 

The first parameter is an Action (in this case, it’s defined using an anonymous method), which defines the operations to execute when the command is invoked. The second optional parameter, instead, is a function that should return a boolean value and that is used to determine if the command is enabled or not. In the sample, the command is enabled only in case the content of the Name property isn’t empty.

Once you have defined a command, you can connect it to a XAML control using the property with the same name, which is exposed by all the controls that support the user interaction (like the Button control).  The following sample shows how to use the Command property offered by the Button control to connect the DelegateCommand property we’ve previously defined.

<Button Content="Click me" Command="{Binding Path=SetNameCommand}" /> 

Also in this case, if you have previous experience with MVVM Light, the approach will be familiar: the toolkit, in fact, offers a class called RelayCommand for the same purpose and which works in the same way.

Navigation and page’s lifecycle

We already mentioned this scenario multiple times in this post: one of the key scenarios to handle in a Universal Windows app is the page’s lifecycle. Frequently, the navigation events are used to handle basic operations like data loading. As such, having access to these kind of events also in a ViewModel is critical, since usually all the logic is there.

For this purpose, the ViewModelBase class offers a set of additional features to make the developer’s life easier. The first feature is the implementation of an interface called INavigable, which allows to access to the navigation events directly in a ViewModel, like in the following sample:

public class DetailViewModel : ViewModelBase 
{ 
    public override void OnNavigatedTo(object parameter, NavigationMode mode, IDictionary<string, object> state) 
    { 
        if (parameter != null) 
        { 
            int id = (int) parameter; 
            //load data 
        } 
    } 

    public override Task OnNavigatedFromAsync(IDictionary<string, object> state, bool suspending) 
    { 
        return base.OnNavigatedFromAsync(state, suspending); 
    } 
} 

As you can see, thanks to this base class you get a 1:1 mapping with the same methods that are available in the code-behind class. You get also useful information about the navigation, like parameters that have been passed from another page or the NavigationMode, which can be useful to distinguish the different navigation scenarios (for example, you may decide to load the application’s data only when the NavigationMode parameter is set to New, which means that it’s a new navigation).

Another navigation feature offered by the ViewModelBase class is the NavigationService, which is a helper that can be used to trigger the navigation from one page to another directly in the ViewModel. Again, this is a scenario that, without this helper, would be supported only in the code-behind class: navigation is handled, in fact, by the Frame class, which can be accessed only in code-behind. The NavigationService class is pretty straightforward to use, since it mimics the behavior of the Frame one: to navigate from one page to another you can use the Navigate() method, passing as information the page’s type and, optionally, a parameter.

NavigationService.Navigate(typeof(DetailPage), person?.Id); 

As you can see in the documentation, the Navigate() method accepts as parameter a generic object: however, it isn’t a good practice to pass complex objects from one page to another, but it’s better to stick with simple types (a string, a number, etc.). This way, we make sure not to break the state management system implemented by Template10 (that we’re going to see later), which requires that parameters needs to be serializable.

Handle the page’s state

One of the most important scenarios to handle in a Universal Windows app is the application’s lifecycle. When an application isn’t in foreground anymore, it’s suspended: the process is frozen in memory (so that the state is preserved) but all the threads that can use CPU, battery or network are terminated. When the application is resumed, we don’t have to do anything special: since the state was preserved in memory, the app will be restored exactly as it was. However, the operating system can decide to terminate a suspended application in case the resources are running low. In this case, since the process is completely killed, when the app is resumed it won’t automatically be restored to the previous state. As developers, we need to handle this scenario: since the termination by the OS is completely transparent to the user, he will expect to find the application as he left it. It’s our duty to properly save and restore the page’s state. Let’s say, for example, that our application includes a page with some fields that the user needs to fill before moving on (like a registration form). Once the application is suspended and then resumed, he would expect to find the data he already filled already there and not to fill the entire form from scratch.

When you use the MVVM pattern, handling this scenario introduces some challenges:

  1. Since we don’t know for sure if the suspended application will be terminated or not, we need to save the page’s state every time a new navigation is performed. When you use the MVVM pattern without relying on other libraries (like Template10), this requirement is hard to handle because we don’t have access to the navigation events in a ViewModel.
  2. When the application is suspended, we need to save in the local storage the application’s state, like the content of the registration form or the last visited page. Then, when the application is resumed, we need to understand if it was terminated and, consequently, restore the state we’ve previously saved. Unfortunately, the basic Windows 10 template doesn’t offer any tool or API to make easier for the developer to support this scenario.

Template10 makes the whole process a lot easier. When we have seen the sample code about handling the page’s lifecycle, you may have noticed that the OnNavigatedTo() and OnNavigatedFrom() events expose a parameter called state. It’s a dictionary, which can contain a list of key-value pairs, that are automatically serialized and deserialized in the local storage when the app is suspended or resumed. When the application is suspended, you’re going to use the OnNavigatedFrom() method to add in the dictionary all the information we need to recover the application’s state. When the page is loaded, instead, in the OnNavigatedTo() event, we’ll retrieve the previously saved info and we’ll assign them to the proper properties in the ViewModel.

Let’s see a real sample, by defining a page with a TextBox control. The user can insert any text in it, which is saved into a ViewModel property, like the following one

private string _name; 

public string Name 
{ 

    get { return _name; } 
    set { Set(ref _name, value); } 
} 

The property is connected, as usual, to the TextBox control using binding:

<TextBlock Text="{Binding Path=Name, Mode=TwoWay}" /> 

You can notice that the binding has been configured using the TwoWay mode: this way, every time the user will write something in the TextBox, the Name property in the ViewModel will be automatically updated with the new value.

Now you can try to suspend the application and to open it back, by using the dropdown menu called Lifecycle events in Visual Studio, that allows to simulate the different stages of the application’s lifecycle. It’s important to remind, in fact, that when the debugger is attached, the app is not suspended when you put in background, like instead happens during the regular usage. If we write some text in the TextBox control, then we suspend the app and we open it back, we will find everything as we’ve left, since the app was just suspended and the process kept in memory. However, if we try to do the same but using the Suspend and shutdown option, you will notice that the content of the TextBox control will be gone: the process has been indeed terminated and, since we didn’t save the content of the TextBox, the data was lost during the restore process.

clip_image002

To avoid this issue we can use the dictionary I’ve previously mentioned: in the OnNavigatedFrom() method of the ViewModel we can understand if the app is being suspended and, eventually, save in the collection the information we need to restore the state.

public class DetailViewModel : ViewModelBase 
{ 

    private string _name; 

    public string Name 
    { 
        get { return _name; } 
        set { Set(ref _name, value); } 
    } 

    public override Task OnNavigatedFromAsync(IDictionary<string, object> state, bool suspending) 
    { 
        if (suspending) 
        { 
            state.Add("Name", Name); 
        } 
        
        return base.OnNavigatedFromAsync(state, suspending); 
    } 
} 

By using the boolean parameter called suspending we understand if the app is being suspended: if that’s the case, we can save into the dictionary called state the value of the Name property, by matching it to a key with the same name. This way, during the suspension, Template10 will automatically take care of serializing the content of this dictionary into the local storage in a text file. Now it will be easier for you to understand one of the key requirements of this implementation: we can store into the dictionary only simple data, that can be serialized into XML or JSON file. Saving, for example, an image stream into the dictionary wouldn’t work.

The next step is to handle the page loading: in case the state dictionary contains some data in the OnNavigatedTo() method, then it means that the app is being resumed from a suspension and we need to retrieve the. Also in this case most of the work will be done by Template10: the bootstrapper will take care of loading the data that was previously serialized and it will automatically redirect the user to the last visited page of the application. This way, we can simply access to the state parameter in the OnNavigatedTo() method and use the data to populate back the properties in our ViewModel, like in the following sample:

public class DetailViewModel : ViewModelBase 
{ 

    private string _name; 

    public string Name 
    { 
        get { return _name; } 
        set { Set(ref _name, value); } 
    } 

    public override void OnNavigatedTo(object parameter, NavigationMode mode, IDictionary<string, object> state) 
    { 
        if (state.Any()) 
        { 
            Name = state["Name"].ToString(); 
            state.Clear(); 
        } 

    } 

    public override Task OnNavigatedFromAsync(IDictionary<string, object> state, bool suspending) 
    { 
        if (suspending) 
        { 
            state.Add("Name", Name); 
        } 

        return base.OnNavigatedFromAsync(state, suspending); 
    } 
} 

Inside the OnNavigatedTo() method we check if there is any data inside the dictionary: only in this case we retrieve the value identified by the Name key and we assign it to the proper ViewModel’s property. The next step is to clear the content of the collection (using the Clear() method), to avoid that the data is retrieved again also when we’re simply navigating from one page to another.

Now we can try again to suspend the app using the Suspend and shutdown option offered by Visual Studio: now the application will behave as expected and the content of the TextBox control will still be there.

Important! It’s crucial to remind that this approach has to be used to save the page’s state, not the application data. Data generated by the user has to be saved as soon as possible, to minimize data loss in case of unexpected errors. During the suspension, you have between 5 and 10 seconds to complete all the pending operations, which may not be enough to save all the data handled by your application. The only data we need to save during suspension are the one that makes easier for the developer to create the illusion that the app has never been closed, even if it was silently terminated by the operating system.

Access to the UI thread

Sometimes you may have the requirement, inside a ViewModel, to perform some operations on background threads. In this case, if we try to directly access to one of the UI controls (for example, because we need to change the value of a property which is connected to a control in the View), we ill get an exception: the reason is that we’re trying to access to the UI thread from a secondary one.

The Windows Runtime offers a class called Dispatcher to solve this problem: it’s a sort of “mailman”, which is able to dispatch some operations to the UI thread, regardless of the thread where the execution is happening. Also in this case, we’re talking about a class which can be easily accessed from a code-behind class, but the same doesn’t apply to an independent class like a ViewModel. Template10 includes a helper that makes easier to access to the dispatcher also from a third party class, like a ViewModel, by exposing a property called Dispatcher as part of the ViewModelBase infrastructure:

await Dispatcher.DispatchAsync(() => 
{ 
    //do something on the UI thread 
}); 

Using it is very easy: just call the DispatchAsync() method of the Dispatcher class by passing, as parameter, an Action with the operations that you want to perform on the UI thread.

Wrapping up

Template10 can be really helpful when you’re working with the MVVM pattern in a Universal Windows app: you can focus on getting things done, rather than trying to reinvent the wheel every time to handle the fundamentals of Universal Windows app development. However, Template10 is still growing and the number of services that will make easier to integrate Windows features into a ViewModel will continue to grow!

For the moment, we’ve finished our journey to discover the Template10 features, but I’m sure we’ll have the chance to talk about it again in the future. Don’t forget that you can find all the information about the project, in addition to many samples, on the official GitHub repository https://github.com/Windows-XAML/Template10

Posted in Universal Apps, wpdev | Tagged , , | 5 Comments

Template10: a new template to create Universal Windows apps – The controls

In the previous post we started to know Template10, the new open source template developed by a Microsoft, with the goal to become the starting point for every Universal Windows app developer. In this post we’re going to see some cool custom controls provided by the library.

The PageHeader control

One of the new features available in Windows 10, when it comes to design the user interface, is the improved flexibility regarding the application bars. In Windows and Windows Phone 8.1 you were able to place an application bar only at the bottom of the screen. Only in Windows 8.1 you were allowed to have a top application bar, but not for commanding purposes: it had to be used to make easier for the user to navigate through the sections of the application.

The bottom application bar was implemented using a control called CommandBar, which makes easier for the developer to quickly add buttons so that that the user can interact with the content on the screen. Windows 10 allows, instead, to place the CommandBar control also at the top. The PageHeader control is an extension of the CommandBar one, so that you can use it not just to provide commands to the user, but also to act as a real header of the page. Thanks to this control, it will be easier to implement the same look & feel offered by many native applications like News or Money, which offer an header with the tile of the page and a set of buttons to handle navigation or content interaction.

The first step to add a PageHeader control is to declare in the XAML page the required namespace, which is Template10.Controls, like in the following sample:

<Page
    x:Class="Controls.Views.MainPage"
    xmlns:controls="using:Template10.Controls"
    mc:Ignorable="d">

    
</Page>

Now you can add the control to your page by using the following code:

<controls:PageHeader Frame="{x:Bind Frame}" />

One of the key properties is called Frame. As we’re going to se later, one of the key features provided by the control is the built-in management of the navigation framework. To make this feature working, we need to connect to the PageHeader control the application’s frame, which handles the pages and the navigation between them: we can do it using the new x:Bind markup extensions, which is able to perform a binding with objects exposed by the code behind class.

This is how the standard PageHeader control looks like:

 

clip_image002

Customizing the control

The key property to customize the PageHeader control is Text, which allows to set the text that is displayed in the header (typically, the title of the page). Eventually, you can also customize the standard color that is assigned to the text and to the background, by using the HeaderForeground and HeaderBackground properties. The following samples shows a customized header, with a red text and an orange background.

<controls:PageHeader Text="Main Page" Frame="{x:Bind Frame}" HeaderBackground="Orange" HeaderForeground="Red" />

clip_image004

Handle navigation

The PageHeader control offers a built-in back button to handle the navigation towards the previous page of the application, which is controlled by a property called BackButtonVisibility. When this property is set to Visible, the button is displayed at the left of the header’s text.

<controls:PageHeader Text="Detail" Frame="{x:Bind Frame}" BackButtonVisibility="Visible" />

clip_image006

However, it’s very important to highlight that the button’s visibility isn’t controlled just by this property, but also by the operating system, which can override our configuration. Specifically:

  1. The control, thanks to the Frame property, is connected to the navigation’s frame. Consequently, it’s able to automatically detect if there are pages in the back stack so that if it’s empty (for example, because you’re in the main page), the button will always be hidden.
  2. Windows 10 can run on multiple devices, which can offer a different navigation experience. If, on the desktop, we have more freedom (we can use the virtual back button embedded in the chrome or include it in the UI of the application), on mobile instead you need to leverage the hardware back button available on every device. As such, if you set the BackButtonVisibility property of the control to Visible but the app is running on a phone, the button will be hidden anyway.
  3. On desktop, as we’ve seen in the previous post, we have the chance to leverage a virtual back button, which is added on the app’s chrome, to handle the navigation. If we have enabled this option (which Template10 applies by default but that can be controlled by the ShowShellBackButton property of the BootStrapper class), the PageHeader control’s button will be hidden anyway.

The commands

As mentioned in the beginning of the post, PageHeader extens the CommandBar control, which is used to add an application bar with one or more commands, so that the user can interact with the current content. Consequently, the PageHeader control offers the same features of the CommandBar one and follows the same principles:

  • Inside the PrimaryCommands collection you can add one or more buttons, which will always be visible and represented by an icon and a label.
  • Inside the SecondaryCommands collection you can add one or more buttons which, instead, will be hidden by default: the user will be able to see them only by tapping on the three dots displayed at the end of the bar. Secondary commands are represented only with a label.

Inside the two collections you don’t have the freedom to add any XAML control, but there’s a specific subset of controls which has been designed to work with a CommandBar. The most used one is AppBarButton, which represents a button that the user can press. It can have an image (defined by the Icon property) and a description (defined by the Label property) and you can subscribe to the Click event to handle the user’s interaction.

The following sample code defines a PageHeader control with one primary command and two secondary commands:

<controls:PageHeader Text="Main Page" Frame="{x:Bind Frame}">
    <controls:PageHeader.PrimaryCommands>
        <AppBarButton Icon="Forward" Label="Next" Click="OnNextClicked" />
    </controls:PageHeader.PrimaryCommands>
    <controls:PageHeader.SecondaryCommands>
        <AppBarButton Label="Option 1" />
        <AppBarButton Label="Option 2" />
    </controls:PageHeader.SecondaryCommands>
</controls:PageHeader>

clip_image008

 

It’s really important to evaluate how many buttons you want to add in the control, especially if you’re application targets multiple families of devices. For example, the usage of many primary commands isn’t a big deal on the desktop: since the screen is bigger and usually in landscape, there’s plenty of available space. The same rules don’t apply to a smartphone: in this scenario, it’s better to reduce the number of primary commands and rely more on the secondary ones.

The following image shows the same layout with three primary commands: you can notice how it works perfectly on the desktop, but it messes up on the mobile (due to the reduced space, the buttons overlaps with the header’s text).

 

clip_image010

 

The HamburgerMenu control

Another new Windows 10 feature is the SplitView control, which can be used to implement navigation experiences based on the hamburger menu in your applications. This approach is based on a side panel (typically, it’s placed on the left of the screen) which the user can expand by tapping a button on the top of the panel (usually, in the top left corner). Inside the panel you can usually find multiple items, which can be used to quickly jump from one section to another of the application. The name comes from the fact that the button to show or hide the panel is visually represented by thee lines, one on top of the other, which look like a hamburger between two pieces of bread.

Many native applications are using this approach, like News (which uses the panel to give access to the different sections of the app) or Mail (which, instead, uses the panel to show the available mail accounts with their sub folders).

The SplitView control is just one of the many controls that are available to define the navigation experience of your application: it’s not the only one and Microsoft doesn’t want to force you to use it in any application you create. It’s up to the developer to find the navigation approach that works best for him. Consequently, the SplitView control leaves a lot of freedom to the developer. It just gives you an easy way to split the page in two parts: a sliding panel and the main content. It’s up to you to define the look & feel of both parts.

The downside of this freedom is that we have a bit of work to do if we want, instead, implement a traditional hamburger menu navigation, similar to the one used by some native apps. Template10 simplifies a lot our job since:

  1. It offers a control called HamburgerMenu, which makes easier to define the panel that will contain the list of application’s sections.
  2. It offers a way to create a shell, which is a special page that will act as a container for the application. The shell will contain the menu, while the content area will be filled with the various pages of the application.
  3. It offers a set of built-in styles to recreate a panel with the same look & feel of the one used by native apps (highlight of the current section, icon support, etc.)

Thanks to Template10 we’ll be able to achieve a result very close to the following one:

clip_image012

Let’s see how to implement it.

The HamburgerMenu control

Like the PageHeader control, the HamburgerMenu one is defined inside the Template10.Controls namespace, which you need to add in the XAML declaration. After that, you’ll be able to add it into a page:

<controls:HamburgerMenu x:Name="Menu" />

Customization is allowed thanks to the following properties:

  • HamburgerBackground and HamburgerForeground define the background and foreground color of the hamburger button (the one used to show / hide the panel)
  • NavButtonBackground and NavButtonForeground define the background and foreground color of the buttons in the panel.
  • NavAreaBackground defines the background color of the panel.

An important feature offered by the HamburgerMenu control, compared to the standard SplitView one, is built-in support to two categories of commands, similarly to the PageHeader control:

  • PrimaryButtons identifies the most used sections of the your application and they are placed at the top of the panel, right below the hamburger button.
  • SecondaryButtons identifies the sections of your app that the user will probably visit less frequently, like the Settings or the About page. They are displayed at the bottom of the panel, with a separator at the top.

Inside both collections you can leverage a specific control offered by Template10 called NavigationButtonInfo, which will recreate for you the look & feel of the buttons you can find in the native application. Under the hood, it’s based on the RadioButton control, since it already implements a set of features that are ideal for our scenario (mutual choice between each button, highlight of the currently selected item, etc.)

The following sample shows a complete definition of the HamburgerMenu control:

<controls:HamburgerMenu x:Name="Menu"
                        HamburgerBackground="#FFD13438"
                        HamburgerForeground="White"
                        NavAreaBackground="#FF2B2B2B"
                        NavButtonBackground="#FFD13438"
                        NavButtonForeground="White">

    <controls:HamburgerMenu.PrimaryButtons>
        <controls:NavigationButtonInfo PageType="views:MainPage" ClearHistory="True">
            <StackPanel Orientation="Horizontal">
                <SymbolIcon Symbol="Home" Width="48" Height="48" />
                <TextBlock Text="Home" Margin="12, 0, 0, 0" />
            </StackPanel>
        </controls:NavigationButtonInfo>
            
        <controls:NavigationButtonInfo PageType="views:DetailPage">
            <StackPanel Orientation="Horizontal">
                <SymbolIcon Symbol="Calendar" Width="48" Height="48" />
                <TextBlock Text="Calendar" Margin="12, 0, 0, 0" />
            </StackPanel>
        </controls:NavigationButtonInfo>
    </controls:HamburgerMenu.PrimaryButtons>
        
    <controls:HamburgerMenu.SecondaryButtons>
        <controls:NavigationButtonInfo PageType="views:SettingsPage">
            <StackPanel Orientation="Horizontal">
                <SymbolIcon Symbol="Setting"  Width="48" Height="48" />
                <TextBlock Text="Settings" Margin="12, 0, 0, 0" />
            </StackPanel>
        </controls:NavigationButtonInfo>
    </controls:HamburgerMenu.SecondaryButtons>
        
</controls:HamburgerMenu>

The samples shows a menu with one primary command and one secondary command. Every button is represented with a NavigationButtonInfo control, which has a key property called PageType. You can use it to specify which is the page of your application connected to this button: when the user will tap on it, he will be automatically redirected to that page. Additionally, there are two other properties to customize the navigation experience:

  • ClearHistory is a boolean that, when it’s set to true, forces the cleanup of the back stack. It’s typically used with the main section of the application, to avoid circular navigation issues (when the user is on the main page of the app and the back button is still enabled).
  • PageParameter is helpful if you need to pass a parameter to the landing page, which can be retrieved using the OnNavigatedTo() method.

The look & feel of the button is up to the developer: inside the NavigationButtonInfo control you can include any XAML control. In the sample you can see a definition that will help you to recreate the same look & feel of native apps: an icon (defined by the SymbolIcon control) and a label (defined with a TextBlock control). Here is how the previous code becomes when the app is running:

 

clip_image014

clip_image016

The HamburgerMenu control, to work properly, needs a reference to the NavigationService, which is the service provided by Template10 to handle the navigation. This reference is configured in code-behind, thanks to the NavigationService property offered by the control:

public sealed partial class Shell : Page
{
    public Shell(NavigationService navigationService)
    {
        this.InitializeComponent();
        Menu.NavigationService = navigationService;
    }
}

In the next section we’re going to learn how to pass a reference to the NavigationService to the page that contains the HamburgerMenu control, like we’ve seen in the previous sample.

Create the shell

In the previous sections we’ve learned how, thanks to Template10, it’s easy to implement a navigation pattern based on the hamburger menu. However, we have a problem: the HambrgerMenu is just a control and, consequently, you need to add it to a page but, at the same time, you need to handle that every page of your application will reuse the same menu.

Let’s introduce the shell, which is a special page of the application that will act as a container for the pages of the application. By using this approach, the HamburgerMenu control will be defined just once inside the shell and, consequently, we won’t have to include it in every page of the application. The first step is to create an empty page in our project and to repeat the steps we’ve already done in the previous section, which are including a HamburgerMenu control and connecting the NavigationService, like in the following sample:

<Page
    x:Class="HamburgerSample.Views.Shell"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:views="using:HamburgerSample.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:controls="using:Template10.Controls"
    x:Name="ThisPage"
    mc:Ignorable="d">

    <controls:HamburgerMenu x:Name="Menu">
        
        <controls:HamburgerMenu.PrimaryButtons>
            <controls:NavigationButtonInfo PageType="views:MainPage" ClearHistory="True">
                <StackPanel Orientation="Horizontal">
                    <SymbolIcon Symbol="Home" Width="48" Height="48" />
                    <TextBlock Text="Home" Margin="12, 0, 0, 0" />
                </StackPanel>
            </controls:NavigationButtonInfo>

            <controls:NavigationButtonInfo PageType="views:DetailPage" >
                <StackPanel Orientation="Horizontal">
                    <SymbolIcon Symbol="Calendar" Width="48" Height="48" />
                    <TextBlock Text="Calendar" Margin="12, 0, 0, 0" />
                </StackPanel>
            </controls:NavigationButtonInfo>
        </controls:HamburgerMenu.PrimaryButtons>

        <controls:HamburgerMenu.SecondaryButtons>
            <controls:NavigationButtonInfo PageType="views:SettingsPage">
                <StackPanel Orientation="Horizontal">
                    <SymbolIcon Symbol="Setting"  Width="48" Height="48" />
                    <TextBlock Text="Settings" Margin="12, 0, 0, 0" />
                </StackPanel>
            </controls:NavigationButtonInfo>
        </controls:HamburgerMenu.SecondaryButtons>

    </controls:HamburgerMenu>
</Page>

public sealed partial class Shell : Page
{
    public Shell(NavigationService navigationService)
    {
        this.InitializeComponent();
        Menu.NavigationService = navigationService;
    }
}

Now we need to:

  1. Configure the page we’ve just created as container for all the page of our application, by replacing the standard frame.
  2. Pass to the page a reference to the NavigationService object

Both operations can be achieved in the BootStrapper class: we’re going to use the OnInitializeAsync() method, which is performed right before the app triggers the navigation to the main page.

sealed partial class App : BootStrapper
{
    public App()
    {
        this.InitializeComponent();
    }

    public override Task OnInitializeAsync(IActivatedEventArgs args)
    {
        var nav = NavigationServiceFactory(BackButton.Attach, ExistingContent.Include);
        Window.Current.Content = new Views.Shell(nav);
        return Task.FromResult<object>(null);
    }

    public override Task OnStartAsync(BootStrapper.StartKind startKind, IActivatedEventArgs args)
    {
        NavigationService.Navigate(typeof(Views.MainPage));
        return Task.FromResult<object>(null);
    }
}

The first step is to use the NavigationServiceFactory method to retrieve the proper reference to the NavigationService. This way, we can pass it as a parameter when we create a new instance of the Shell page. Then we assign this instance to the Window.Current.Content property, which holds a reference to the main frame of the application, which will act as a container for the pages. In a standard application, this property is simply set with a new instance of the Frame class.

Thanks to this line of code, the application won’t use anymore an empty frame as a container for your pages, but the Shell page, which contains the HamburgerMenu definition. The final result will be that all the pages of your application will share the same menu we have defined in the Shell page.

HamburgerMenu and PageHeader: the dynamic duo

The PageHeader and HamburgerMenu controls have been designed to work together. The best visual layout, in fact, can be achieved when the various sections in a hamburger menu are handled with a page that has a PageHeader control to define the header.

Moreover, both controls supports the adaptive layout, which is the new approach introduced in Windows 10 to help developers building a single binary package that can runs on every platform (vice versa, on Windows and Windows Phone 8.1 you needed to create and publish two different packages). Adaptive layout is an approach which is already widely used in the web world and it simply means that the user interface has to properly react to the changes in the window’s size, so that the app can always offer the best user experience, regardless if it’s running on a mobile phone or on a console.

Both controls implements this approach to optimize the user experience:

  • By default, the PageHeader control doesn’t add any margin to the text of the header. When the app’s windows is wide enough, the HamburgerMenu control will always be visible in minimal mode (which means that the icons will always be visible, while the labels will be displayed only when the panel is open). Consequently, there’s no need to artificially add a margin in the PageHeader control: the hamburger button of the menu already takes care of it.
  • When the size of the window is smaller (for example, on a phone) there isn’t enough space to keep the menu icons always visible. Consequently, the panel is completely hidden: only the hamburger button will be visible. In this scenario, the PageHeader control adds a 48px margin on the left, to avoid that the header’s text overlaps with the button.

This behavior is automatically handled by both controls. However, you have the chance to define which is the size of the window that should trigger the two visual states, by using the VisualStateNarrowMinWidth and VisualStateNormalMinWidth properties. Take a look at the following sample:

<controls:PageHeader Text="Main page" Frame="{x:Bind Frame}"
                     VisualStateNarrowMinWidth="0"
                     VisualStateNormalMinWidth="700" />

With this configuration:

  • When the width of the window is between 0 and 700, the control applies the VisualStateNarrow visual state, which is the minimal one (the panel is hidden and the header’s text is shifted).
  • When the width of the window is bigger than 700, instead, the control applies the VisualStateNormal visual state, which is the standard one (the panel is visible in minimal mode and a shift of the header’s text isn’t required).

The same properties are available also in the HamburgerMenu control: of course, to get the best result, it’s important that the two properties are set in the same way on both controls. The following images will help you to understand better the difference between the two states: the first one is the normal state, the second one is the narrow state.

clip_image017

clip_image019

If you want to disable this behavior for the PageHeader control (for example, because you aren’t providing a hamburger menu based navigation experience and, as such, the shift of the header’s text can break your layout) it’s enough to set the VisualStateNarrowMinWidth property to –1.

Wrapping up

In this post we’ve learned how to use the custom controls offered by Template10. In the next post, instead, we’ll see more C# code, since we will focus on how Template10 can make easier the implementation of the MVVM pattern.

As a reminder, you can find Template10 on GitHub (http://github.com/Windows-XAML/Template10/). The repository contains also a set of samples to start playing with the controls described in this post. Happy coding!

Posted in Universal Apps | Tagged , , | 1 Comment

Template10: a new template to create Universal Windows apps – The basics

When you launch Visual Studio 2015 to create a Universal Windows app for Windows 10 for the first time, the first thing you notice is that the number of available templates is very low. If, when it comes to Windows / Windows Phone 8.1 development, Visual Studio 2013 offered many templates to quickly implement the most used layouts (Hub, Pivot, etc.), in Visual Studio 2015 we have just one template called “Blank app”.

The reason of this choice is that, in the past, the standard templates were used by the developers without very good skills in developing the user experience of an application (like me Smile ) to make the job easier and to avoid to create the user interface from scratch. The downside of this approach is that, during the course of time, it leads many developers to publish a lot of applications that looked very similar to each other. Consequently, Microsoft has decided, with Windows 10, to leave more freedom to the developers and to avoid forcing them to adopt a specific design patter. It’s important to highlight, however, that this doesn’t mean that you can do whatever you want when it comes to create the user interface, without following any criteria. Providing a great user experience is still one of the key pillars to create a successful app! As such, I strongly suggest to read the official guidelines to design Universal Windows apps on the Dev Center: https://dev.windows.com/en-us/design

The new blank template provided by Visual Studio 2015 is very simple and it’s the perfect starting point for every application. However, sometimes, especially when you need to work on a complex project, it can be even too simple. When we need to handle advanced scenarios (like using the MVVM pattern or managing the state of the page) we need to create all the required infrastructure.

To make the life the developers easier, a team of Microsoft people, lead by Jerry Nixon (a Technical Evangelist very well known for his series of MVA trainings about Windows 10 development) have started to work on an advanced template called Template10. It’s an open source project, available on GitHub at https://github.com/Windows-XAML/Template10 and, as such, you’re more then welcome to give your contribute, by helping with the documentation or by making some enhancements and submitting a pull request.

The project is still evolving, but the goal is very clear: Template10 wants to become the preferred choice for Universal Windows apps developers, independently from the development approach they prefer (code behind, MVVM, etc.) or from the toolkits and libraries they already use in their applications. If you want to learn more about the project, you can read the official FAQ on https://github.com/Windows-XAML/Template10/wiki/Questions. In the near future, Template10 will be released as a NuGet package and as a Visual Studio extension. This way, you’ll be able to use it as a starting point for your app directly from the New project menu in Visual Studio 2015. Meanwhile, however, even if the main library that defines the template’s components is considered stable and ready for production, it’s available only on GithHub. Let’s see which are the required steps to start creating a new Universal Windows app using Template 10.

UPDATE: Template10 is now available also as NuGet package: http://www.nuget.org/packages/Template10/1.0.2.2-preview. However, to find and install it, you’ll need to enable in the NuGet Package Manager UI the Include prerelease options, since the package is still in beta.

This post is just the first of a series: in this one we’re going to see the basic concepts. In the next ones, we’ll see some more advanced topics like the available controls or the MVVM pattern.

Create the first project

The first step is to clone the GitHub repository. We can achieve this goal using the tools provided directly by Visual Studio 2015.

  1. Open the window called Team Explorer. As default behavior, it’s placed on the right side of the screen, in the same section where you have access to the Solution explorer’s window.
  2. You’ll find a section labeled Local Git Repositories, which lists all the Git repositories on your computer. Press the Clone button.
  3. In the first field (the one with the yellow background) you need to specify the URL of the GitHub repository, which is https://github.com/Windows-XAML/Template10
  4. In the second field, instead, you need to set the local path on your computer where you want to clone the project.
  5. Now press the Clone button: Visual Studio will take care of downloading the project and copying it on your computer.

 

From now on, by using Team Explorer, you’ll be able to quickly access to the repository. By using the Sync option you’ll have the chance to keep the local repository up to date with the latest version of the library.

A good starting point for a new Universal Windows app based on Template10 is to use the Blank project, which is stored inside the Templates (Project) folder. This project already provides the basic infrastructure required by Template10 to work properly. However, in this post we’re going to start with an empty project and to manually configure Template10: this way, it will be easier to understand how it works under the hood.

Let’s start by creating a new Universal Windows app with the Blank app template provided by Visual Studio. Then, let’s right click on the solution in Solution Explorer and choose Add existing project. We’ll have to look for the folder where we’ve cloned the GitHub repository and, specifically, we’ll have to find the project named Template10Library: you’ll find in the folder with the same name and it’s defined by the Template10Library.csproj file. Once you’ve added the project to your solution, it’s time to add a reference to Template10 in our app. Just right click on the project of the application, choose Add reference and, in the list, choose the Template10 project. Now we are ready to start writing some code!

The bootstrapper

The App class is the starting point of every Universal Windows app: its goal is to initialize the main window of the application with its frame, which acts as a container of all the pages of the application and provides the necessary infrastructure to handle the navigations. The base structure of the App class (stored in the App.xaml.cs file), however, can be a little bit confusing, especially for new developers. You’ll find a lot of fixed code, which is part of the standard initialization and, as such, it creates just “noise”, since you’ll probably never change it. Another weak point is the application’s lifecycle management. The App class offers different event handlers to manage the different application’s state (launching, suspending, resuming, etc.) but, based on the activation’s type, you can have multiple entry points. Template10 makes the initialization of the app easier to understand and to use by providing a bootstrapper, which is a class that replaces the App one and that simplifies the code. The first step to use is to replace the App class with the BootStrapper one, which is included in the Template10.Common namespace. Here is a sample definition:

<common:BootStrapper
        x:Class="BasicSample.App"
        xmlns:common="using:Template10.Common"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

</common:BootStrapper> 

You can notice that the main App node has been replaced with the BootStrapper one. Consequently, you will have also to update the code-behind class (the App.xaml.cs file), so that the App class inherits from the BootStrapper one, like in the following sample:

sealed partial class App : Template10.Common.BootStrapper
{ 
    public App() 
    { 
        InitializeComponent(); 
    } 

}

Here is, instead, how a complete definition of the BootStrapper class looks like:

sealed partial class App : Template10.Common.BootStrapper
{
    public App()
    {
        InitializeComponent();
    }

    public override Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
    {
        NavigationService.Navigate(typeof(MainPage));
 return Task.FromResult<object>(null);
    }
}

You can immediately notice how, compared to the standard App class, the code is much more simple to understand. The core is the OnStartAsync() method, which is the starting point of the application, regardless from the activation’s scenario. No matter if the app has been opened using the main tile, a secondary tile or from a toast notification, the OnStartAsync() method will always be invoked to let you, as developer, handling the main navigation. In the simplest scenario (your app doesn’t have secondary tiles or doesn’t support secondary activation entries), the method will look like the one in the sample: it simply takes care of redirecting the user to the main page of the application. The second operation is just a workaround to support asynchronous code inside this method. To properly support async / await operations, the method has been configured to return a Task object; however if, like in this case, you don’t have the requirement to perform any asynchronous operation, we simply return an empty Task, so that the code can compile.

The main advantage of the OnStartAsync() method is that the bootstrapper, under the hood, always takes care of preparing the Frame, which is required to handle the rendering and the navigation of the pages of the application. The standard App class, instead, takes care of initializing the Frame only in the main entry point (the OnLaunched() event handler), leaving you to do all the “dirty work” in case the app has been opened from a different activation point.

To help you understanding better this approach, here is a sample bootstrapper used to handle the activation from a secondary tile:

sealed partial class App : Template10.Common.BootStrapper
{
    public App()
    {
        InitializeComponent();
    }

    public override Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
    {
        AdditionalKinds cause = DetermineStartCause(args);
        if (cause == AdditionalKinds.SecondaryTile)
        {
            LaunchActivatedEventArgs eventArgs = args as LaunchActivatedEventArgs;
            NavigationService.Navigate(typeof (DetailPage), eventArgs.Arguments);
        }
        else
        {
            NavigationService.Navigate(typeof (MainPage));
        }

        return Task.FromResult<object>(null);
    }
}

The code is very simple to understand. Thanks to the internal method DetermineStartCause() we are able to determine which is the activation point of the app and to redirect the user to the most appropriate page. In the sample we are handling the scenario where the tap on a secondary tile redirects the user to a specific item of the application (like a category of news): in case the activation’s cause is AdditionalKinds.SecondaryTile, we retrieve the tile’s arguments (thanks to the Arguments property) and we pass it to the page called DetailPage. In case, instead, the application has been regularly launched using the main tile, the user is simply redirected to the main page.

With the same approach we can handle all the other activation’s scenarios: from a toast notification, from a uri, from a sharing contract, etc. In this case, the DetermineStartCause() method will return you the Other value of the AdditionalKinds enumerator. To properly determine what’s happened, we need to use the Kind property of the activation’s parameter which type is IActivatedEventArgs.

Inside the bootstrapper class you have also the chance to override three other methods, which can be useful to handle special scenarios.

  1. OnInitializeAsync() is invoked when the app is initialized, right before calling the OnStartAsync() method. It’s useful if you have any service or feature that requires to be initialized at startup (for example, analytics services like Application Insights).
  2. OnResuming() has the same purpose of the method with the same name of the standard App class and it’s invoked when the application is resumed after it has been suspended. Typically, you’re not required to handle this event; the reason is that it’s triggered only when the application has been resumed from a suspension state and not from a termination. As such, since the process was kept in memory, you don’t have to retrieve the state you may have previously saved, since it’s still there. This method can be useful if you need to refresh the data in case, for example, the user has resumed the application after a while.
  3. OnSuspending() is invoked when the application is suspended. Typically, this method is used to save the application’s state, so that it can be restored in the case the app is terminated by the operating system due to low resources. However, as we’re going to see in the next posts, with Template10 this operation is not required: the bootstrapper is able to take care of this scenario automatically.

Extended splash screen

The splash screen is a static image (placed in the Assets folder of your project) which is displayed to the user during the app’s initialization phase. Once the operation is completed, the splash screen is removed from the screen and the Frame redirects the user to the main page of the app. As best practices, the app’s initialization should be as quickest as possible: if the operation isn’t completed within 10 seconds, the app will be terminated by the OS. However, it’s not uncommon that the app may need more than 10 seconds to be ready, especially if the application’s data has to be downloaded from a remote source (like a REST service). To avoid the app to be terminated by the OS, one of the best practices is to avoid loading the data in the App class, but to perform it directly in the main page of the app. This way, the initialization phase will be very quick and the main page will immediately take control of the app. However, since the app is now ready and the initialization operation is completed, the OS won’t try to kill the app anymore, even if the main page would need more than 10 seconds to load all the data.

This approach works great, but often it doesn’t provide a good user experience: the user is redirected to the main page of the app which, however, will be empty and it will display just a loading message, until all the data is ready to be displayed. To improve the UX many applications have introduced the concept of extended splash screen: after that the basic initialization is completed, the user will be redirected to another page of the app which will look exactly like the splash screen. The difference here is that, since we aren’t talking anymore about a static image but we’re dealing with a real page, we can add additional UI elements to notify to the user that a loading operation is in progress (like a ProgressBar or a ProgressRing control). If you want to learn more about this topic, the MSDN documentation offers some guidance on how to implement an extended splash screen at https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868191.aspx

As you can see in the document, there’s a bit of work to do, other than just creating the page that will act as extended splash screen. Template10 simplifies this approach, by offering a class that takes care of handling the transition between splash screen –> extended splash screen –> first page of the app. Let’s see how to use it.

The first step is to create the splash screen itself, by adding a new UserControl to your application. You have the freedom to add everything you want in this control. However, since the goal of this control is to hide the transition from the static splash screen, typically the first thing you want to add is an Image control that displays the same image used as splash screen. The following sample shows a control where the image is placed inside a Canvas with the same background color of the image. In addition, we add a ProgressRing control to notify to the user that a loading operation is in progress.

<UserControl
    x:Class="BasicSample.Views.SplashScreenView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid>
        <Canvas x:Name="MyCanvas" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#0971C3">
            <Image x:Name="MyImage" Stretch="None" Source="/Assets/SplashScreen.png" />
        </Canvas>
        <ProgressRing VerticalAlignment="Bottom" HorizontalAlignment="Center" Width="50" Height="50" IsActive="True" Foreground="White"
                      Margin="0, 0, 0, 100"/>
    </Grid>
</UserControl>

In code behind we use the SplashScreen class (which returns some important information about the image, like the size and the position) to configure the Image control in the same way. This way, the user won’t notice the transition from the real splash screen to the extended one.

public sealed partial class SplashScreenView : UserControl
{
    public SplashScreenView(SplashScreen splashScreen)
    {
        this.InitializeComponent();
        Action resize = () =>
        {
            MyImage.Height = splashScreen.ImageLocation.Height;
            MyImage.Width = splashScreen.ImageLocation.Width;
            MyImage.SetValue(Canvas.TopProperty, splashScreen.ImageLocation.Top);
            MyImage.SetValue(Canvas.LeftProperty, splashScreen.ImageLocation.Left);
        };
        Window.Current.SizeChanged += (s, e) => resize();
        resize();
    }
}

The resize and reposition operations are defined into an Action which, other than being executed when the user control is initialized, is connected also to the SizeChanged event, which is triggered when the size of the app’s window changes. It’s required since, when the app runs on a desktop, the user is able to resize the window at any time and, consequently, the splash screen needs to readapt itself.

Now that we have created our custom control, we are ready to use it as a splash screen, thanks to the SplashFactory class provided by the BootStrapper:

public App()
{
    InitializeComponent();
    SplashFactory = e => new SplashScreenView(e);
}

SplashScrenView is the name of the UserControl we have just created, while e is the instance of the SplashScreen class that we have passed to the control’s constructor (it’s the one we’ve used to calculate the size and the position of the image).

Now we’re ready to test it: as soon as the application takes more than a few seconds to initialize, the user will be redirected to the extended splash screen and, only at the end of the loading process, to the main page of the app. If you want to simulate a heavy data loading to test the splash screen, you can add a delay in the OnStartAsync() method, before the navigation to the main page is performed, like in the following sample:

sealed partial class App : Template10.Common.BootStrapper
{
    public App()
    {
        InitializeComponent();
        SplashFactory = e => new SplashScreenView(e);
    }

    public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
    {
 await Task.Delay(TimeSpan.FromSeconds(5));
        NavigationService.Navigate(typeof(MainPage));
    }
}

Once the initialization is completed, the bootstrapper will invoke the OnStartAsync() method and, until it’s triggered the navigation to the main page of the page, the extended splash screen will be displayed. In this sample, since we’ve added a 5 second delay, the splash screen will be displayed for 5 seconds before the user will see the main page.

Navigation

Another important feature offered by Template10 is the automatic handling of the page stack. If you already have some experience in developing Windows Store apps for Windows and Windows Phone 8.1, you’ll know that navigation management is one of the main differences between the two platforms. On Windows Phone, you don’t have to add any visual element in the user interface to allow the user to go back to the previous page of the app, since every device has a hardware Back button. However, the same doesn’t apply on Windows, since there is no Back button on a desktop or on a tablet.

Windows 10 has changed this behavior; also the desktop version, in fact, offers a build-in management of the Back button, by providing a virtual back button which can be placed in different positions, based on the scenario:

  1. If the app is running in desktop mode, the Back button will be added in the app’s chrome, on the top right corner.
  2. If the app is running in tablet mode, the Back button will be added in the system bar, between the Start and Cortana buttons.

 

 

Typically, in a standard application, it’s up to the developer to handle this feature, by using the SystemNavigationManager class, which provides the required APIs to handle the visibility of the button or the navigation events. Template10, instead, automatically enables this management on every device family. Consequently:

  • When the application is running on the desktop and the page stack isn’t empty, on the top right corner the virtual Back button will be visible. If, instead, the stack is empty (for example, because the user is on the first page), the button will be automatically hidden.
  • When the application is running on a mobile device, pressing the hardware Back button will automatically redirect the user to the previous page of the app or, if the stack is empty, to the Start screen of the device.

If we want to disable this behavior (for example, because we want to handle the navigation by ourselves, by adding a button in the UI) we can set the ShowShellButton property of the BootStrapper class to false:

public App()
{
    InitializeComponent();
    ShowShellBackButton = false;
}

When this option is disabled, you will notice that the virtual Back button in the app’s chrome will never be displayed.

In the next post

In this post we’ve learned some of the basic concepts of Template10 and which are some of the features that we can start to use, right away, to improve our application. We’ve just scratched the surfaced and, in the next posts, we’re going to see the “true power” of Template10, especially when it’s used in combination with the MVVM pattern. If, in the meanwhile, you want to start doing experiments with Template10, you can use the samples that are provided on the GitHub repository. Happy coding!

Posted in Universal Apps | Tagged , , | 5 Comments