Prism and Universal Windows app – Managing the application’s lifecycle

Unless this is your first experience with Windows Store app development, you should be familiar with the concept of “application lifecycle”. Windows Store apps are created for scenarios where battery life, memory and CPU are not unlimited: consequently, the old desktop approach, where applications are able to keep running in background for an indefinite time, doesn’t fit well this new modern world, where PCs aren’t anymore the only device used to connect to the Internet, work, play, etc.

When a Windows Store isn’t in foreground anymore (because the user has returned to the Start screen, he has launched another application, he has tapped on a toast notification, etc.) it’s suspended after 10 seconds: the process is kept in memory, but all the running operations (network connections, thread, etc.) are stopped. The application will continue to use RAM memory, but it won’t be able to “steal” CPU power, network, etc. to the other applications. This way, every other application will be able to use the same resources of the previously opened ones. However, RAM memory isn’t infinite: consequently, when it’s running low, the operating system is able to terminate the older applications, to free some memory.

However, this termination should be transparent to the user: since he didn’t explicitly close the application (by using the task switcher in Windows Phone or by dragging the application from the top to the bottom in Windows, for example), he expects to find it in the same state he left. This is what we, as developers, call “managing the application’s state”: typically, when the application is suspended, we’re going to save in the local storage (which content is persisted across different usages) all the data that we need to recreate the impression that the app has never been closed (the last opened page, the content of a form, etc.). When the application starts, in case it was terminated due to low memory, we need to load this state and to restore the application in the previous state.

In a typical Universal Windows app, we perform this operation in two steps:

  1. The first one is to use the OnNavigatedTo() and OnNavigatedFrom() events exposed by the page to save and restore the page’s state.
  2. The second one is to use the various methods offered by the App class to manage the application’s lifecycle, like OnSuspended() (to save the state) and OnLaunched() (to restore the state, in case we detect that the app was terminated by the operating system).

However, Prism offers a simpler way to manage this scenario. Let’s see the details.

Saving simple data

The simplest scenario is when we need to save plain data, like a text in a TextBox or boolean in a CheckBox. These kind of properties can be automatically saved by Prism when the application is suspended and restored when it’s activated simply by marking them with the RestorableState attribute. Let’s say that you have a page with the following XAML:

<StackPanel Margin="12, 0, 12, 0">
    <TextBox Text="{Binding Path=Name, Mode=TwoWay" />
    <TextBox Text="{Binding Path=Surname, Mode=TwoWay}" Margin="0, 0, 0, 20 "/>
</StackPanel>  

We have added two TextBox controls, which are in binding (in two way mode) with two properties in the ViewModel, called Name and Surname. Let’s see how they’re defined:

public class MainPageViewModel : ViewModel
{
    private string _name;

    [RestorableState]
    public string Name
    {
        get {return _name;}
        set { SetProperty(ref _name, value); }
    }

    private string _surname;

    [RestorableState]
    public string Surname
    {
        get { return _surname; }
        set { SetProperty(ref _surname, value); }
    }
}

You can notice that we’re dealing with two standard properties that, thanks to SetProperty() method offered by Prism, are able to notify the View every time their value changes. However, you can also notice that we’ve decorated the public properties with the [RestorableState] attribute. This is enough to enable the automatic state management by Prism.

Test the scenario is easy, thanks to the tools provided by Visual Studio: launch the application with the debugger connected and write some texts in the two TextBox controls. When the debugging session is running, you’ll find a dropdown menu in the Debug location toolbar (if you can’t see it, just right click in an empty space in the top area and enable it) called Lifecycle Events. This dropdown provides a list of options to simulate the different application’s state, since some of them aren’t deterministic: termination is one of them, since we don’t know if and when the operating system will terminate our application due to low memory. Choose Suspend and shutdown from the menu: the application will be terminated and the debugger disconnected. Now launch again the application: you’ll notice that, despite the fact that the process has been terminated, the two values you’ve inserted in the TextBox controls will still be there. If you launch the application from scratch, instead, the two controls will be empty: it’s correct, because in this case the user is launching the application for the first time or after he explicitly closed it, so he doesn’t expect to find it in the previous state.

4.11

If you want to make sure that it’s not a trick, but Prism is really managing the state for you, just try to remove the [RestorableState] attributes from one of the two properties: if you simulate again the termination, you’ll notice that only the property which is still marked with the attribute will restore its value, while the other TextBox will be empty.

Saving complex data

Another common scenario is when you have to deal with complex data, like classes that are part of your model. Let’s say, for example, that the Name and Surname properties we’ve previously seen compose a class named Person, with the following definition:

public class Person
{
    public string Name { get; set; }
    public string Surname { get; set; }
}

Now let’s change the XAML of our page in the following way:

<storeApps:VisualStateAwarePage
    x:Class="Prism_StateManagement.Views.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Prism_StateManagement.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:storeApps="using:Microsoft.Practices.Prism.StoreApps"
    xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm"
    mc:Ignorable="d"
    mvvm:ViewModelLocator.AutoWireViewModel="True"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <StackPanel Margin="12, 0, 12, 0">
            <TextBox Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
            <TextBox Text="{Binding Path=Surname, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0, 0, 0, 20 "/>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=LatestPerson.Name}" Style="{StaticResource HeaderTextBlockStyle}" />    
                <TextBlock Text="{Binding Path=LatestPerson.Surname}" Style="{StaticResource HeaderTextBlockStyle}" Margin="30, 0, 0, 0"  />
            </StackPanel>
        </StackPanel>   
    </Grid>
    
    <Page.BottomAppBar>
        <CommandBar>
            <CommandBar.PrimaryCommands>
                <AppBarButton Label="Ok" Icon="Accept" Command="{Binding Path=ShowMessageCommand}" />
            </CommandBar.PrimaryCommands>
        </CommandBar>
    </Page.BottomAppBar>
</storeApps:VisualStateAwarePage>

We’ve added a couple of new TextBlock controls, which are in binding with a property in the ViewModel called LatestPerson: by using the dot as separator, we access to the Name and Surname properties of the class. We’ve also added a button in the application bar, which is connected to a command in the ViewModel called ShowMessageCommand. Let’s see, now, the new definition of the ViewModel:

public class MainPageViewModel : ViewModel
{
    private string _name;

    [RestorableState]
    public string Name
    {
        get {return _name;}
        set { SetProperty(ref _name, value); }
    }

    private string _surname;

    [RestorableState]
    public string Surname
    {
        get { return _surname; }
        set { SetProperty(ref _surname, value); }
    }

    private Person _latestPerson;

    public Person LatestPerson
    {
        get {return _latestPerson;}
        set { SetProperty(ref _latestPerson, value); }
    }

    public MainPageViewModel()
    {
        ShowMessageCommand = new DelegateCommand(() =>
        {
            LatestPerson = new Person
            {
                Name = Name,
                Surname = Surname
            };
        });
    }

    public DelegateCommand ShowMessageCommand { get; private set; }
}

We’ve added a new Person property, called LatestPerson, which is the one in binding with the new TextBlock controls we’ve added in the page. We’ve also defined a new DelegateCommand, which name is ShowMessageCommand, that is triggered when you press the button in the application bar: the command simply takes the values inserted by the user in the two TextBox controls in the page and use them to create a new Person object, which is displayed on the page simply by assigning it to the LatestPerson property.

Now let’s say that we want to preserve also the value of the LatestPerson property so that, when the user restores the app, even if it was terminated, both the TextBox controls and the new TextBlock ones will hold the previous value. In this case, we can’t simply add the [RestorableState] attribute to the LatestPerson property, since it’s a complex one. We need to use another approach, thanks to another helper offered by Prism: a class called SessionStateManager. Like the NavigationService, this class is registered in the Unity container in the App class, inside the method OnInitializeAsync():

protected override Task OnInitializeAsync(IActivatedEventArgs args)
{
    // Register MvvmAppBase services with the container so that view models can take dependencies on them
    _container.RegisterInstance<ISessionStateService>(SessionStateService);
    _container.RegisterInstance<INavigationService>(NavigationService);
    // Register any app specific types with the container

    // Set a factory for the ViewModelLocator to use the container to construct view models so their 
    // dependencies get injected by the container
    ViewModelLocationProvider.SetDefaultViewModelFactory((viewModelType) => _container.Resolve(viewModelType));
    return Task.FromResult<object>(null);
}

Thanks to the dependency injection approach, you’ll be able to use the SessioneStateService class simply by adding an ISessionStateService parameter in the ViewModel’s constructor, like in the following sample:

public class MainPageViewModel : ViewModel
{
    private readonly ISessionStateService _sessionStateService;

    public MainPageViewModel(ISessionStateService sessionStateService)
    {
        _sessionStateService = sessionStateService;
    }
}

The SessionStateService class offers a property called SessionState, which type is Dictionary<string, object>: you’ll be able to save, inside this collection, any type of complex data that you want to keep in case of termination. Under the hood, the content of the collection will be serialized in the storage. The SessionStateService class is very useful because it takes care of automatically saving and restoring its content when the app is suspended and resume: as developers, we’ll have just to take to save inside the SessionState collection the data we want to save. That’s it: Prism will take care of saving it when the app is suspended and to restore it in case the app is resumed and it was terminated by the operating system.

Since it’s a standard Dictonary collection, working with is really easy. Here is the complete ViewModel:

public class MainPageViewModel : ViewModel
{
    private readonly ISessionStateService _sessionStateService;
    private string _name;

    [RestorableState]
    public string Name
    {
        get {return _name;}
        set { SetProperty(ref _name, value); }
    }

    private string _surname;

    [RestorableState]
    public string Surname
    {
        get { return _surname; }
        set { SetProperty(ref _surname, value); }
    }

    private Person _latestPerson;

    public Person LatestPerson
    {
        get {return _latestPerson;}
        set { SetProperty(ref _latestPerson, value); }
    }

    public MainPageViewModel(ISessionStateService sessionStateService)
    {
        _sessionStateService = sessionStateService;
        ShowMessageCommand = new DelegateCommand(() =>
        {
            LatestPerson = new Person
            {
                Name = Name,
                Surname = Surname
            };

            if (sessionStateService.SessionState.ContainsKey("Person"))
            {
                sessionStateService.SessionState.Remove("Person");
            }
            sessionStateService.SessionState.Add("Person", LatestPerson);
        });
    }

    public DelegateCommand ShowMessageCommand { get; private set; }

    public override void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
    {
        base.OnNavigatedTo(navigationParameter, navigationMode, viewModelState);
        if (_sessionStateService.SessionState.ContainsKey("Person"))
        {
            LatestPerson = _sessionStateService.SessionState["Person"] as Person;
        }
    }
}

When the ShowMessageCommand is executed, other than just assigning a value to the LatestPerson property, we save it in the SessionState collection, simply by using the Add() method. Then, in the OnNavigatedTo() method (which we’ve discussed in the previous post and it’s triggered when the user navigates to the current page, also in case of resume), we can check if the SessionState contains the value we’ve previously saved, which is identified by the Person key. If it exists, we retrieve it and we assign it to the LatestPerson property, after performing a cast since the SessionState collection contain generic objects.

If you’ll try to execute the application, however, you’ll get an exception when the app is suspended: this happens because Person is a custom class, it’s not part of the Windows Runtime, so Prism doesn’t know how to handle it when it comes to save the state by serializing it. We can solve this problem by overriding a method in the App class called OnRegisterKnownTypesForSerialization(), in which we have to register, in the SessionStateService, every custom class we’re going to use in the application, like in the following sample:

protected override void OnRegisterKnownTypesForSerialization()
{
    base.OnRegisterKnownTypesForSerialization();
    SessionStateService.RegisterKnownType(typeof(Person));
}

We simply call the RegisterKnownType() method, passing as parameter the class’ type (in this case, Person).

That’s all! Now, if you launch the application and, again, by simulating the termination using the Suspend and shutdown option in Visual Studio, you’ll notice that both the simple properties (Name and Surname) and the complex one (LatestPerson) we’ll be correctly restored.

Wrapping up

As usual, you can find the sample project used for this post on GitHub at https://github.com/qmatteoq/Prism-UniversalSample

Index of the posts about Prism and Universal Windows apps

  1. The basic concepts
  2. Binding and commands
  3. Advanced commands
  4. Navigation
  5. Managing the application’s lifecycle
  6. Messages
  7. Layout management

Sample project: https://github.com/qmatteoq/Prism-UniversalSample

Posted in Universal Apps, wpdev | Tagged , , , | 1 Comment

Prism and Universal Windows app – Navigation

Let’s continue our journey about using Prism in Universal Windows app development, by understanding how to manage a very important feature: navigation. Unless we’re talking about a really basic application, your project will likely contain more than one page. Consequently, we need to be able to navigate from one page to another. The problem is that, typically, the operation is performed using the Frame class, which can be accessed only in code behind, since the pages inherits from base Page class. To achieve the same result in a MVVM application, we need to use a special service that act as a wrapper of the Frame class and that can be accessed also from a ViewModel. Prism already offers this class: it’s called NavigationService and we’ve already seen it in the first post, when we’ve setup the infrastructure required by Prism to properly work. If you remember, the App.xaml.cs file contains the following method:

protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
{
    NavigationService.Navigate("Main", null);
    return Task.FromResult<object>(null);
}

This method is invoked when the application is started and it’s used to redirect the user the user to the main page of the application. We’ve already described how to perform a basic navigation using the NavigationService: we call the Navigate() method, passing as parameter a string with the name of the View, without the Page suffix. In the previous sample, passing Main as parameter of the Navigate() method means that we want to redirect the user to a View in our project that is called MainPage.xaml.

Using the NavigationService in a ViewModel

To use the NavigationService in a ViewModel we need to use the dependency injection approach we’ve already seen in the first post. The App.xaml.cs file, in fact, contains also the following method:

protected override Task OnInitializeAsync(IActivatedEventArgs args)
{
    // Register MvvmAppBase services with the container so that view models can take dependencies on them
    _container.RegisterInstance<ISessionStateService>(SessionStateService);
    _container.RegisterInstance<INavigationService>(NavigationService);
    // Register any app specific types with the container

    // Set a factory for the ViewModelLocator to use the container to construct view models so their 
    // dependencies get injected by the container
    ViewModelLocationProvider.SetDefaultViewModelFactory((viewModelType) => _container.Resolve(viewModelType));
    return Task.FromResult<object>(null);
}

As you can see, among other things, the method takes of registering, inside the UnityContainer object, the INavigationService interface, by connecting it to the NavigationService implementation offered by Prism. This way, we’ll be able to use the NavigationService in a ViewModel simply by adding an INavigationService parameter to the ViewModel’s constructor, like in the following sample:

public class MainPageViewModel : ViewModel
{
    private readonly INavigationService _navigationService;

    public MainPageViewModel(INavigationService navigationService)
    {
        _navigationService = navigationService;
    }
}

Now we have a reference to the Prism’s NavigationService, that we can use to perform navigation inside a ViewModel.

Managing the navigation events in a ViewModel

Another common requirement when you develop an Universal Windows app using the MVVM pattern is to find a way to intercept when the user is navigating to or away from the current page. In code behind, it’s easy to do it because we have access to two methods called OnNavigatedTo() and OnNavigatedFrom(): unfortunately, they are available only in the code behind class, since they are inherited from the base Page class.

Prism offers a simple way to manage these two navigation events in a ViewModel: as we’ve already seen in the previous posts, the ViewModels inherits from a base class called ViewModel. Thanks to this class, we are able to subscribe to the OnNavigatedTo() and OnNavigatedFrom() methods inside a ViewModel, like in the following sample:

public class MainPageViewModel : ViewModel
{
    public override void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
    {
        base.OnNavigatedTo(navigationParameter, navigationMode, viewModelState);
    }

    public override void OnNavigatedFrom(Dictionary<string, object> viewModelState, bool suspending)
    {
        base.OnNavigatedFrom(viewModelState, suspending);
 
    }
}

The OnNavigatedTo() method, especially, is very important, because it’s the best point where to load the data that will be displayed in the page. Some people, in fact, often use the ViewModel constructor to load the data: however, it’s not a good approach, especially in modern development. It often happens, in fact, that the data needs to be loaded using asynchronous methods, which are based on the async and await pattern. If you have some experience with this approach, you’ll know that a class constructor can’t be marked with the async keyword, so you won’t be able to call a method using the await prefix. This means that, for example, the following code won’t compile:

public class MainPageViewModel : ViewModel
{
    private readonly INavigationService _navigationService;
    private readonly IFeedService _feedService;
    private ObservableCollection<News> _news;

    public ObservableCollection<News> News
    {
        get { return _news; }
        set { SetProperty(ref _news, value); }
    }

    public MainPageViewModel(INavigationService navigationService, IFeedService feedService)
    {
        _navigationService = navigationService;
        _feedService = feedService;

        IEnumerable<News> news = await _feedService.GetNews();

        News = new ObservableCollection<News>();
        foreach (News item in news)
        {
            News.Add(item);
        }
    }        
}

I won’t describe in details how is defined the IFeedService class and how exactly works the GetNews() method: you can see all the details in the source code of the project that is published at https://github.com/qmatteoq/Prism-UniversalSample. For the moment, it’s important just to know that it’s an asynchronous method which, by using the SyndicationClient class provided by the Windows Runtime, downloads the RSS feed of this blog and parses it, to return the items as list of objects. Our goal is to display this list using a ListView control in the application: however, as I’ve previously mentioned, the previous code won’t compile, since I’m calling an asynchronous method (GetNews(), which is invoked with the await keyword) inside the ViewModel constructor, which can’t be marked with the async keyword.

The OnNavigatedTo(), instead, since it’s a sort of event handler (it manages the page navigation event), can be marked with the async keyword, so you can call asynchronous method in it without problems. Here is the correct approach to implement the previous sample:

public class MainPageViewModel : ViewModel
{
    private readonly INavigationService _navigationService;
    private readonly IFeedService _feedService;
    private ObservableCollection<News> _news;

    public ObservableCollection<News> News
    {
        get { return _news; }
        set { SetProperty(ref _news, value); }
    }

    public MainPageViewModel(INavigationService navigationService, IFeedService feedService)
    {
        _navigationService = navigationService;
        _feedService = feedService;
    }

    public override async void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
    {
        IEnumerable<News> news = await _feedService.GetNews();

        News = new ObservableCollection<News>();
        foreach (News item in news)
        {
            News.Add(item);
        }
    }
}

As you can see, the data loading operation is now performed in the OnNavigatedTo() method, which is marked with the async keyword and, consequently, we can call the GetNews() method using the await prefix without any issue. This code will compile and run just fine!

Passing parameters from one page to another

The OnNavigatedTo() can be useful also in another scenario: to pass parameters from one page to the another. Let’s use again the previous sample and let’s say that we have the following XAML page, which is the same we’ve seen in the previous post talking about commands with parameters:

<storeApps:VisualStateAwarePage
    x:Class="Prism_Navigation.Views.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Prism_Navigation"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:storeApps="using:Microsoft.Practices.Prism.StoreApps"
    xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm"
    xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:core="using:Microsoft.Xaml.Interactions.Core"
    mc:Ignorable="d"
    mvvm:ViewModelLocator.AutoWireViewModel="True"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <ListView ItemsSource="{Binding Path=News}" SelectionMode="Single" IsItemClickEnabled="True" Margin="12, 0, 12, 0">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Title}" Style="{StaticResource SubheaderTextBlockStyle}" 
                       TextWrapping="Wrap" />
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
            <interactivity:Interaction.Behaviors>
                <core:EventTriggerBehavior EventName="ItemClick">
                    <core:InvokeCommandAction Command="{Binding Path=ShowDetailCommand}" />
                </core:EventTriggerBehavior>
            </interactivity:Interaction.Behaviors>
        </ListView>
    </Grid>
</storeApps:VisualStateAwarePage>

We’re using a ListView control to display the list of news retrieved by the GetNews() method of the FeedService class. By using the behavior we’ve learned to use in the previous post, we’ve connected the ItemClick event to the ShowDetailCommand command in the ViewModel. Here is how the ShowDetailCommand’s definiton looks like:

public class MainPageViewModel : ViewModel
{
    public MainPageViewModel(INavigationService navigationService, IFeedService feedService)
    {
        _navigationService = navigationService;
        _feedService = feedService;

        ShowDetailCommand = new DelegateCommand<ItemClickEventArgs>((args) =>
        {
            News selectedNews = args.ClickedItem as News;
            _navigationService.Navigate("Detail", selectedNews);
        });
    }

    public DelegateCommand<ItemClickEventArgs> ShowDetailCommand { get; private set; }
}

The approach is the same we’ve seen in the previous post: we’ve defined a DelegateCommand<ItemClickEventArgs> and, consequently, we are able to retrieve, in the command definition, the item selected by the user. The difference is that, this time, after casting it as a News object, we pass it as second parameter of the Navigate() method of the NavigationService. This way, other than redirecting the user to a page called DetailPage.xaml (since we’re using the string Detail), we bring the information about the selected news, so that we can show the details.

The OnNavigatedTo() method can be used also to retrieve the parameter that we’ve passed from the NavigationService, thanks to one of the parameters called navigationParameter. The following sample shows the definition of the ViewModel of the detail page, which is the destination page of the navigation:

public class DetailPageViewModel : ViewModel
{
    private News _selectedNews;

    public News SelectedNews
    {
        get { return _selectedNews; }
        set { SetProperty(ref _selectedNews, value); }
    }

    public override void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
    {
        if (navigationParameter != null)
        {
            SelectedNews = navigationParameter as News;
        }
    }
}

As you can see, thanks to the navigationParameter, we are able to retrieve the selected item that has been passed by the previous page. In the sample, we simply cast it back to the News type (since it’s a generic object) and we display it to the user with the following XAML:

<Grid>
    <StackPanel>
        <TextBlock Text="{Binding Path=SelectedNews.Title}" />
        <TextBlock Text="{Binding Path=SelectedNews.Summary}" />
    </StackPanel>
</Grid>

Managing the back button in Windows Phone 8.1

One of the most important differences in the navigation system between Windows Phone 8.0 and Windows Phone 8.1 is the back button management: by default, in Windows Phone 8.0, the Back button always redirects the user to the previous page of the application. In Windows Phone 8.1, instead, to keep the behavior consistent with Windows 8.1 (which doesn’t offer a hardware button), the Back button redirect the user to the previous application. However, Microsoft don’t suggest to developers to use this approach: users, by pressing the back button, expect to go back to the previous page of the application since Windows Phone 7.0. Consequently, you need to override, in every page or in the App.xaml.cs, the HardwareButtons.BackPressed event and to perform a similar code:

private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
    Frame frame = Window.Current.Content as Frame;
    if (frame == null)
    {
        return;
    }

    if (frame.CanGoBack)
    {
        frame.GoBack();
        e.Handled = true;
    }
}

The code takes care of checking if there are pages in the backstack of the application (by checking the value of the CanGoBack property): if this is the case, we call the GoBack() method to perform a navigation to the previous page and we set the Handled property of the event handler as true, so that we prevent the operating system to manage it.

Well, the good news is that the MvvmAppBase class, which is the one that replaces the App one in a Prism application, already takes care of this for us: we won’t have to do nothing or to write additional code to support a proper Back key management in a Windows Phone 8.1 application.

Wrapping up

As usual, you can download the sample code related to this post from GitHub at the following URL: https://github.com/qmatteoq/Prism-UniversalSample

Index of the posts about Prism and Universal Windows apps

  1. The basic concepts
  2. Binding and commands
  3. Advanced commands
  4. Navigation
  5. Managing the application’s lifecycle
  6. Messages
  7. Layout management

Sample project: https://github.com/qmatteoq/Prism-UniversalSample

Posted in Universal Apps | Tagged , , , | Leave a comment

Prism and Universal Windows apps – Advanced commands

In the previous post we’ve learned the basic concepts that are required to implement the MVVM pattern using Prism in a Universal Windows app. In this post, we’ll continue our journey by exploring more details about using commands.

Managing secondary events with commands

When we use the Command property provided by the XAML control, we define the operation that should be executed when the user interacts with the primary event exposed by the control. For example, if it’s a Button, the Command property is connected to the Click event, so the operation is performed when the user taps on the button. However, in some situation we may have the requirement to subscribe to additional events that are exposed by the control. Let’s say, for example, that we want to manage the DoubleTapped event exposed by the Button control, which is triggered when you perform a double tap (instead of a single tap) on the button.

The goal can be achieved thanks to the behaviors provided by the Microsoft.Xaml.Interactivity library, which can be added to your project by right clicking on it, choosing Add reference and, in the Extensions section, enabling the Behaviors SDK (XAML) option. Now you’ll be able to use some behaviors that can be used to connect a secondary event to a command in the ViewModel. Here is a sample in the XAML page:

<storeApps:VisualStateAwarePage
    x:Class="Prism_AdvancedDemo.Views.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Prism_AdvancedDemo"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:storeApps="using:Microsoft.Practices.Prism.StoreApps"
    xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm"
    xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:core="using:Microsoft.Xaml.Interactions.Core"
    mc:Ignorable="d"
    mvvm:ViewModelLocator.AutoWireViewModel="True"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <Button Content="Double tap me">
            <interactivity:Interaction.Behaviors>
                <core:EventTriggerBehavior EventName="DoubleTapped">
                    <core:InvokeCommandAction Command="{Binding Path=DoubleTapCommand}" />
                </core:EventTriggerBehavior>
            </interactivity:Interaction.Behaviors>
        </Button>
    </Grid>
</storeApps:VisualStateAwarePage>

As you can, we’ve added two new namespaces to the XAML page definition: one is Microsoft.Xaml.Interactivity, the other one is Microsoft.Xaml.Interactions.Core. Thanks to these namespaces we are able to define, by using the attached property Interaction.Behaviors, the list of behaviors that we want to apply to the control (in our case, it’s the Button one). The behavior we’re going to use is called EventTriggerBehavior, which requires, by using the EventName property, the name of the event exposed by the control that we want to connect to it: in this case, it’s the DoubleTapped one. Inside the behavior we need to specify which action we want to perform: in this case, we need to use the InvokeCommandAction trigger, which is used to invoke an ICommand object defined in the ViewModel.

From the ViewModel point of view, nothing changes when it comes to define the DoubleTapCommand: it’s a standard implementation of the DelegateCommand class, as we’ve seen in the previous post.

public class MainPageViewModel : ViewModel
{
    public MainPageViewModel()
    {
        DoubleTapCommand = new DelegateCommand(async () =>
        {
            MessageDialog dialog = new MessageDialog("Double tap performed");
            await dialog.ShowAsync();
        });
    }


    public DelegateCommand DoubleTapCommand { get; private set; }
}

The command simply displays a message to the user, using a MessageDialog popup, every time it’s invoked.

Commands with parameters

Commands also support a way to pass parameters to the method that is invoked when the command is invoked. From the XAML point of view, it’s enough to set the parameter using the CommandParameter property offered by every control that support the Command property. The following sample shows how to set a parameter with a Button control:

<Button Content="Click me" Command="{Binding Path=DisplayMessageCommand}" CommandParameter="Text of the message" />

This approach is not a specific Prism feature, but it’s built-in in the XAML frameworks. What Prism offers is a a different implementation of the DelegateCommand class, which supports a parameter using generics. The following sample shows how to declare the DisplayMessageCommand so that it can receive a string parameter (since the value passed to the CommandParameter property is a text):

public class MainPageViewModel : ViewModel
{
    public MainPageViewModel()
    {         
        DisplayMessageCommand = new DelegateCommand<string>(async (args) =>
        {
            MessageDialog dialog = new MessageDialog(args);
            await dialog.ShowAsync();
        });
    }

   
    public DelegateCommand<string> DisplayMessageCommand { get; private set; }

}

There are two differences compared to a standard DelegateCommand implementation:

  • We’re using the DelegateCommand<T> type, where T is the parameter’s type (in our sample, it’s string).
  • The anonymous method that contains the code that is executed when the command is invoked contains a parameter, which is the value received by the CommandParameter property. In the sample, it’s called args and we use it to display to the user, using a MessageDialog, the parameter’s value.

Passing as parameter the event handler’s argument

When you work in code behind and you subscribe to an event handler, typically you get a parameter that contains some important information about the event. Let’s use, as sample, a ListView control, which is used to display a collection of items. One way to interact with the list (that is often used when you just need to know which item has been chosen, for example in a master – detail scenario) is to set the IsItemClickEnabled property to True: this way you can simply subscribe to the ItemClick event to get which item has been selected. Here is a sample usage of this event in the code behind:

private void NewsList_OnItemClick(object sender, ItemClickEventArgs e)
{
    News news = e.ClickedItem as News;
}

As you can see, the event handler contains a parameter (which type is ItemClickEventArgs) which stores, inside the ClickedItem property, the item that the user has selected in the ListView. In the previous sample, we’re displaying a collection of News objects so, thanks to a cast, we’re converting the selected item (which is a generic object) into the proper type.

This approach works fine in code behind, but what about MVVM? Since we have a command and not an event handler, how we can get, in the ViewModel, the event arguments received by the method (in this case, the ItemClickEventArgs object)? Prism makes things simple: it’s enough to create a DelegateCommand<T> property in the ViewModel, where T is the event argument’s type. Prism will automatically take care of passing, to the command, the event arguments of the event we’ve subscribed. Let’s consider the following sample:

<ListView ItemsSource="{Binding Path=News}" SelectionMode="Single" IsItemClickEnabled="True">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Title}" Style="{StaticResource SubheaderTextBlockStyle}" 
           TextWrapping="Wrap" />
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
    <interactivity:Interaction.Behaviors>
        <core:EventTriggerBehavior EventName="ItemClick">
            <core:InvokeCommandAction Command="{Binding Path=ShowDetailCommand}"
                      />
        </core:EventTriggerBehavior>
    </interactivity:Interaction.Behaviors>
</ListView>

We’re using the same approach we’ve seen before with the Button control: we’ve added an EventTriggerBehavior to the ListView control, which is connected to the ItemClick event. Then we applied an InvokeCommandAction, which invokes a command called ShowDetailCommand. As you can see, we’re not specyfing any command parameter. However, we are able to create a DelegateCommand object in the ViewModel that looks like this:

public class MainPageViewModel : ViewModel
{
    public MainPageViewModel()
    {
        ShowDetailCommand = new DelegateCommand<ItemClickEventArgs>((args) =>
        {
            News news = args.ClickedItem as News;
        });
    }

    public DelegateCommand<ItemClickEventArgs> ShowDetailCommand { get; private set; }
}

As you can see, we’ve not created a plain DelegateCommand object, but a DelegateCommand<T> one, where T is the event argument’s type we receive in the event handler (in our case, it’s ItemClickEventArgs). Prism will automatically inject, into the method, the event handler’s parameter: when we create the DelegateCommand<ItemClickEventArgs> object, we are able to access to this parameter and to perform the same operation we did in the code behind (which is accessing to the ClickedItem property and casting it to a News object). This way we would be able, for example, to use the Prism’s navigation service (which we’ll cover in the next post) to redirect the user to detail page, passing as parameter the selected item.

Wrapping up

As usual, you can find the sample code used for this post in the GitHub’s project available at the URL https://github.com/qmatteoq/Prism-UniversalSample

Index of the posts about Prism and Universal Windows apps

  1. The basic concepts
  2. Binding and commands
  3. Advanced commands
  4. Navigation
  5. Managing the application’s lifecycle
  6. Messages
  7. Layout management

Sample project: https://github.com/qmatteoq/Prism-UniversalSample

Posted in Universal Apps | Tagged , , , | 4 Comments

Prism and Universal Windows apps – Binding and commands

In the previous post we’ve seen the basic concepts about using Prism in a Universal Windows app: we’ve seen how to create our first project and how to setup the Prism infrastructure, so that we are able to use all the helpers and facilities offered by the framework. In this post we’ll see how to support the two most important MVVM concepts: binding and commands.

Binding

Binding is the way that, in MVVM, you use to connect properties that are declared in the ViewModel to controls that are placed in the View. This way, you’ll be able to perform two basic but important operations:

  • Display data in the page: every time you change a property in the ViewModel, the control that is connected to the property will automatically update itself to display the new value.
  • Receive input from the user: thanks to the two way binding, the communication channel between a property and a control can be bidirectional. This way, if the user interacts with a control in the page (for example, he writes something in a TextBox), the value will be stored in the property in the ViewModel.

The binding is based on the INotifyPropertyChanged interface, which should be implemented by ViewModels: this way, all the properties can notify to the controls in the View when its value is changed. Prism offers a base class that every ViewModel should implement which, among other things, gives us a quick way to implement this interface. The name of the class is VisualStateAwarePage: the name should help you to understand one of the other features of this class, which is a way to support, with visual states, the different layouts that a View can assume (portrait, landscape, snapped in case of a Windows Store app for Windows 8).

To support this class in our ViewModel we need to perform two operations: the first one is to replace the Page class from which every page inherits from with the VisualStateAwarePage one, which is included in the Microsoft.Practices.Prism.StoreApps namespace. Here is how a page of a Universal Windows app developed with Prism looks like:

<storeApps:VisualStateAwarePage
    x:Class="PrismDemo.Views.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PrismDemo.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:storeApps="using:Microsoft.Practices.Prism.StoreApps"
    xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm"
    mc:Ignorable="d"
    mvvm:ViewModelLocator.AutoWireViewModel="True"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <!-- content of the page -->

</storeApps:VisualStateAwarePage>

As you can see, the base node it’s not called Page anymore, but it’s been replaced by the VisualStateAwarePage one.

The second step is to change also the code behind class of the page (the .xaml.cs file), so that it doesn’t inherit anymore from the Page class, but from the VisualStateAwarePage one. The following code shows a sample code behind definition:

using Microsoft.Practices.Prism.StoreApps;

namespace PrismDemo.Views
{
    public sealed partial class MainPage : VisualStateAwarePage
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
    }
}

Now that you’re properly set up the page, you’re ready to start using binding. The main concept behind binding is that, instead of using plain simple properties (with a standard getter and setter), you’re going to define properties that are able to propagate the changes to the user interface when its value changes. To make use of the mechanism offered by Prism to manage the notification propagation, you’ll need to inherit your ViewModels from the ViewModel class. The following sample shows a ViewModel with a simple property, which is defined using the Prism approach:

public class MainPageViewModel : ViewModel
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set { SetProperty(ref _name, value); }
    }

}

To assign a value to the property we use the SetProperty() method offered by Prism, which requires a reference to the private variable that holds its value (in this sample, it’s _name) and the value to assign (which is defined by the value keyword). Under the hood, the SetProperty() method, other than just assigning a value to the property, will take care of notifying the control that is in binding with it that the value is changed, by implementing, under the hood, the INotifyPropertyChanged interface. This way, the control in the XAML will update itself to reflect the change. Connecting this property in the ViewModel with a control in the XAML, now, doesn’t require any special knowledge, rather than standard binding. For example, here is how we can display the value of the Name property using a TextBlock control, by assigning it to the Text property using binding:

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

Otherwise, if other than just displaying the value we also need to retrieve the input from the user, we can simply apply the Mode attribute to the binding and set it to TwoWay, like in the following sample:

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

This way, when the user will write something in the box, we’ll be able to get the inserted text in the Name property of the ViewModel.

Commands

Commands are the mechanism offered by the XAML to support the user interaction without being forced to use event handlers. Typically, when you write an application without using the MVVM pattern, to manage the user’s interaction with the user interface (for example, he clicks on a button) you subscribe to a event handler: this way, a new method will be generated in code behind, which will contain the code that will be execute when the event is raised.

The downside of this approach is that it creates a strong connection between the View and the code: event handlers can be managed only in code behind, you can’t simply move it to a ViewModel. The solution is to use commands, which are special objects (that implement the ICommand interface) that define the operation to perform when the command is executed. The Windows Runtime offers only the basic interface to support commands, which is ICommand: a developer, typically, would have to create its own class to implement this interface. However, al the MVVM frameworks usually offer it and Prism makes no exception: in this case, the class is called DelegateCommand. Let’s see a sample about how to define a command in a ViewModel:

public class MainPageViewModel : ViewModel
{

    public MainPageViewModel()
    {
        SayHelloCommand = new DelegateCommand(() =>
        {
            Message = string.Format("Hello {0}", Name);
        });
    }

    public DelegateCommand SayHelloCommand { get; private set; }


    private string _name;

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

    private string _message;

    public string Message
    {
        get { return _message; }
        set { SetProperty(ref _message, value); }
    }
}

As you can see, we’ve defined a new property, which type is DelegateCommand: in this case, we don’t need to use the SetProperty() method to define it, since a command won’t change implementation at runtime, so it will be set only by the ViewModel when it’s instantiated. It’s what we do in the ViewModel constructor (the method called MainPageViewModel()): we create a new DelegateCommand and we pass, as parameter,  an anonymous method that defines the operation to execute when the command is invoked. In this sample, we display to the user the message “Hello” followed by his name, that we have received in the property called Name.

Here is how the View connected to this ViewModel looks like:

<storeApps:VisualStateAwarePage
    x:Class="PrismDemo.Views.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PrismDemo.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:storeApps="using:Microsoft.Practices.Prism.StoreApps"
    xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm"
    mc:Ignorable="d"
    mvvm:ViewModelLocator.AutoWireViewModel="True"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <StackPanel Margin="12, 0, 12, 0">
            <TextBox Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
            <TextBlock Text="{Binding Path=Message}" Style="{StaticResource HeaderTextBlockStyle}" />
        </StackPanel>
    </Grid>
    
    <storeApps:VisualStateAwarePage.BottomAppBar>
        <CommandBar>
            <CommandBar.PrimaryCommands>
                <AppBarButton Label="confirm" Icon="Accept" Command="{Binding Path=SayHelloCommand}" />
            </CommandBar.PrimaryCommands>
        </CommandBar>
    </storeApps:VisualStateAwarePage.BottomAppBar>
</storeApps:VisualStateAwarePage>

As you can see, we’ve added a TextBox control (which we’re going to use to collect the user’s name), a TextBlock control (which will display the hello message) and a CommandBar, which contains the button that the user will have to click to see the message. The button, which is an AppBarButton control, shows how to use commands: we simply put in binding the Command property of the control with the DelegateCommand’s object we’ve defined in the ViewModel. Now, every time the user will press the button, the operation we’ve defined in the command will be executed.

Enabling and disabling commands

One of the most powerful features provided by commands is the automatic support to the state management. With a simple boolean condition, we can control if the command should be enabled or not: the control that is connected to the command will automatically change his appearance to reflect this status. This means that if, in the previous sample, the SayHelloCommand is marked as disabled, the AppBarButton control will be grayed and the user won’t be able to click on it.

To support this feature, you just need to pass a boolean condition as second parameter when you define the DelegateCommand object, like in the following sample:

public MainPageViewModel()
{
    SayHelloCommand = new DelegateCommand(() =>
    {
        Message = string.Format("Hello {0}", Name);
    }, () => !string.IsNullOrEmpty(Name));
}

As you can see, the second parameter is a boolean condition that checks if the Name property contains an empty value or not: this way, in case the user doesn’t type anything in the TextBox control, we disable the button, since we are not able to display the hello message.

There’s one last step to do to properly support this feature: the application is not able, automatically, to know when the boolean condition that we’ve specified could have changed, so we need to explicitly tell it. We do this by calling the RaiseCanExecuteChanged() method offered by the DelegateCommand class, which tells to the command to evaluate again his status. It’s up to us to decide when it’s the best moment to call it, according to the purpose of the command: in our sample, since we want to avoid that the user can press the button if he hasn’t written anything in the box, we’re going to evaluate the status of the command every time the value of the Name property changes. Here is how the definition of the Name property changes to support our scenario:

private string _name;

public string Name
{
    get { return _name; }
    set
    {
        SayHelloCommand.RaiseCanExecuteChanged();
        SetProperty(ref _name, value);
    }
}

Simply, before calling the SetProperty() method to save the value and update the control, we call the RaiseCanExecuteChanged() method of the SayHelloCommand object.

Wrapping up

In this post we’ve seen the basic concepts which are important to start writing a Universal Windows app using prism: binding and commands. In the next posts we’ll cover more advanced scenarios, like navigation, state management, advanced commands features, etc. You find this post’s sample on GitHub: https://github.com/qmatteoq/Prism-UniversalSample

Index of the posts about Prism and Universal Windows apps

  1. The basic concepts
  2. Binding and commands
  3. Advanced commands
  4. Navigation
  5. Managing the application’s lifecycle
  6. Messages
  7. Layout management

Sample project: https://github.com/qmatteoq/Prism-UniversalSample

Posted in Universal Apps | Tagged , , | 5 Comments

Prism and Universal Windows app – The basic concepts

In the latest days I’ve started to work with Prism for Universal Windows apps and I’ve decided to share my experience with you. What is Prism? If you’re a long time Microsoft developer, you’ll probably already know it: it’s a very popular MVVM (Model-View-ViewModel) framework created by the Patterns & Practices division in Microsoft, with the goal to help developers to implement the MVVM pattern in their application and to support the most common scenarios.

Recently, the division has released a Prism version which is completely compatible with the Windows Runtime and, consequently, with Universal Windows apps development: the purpose of this series of blog posts is to see how to use it for this scenario and how it can help you developing a MVVM application.

I won’t discuss in details the advantages of using the MVVM pattern: I’ve already talked about this topic in the posts series about Caliburn Micro.

Prism vs the other toolkits and frameworks

How does Prism compare to the other popular MVVM toolkits and frameworks, like MVVM Light and Caliburn Micro? After playing a bit with it, I’ve reached the conclusion that it tries to take the best of the both worlds. Definitely, it’s much more similar to Caliburn Micro than MVVM Light: in fact, we’re talking about a framework, which offers many built-in classes and helpers that are useful to manage specific scenarios of the platform (like navigation, state management, etc.). Moreover, like Caliburn Micro, it uses some special classes that replace the native ones (like the App class or the Page class), which acts as a bootstrapper to properly setup all the infrastructure required by Prism to properly work.

However, one of the cons of Caliburn Micro is that it’s not ideal to developers that are working with MVVM for the first time: despite being very powerful, all the naming conventions tend to hide all the basic concepts behind the pattern, like the binding, the DataContext or the usage of the INotifyPropertyChanged interface. Prism, instead, except for some minor scenarios (we’ll see the details later) is still based on the standard MVVM fundamentals, so it uses concepts that should be familiar to every XAML developer like binding or commands.

The project setup

Let’s see how to create our first Universal Windows app using Prism: the first step is to create a new Universal Windows app project in Visual Studio, which will create the usual solution with a shared project, a Windows 8.1 one and a Windows Phone 8.1 one. If you’re familiar with Universal Windows app development, you’ll know that the shared project isn’t a real library, but it’s just a collection of shared resources (like classes, assets and XAML controls) which are linked to the two other projects. Consequently, you can’t add a reference to a third party library to the shared project: references are taken directly by the main platforms specific projects. The first step is, by using NuGet, to install both in the Windows and in the Windows Phone project the Prism.StoreApp library, which is the Prism version specific for Windows Store Apps.

The second step is optional, but highly recommended, since we’re going to use this approach in the next samples: when we talked about Caliburn Micro we’ve learned a bit more about dependency injection, which is a way to create objects at runtime instead of compile time. The pros of this approach is that we are able to easily change the implementation of a class (for example, because we want to swap a real class with a fake one that provides fake data at design time) without having to modify all the ViewModels that use it.

Also Prism supports dependency injection and it’s the best way to manage the dependencies of the ViewModels from other services of our application (like a navigation service, or a data service that retrieves our application’s data, etc.). The most widely used dependency injection’s container for Prism is Unity, which is also provided by the Pattern & Practices division by Microsoft: the next step, consequently, is to use again NuGet to install Unity in both project. It’s important to highlight that you’ll need to enable the option to extend the search also in pre-release packages: the latest stable version, in fact, doesn’t support yet Windows Phone 8.1, so you’ll get an installation error if you try to add it.

Convert the application into a Prism application

The first step to convert the Universal app into a Prism based app is to configure the bootstrapper: with this term, I mean the procedure that is required by the framework to properly initialize all the infrastructure required to work. In Universal Windows apps, the bootstrapper is the App class itself: we’re going to redefine the App class, so that it doesn’t inherit anymore from the native Application class, but from a Prism classed called MvvmAppBase.

To do this you need to follow two steps: the first one is to change the definition of the App class in the XAML, in the file App.xaml. You’ll need to add a new namespace, which is the one where the MvvmAppBase class is defined: the namespace is Microsoft.Practices.Prism.Mvvm. The second step is to replace the base Application tag with the MvvmAppBase one. Here is how the App.xaml file will look like at the end:

<mvvm:MvvmAppBase
    x:Class="PrismDemo.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PrismDemo"
    xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm">

</mvvm:MvvmAppBase>

The second step, instead, is to change the App class code, so you’ll need to edit the App.xaml.cs file: the first thing to do is to replace the class where the App object inherits from, which isn’t anymore Application but MvvmAppBase. Then, you’ll need to remove all the code and keep just the App constructor: Prism, in fact, offers its own way to manage the different application’s lifecycle events (like launched, activated, suspended, etc.).

Here is how a base App class for a Prism project looks like:

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

}

We’re not done yet in setting up the bootstrapper but, first, we need to create our first page, so that it will be easier to understand the next steps. As I’ve mentioned before, one of the advantages of Prism over Caliburn is that, despite being a powerful framework, it doesn’t hide all the basic MVVM infrastructure. However, there’s an exception: like in Caliburn, the connection between a View and a ViewModel is performed using a naming convention. You can use also another approach if you prefer (like using a ViewModelLocator or by directly binding the ViewModel as data context of the View), but the naming convention one is the easiest to use to take advantage of all the Prims features. The naming convention is very simple and it reminds the one used by Caliburn: you’ll have to place your ViewModels into a folder of your project called ViewModels, while the Views will be placed in a folder called Views. Since you’re working on a Universal Windows app, typically you’re going to create the ViewModels folder into the Shared project (since the ViewModels will be shared across the two platforms), while the Views folder will be created in the platform specific project, so that you can optimize the user interface for the two platforms.

There’s also another naming convention to follow, which is about the name of the files:

  • The View should end with the Page suffix (like MainPage).
  • The ViewModel should have the same name of the View, plus the ViewModel suffix (so, for example, the ViewModel connected to a page called MainPage will be named MainPageViewModel).

solution

Now that you have created your first page of the application, you’re going to need to tell to Prism that it’s the default one, that needs to be loaded when the application starts. You’re going to achieve this goal by overriding in the App class one of the methods offered by the MvvmAppBase class, which is OnLaunchApplicationAsync(). Here is how it looks like in a typical Universal Windows app:

protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
{
    NavigationService.Navigate("Main", null);
    return Task.FromResult<object>(null);
}

The method uses one of the built in helpers offered by Prism, that we’ll cover in details in the next posts: it’s a class called NavigationService, which is used to perform navigation from one page to another. To navigate to another page you need to use the Navigate() method, which accepts as first parameter the name of the page, which is the name of the View without the Page suffix: in the previous sample, by passing as parameter the value Main we’re assuming that, in the Views folder of our project, we have a page called MainPage.xaml. For the moment, ignore the second parameter, which is simply set to null: it’s the optional parameter that we can pass to the destination page.

The last line of code executed by the operation is a “workaround”: as you can see, the OnLaunchApplicationAsync() method returns a Task, so that you can perform asynchronous operations inside it. Since, in this case, we’re not performing any of them, we’re returning a “fake” one by using the Task.FromResult() method and passing null as parameter.

Setting up the dependency injection

The last step before starting working for real on the application is to configure the dependency injection container: as already mentioned, we’re going to use Unity. The container initialization is made in a method offered by the MvvmAppBase called OnInitializeAsync(), which is executed when the application is initialized for the first time. The approach here is the same we’ve seen in Caliburn: we are able to register own services, so that they will be automatically injected in the ViewModels when we’re going to use them. However, we have also to register some of the built-in services, so that we can use them in the other ViewModels: they are the NavigationService (which we’ve already seen and it’s used to perform navigation from one page to the other) and the SessionStateService, which we’ll see in details in another post. For the moment, it’s important just to know that it’s a helper to make it easier for developer to manage the suspension and termination of the app.

If you have some experience with Caliburn or MVVM Light, you’ll know that one of the required step to properly set up the dependency injection is to register, inside the container (which is the class that takes care of dispatching the objects when required), all the ViewModels of the project. With Prism this is not required: thanks to the naming convention previously described, in fact, we are able to tell to Prism (using a class called ViewModelLocatorProvider) that we want to automatically register every available ViewModel.

Here is how the complete App.xaml.cs looks like:

sealed partial class App : MvvmAppBase
{
    IUnityContainer _container = new UnityContainer();
    public App()
    {
        this.InitializeComponent();
    }

    protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
    {
        NavigationService.Navigate("Main", null);
        return Task.FromResult<object>(null);
    }

    protected override Task OnInitializeAsync(IActivatedEventArgs args)
    {
        // Register MvvmAppBase services with the container so that view models can take dependencies on them
        _container.RegisterInstance<ISessionStateService>(SessionStateService);
        _container.RegisterInstance<INavigationService>(NavigationService);
        // Register any app specific types with the container

        // Set a factory for the ViewModelLocator to use the container to construct view models so their 
        // dependencies get injected by the container
        ViewModelLocationProvider.SetDefaultViewModelFactory((viewModelType) => _container.Resolve(viewModelType));
        return Task.FromResult<object>(null);
    }
}

In the previous code you can see the three required steps to setup the dependency injection:

  • We create a property which type is IUnityContainer and we create a new instance.
  • We register, by using the RegisterInstance<T>(), the previously described SessionStateService and NavigationService.
  • By using the SetDefaultViewModelFactory() method of the ViewModelLocationProvider class, we are able to automatically register every ViewModel we have in our project, so that it can be automatically connected to the View when required..Now we have defined the proper infrastructure required by Prism: there’s only one last step to, which is to tell to every View in our application which ViewModel to use. We achieve this by adding, in the Page class in the XAML, a property offered by Prism called AutoWireViewModel, which is offered by the ViewModelLocator class: by setting it to True, we enable the naming convention, so the View will automatically look for its own ViewModel and will assign it as DataContext. Here is how a page in a Prism application looks like:
    <Page
        x:Class="PrismDemo.Views.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:PrismDemo.Views"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm"
        mc:Ignorable="d"
        mvvm:ViewModelLocator.AutoWireViewModel="True"
    
    </Page>
    

    Wrapping up

    So far, we’ve just seen how Prism works and how to setup the project. In the next post, we’re going to start creating the application for real, by seeing how to use binding and how to define commands to manage the user interaction. If you want a sneak peak of a real project, you can find the sample we’re going to use in the next post on GitHub at the URL https://github.com/qmatteoq/Prism-UniversalSample

    Index of the posts about Prism and Universal Windows app

    1. The basic concepts
    2. Binding and commands
    3. Advanced commands
    4. Navigation
    5. Managing the application’s lifecycle
    6. Messages
    7. Layout management

    Sample project: https://github.com/qmatteoq/Prism-UniversalSample

Posted in Universal Apps | Tagged , , | 6 Comments