The MVVM Light NavigationService part 5: Windows Store

Introduction

This series of articles documents how to use the MVVM Light NavigationService on all supported platforms.

In this article, we will see how the NavigationService works in a Windows Store application.

See the bottom of this article for a working sample!

Creating the application

In Windows Store, you normally define the UI in a XAML file (an XML-based file). It is also possible in code but quite rare. Each view has a separate XAML file linked to a “code-behind” file, which is where the event handlers are normally defined. You can edit the XAML file using a markup editor such as Visual Studio, or a visual designer such as Blend or Visual Studio.

We will start by creating a new application with three pages in Visual Studio. Note that we will keep things concentrated on the NavigationService only, and we won’t use viewmodels, but trigger the navigation directly from the view.

  • In Visual Studio, select File, New, Project.
  • In the New Project dialog, select Visual C# / Store Apps / Windows Apps / Blank App. Note that the techniques shown here also work in Universal apps.
  • Give a name to the new app and click OK.

This creates a Windows Store app project with a MainPage and the corresponding C# code behind file. Now we will add two more pages.

  • In the Solution Explorer, right click on the newly created project and select Add, New Item.
  • In the Add New Item dialog, select Visual C# and then Blank Page.
  • Name the new item Page2 and click OK.
  • Repeat the same for Page3.

At this point, your Solution Explorer should look like this:

[2015-02-22_12-20-25.png]

Creating the UI

Now we will design a simple UI for the navigation. We will do this in Visual Studio but you can also select Blend if you prefer. Start by right clicking MainPage.xaml and select View Designer. Make sure that the Design tab is selected. You should see the screen showing up in the designer.

[2015-02-22_12-23-47.png]

  • Open the Toolbox (Menu View, Toolbox).
  • Drag and drop a Button on the page.
  • With the button selected, open the Properties tab.
  • Locate the Content property and set it to “Navigate to Page 2”.
  • Set the button’s name to “NavigateButton”.
  • In the Solution Explorer, open Page2.xaml. It should show an empty page.
  • Drag a Button on the page’s surface.
  • With the button selected, set the Content property to “Navigate to Page 3 with parameter”.
  • Set that button’s name to “NavigateWithParameterButton”.
  • Add another button below the first one.
  • Set this second button’s Content to “Go back” and it’s Name to “GoBackButton”.
  • Open Page3.xaml and add a new button too.
  • Set this button’s Content to “Go back to Page 2” and its Name to “GoBackButton”. You can safely use the same name for the GoBackButton on Page2 and Page3 because the name scope is not overlapping.
  • Add a TextBlock below the button.
  • With the TextBlock selected, set the Text property to “Nothing yet”.
  • Set the TextBlock’s Name to “DisplayText”. You can also set the FontSize to 24px or 24pt.

Installing MVVM Light

In order to use MVVM Light, we will pull the latest version from Nuget.

  • Right click on the project in the Solution Explorer, and select Manage NuGet Packages.
  • Select the nuget.org repository (under Online) and enter "mvvmlightlibs" in the Search field.
  • Select the "MVVM Light libraries only" package and click on Install.
  • Follow the instructions.

Initializing and registering the NavigationService

Now we will initialize the navigation service and the IOC container.

  • In the Solution Explorer, open App.xaml.cs, which is nested below App.xaml.
  • Modify the "App" constructor as shown below.
    • The first line configures the ServiceLocator, so we can use it in a standard manner throughout the application. For more details on this, see CommonServiceLocator.
    • Calling Configure adds a mapping key –> Page type in the NavigationService.
    • Finally, save the configured NavigationService instance in the SimpleIoc.
public const string Page2Key = "Page2";
public const string Page3Key = "Page3";
public App()
{
    InitializeComponent();
    Suspending += OnSuspending;

    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
    
    var nav = new NavigationService();
    nav.Configure(Page2Key, typeof(Page2));
    nav.Configure(Page3Key, typeof(Page3));
    
    SimpleIoc.Default.Register<INavigationService>(() => nav);
}

Navigating to another page

Now we will trigger the navigation. As stated before, the navigation can be triggered from any location in the application, including shared code in a portable class library, etc. Here, to keep things simple, we will not add any viewmodels but just use the code-behind and event handlers. In a real life application, the INavigationService would be injected inside the viewmodel using dependency injection. For more information about dependency injection and IOC, see my MSDN article.

  • In the MainPage.xaml.cs, modify the constructor as shown:
public MainPage()
{
    InitializeComponent();
    NavigateButton.Click += (s, e) =>
    {
        var nav = ServiceLocator.Current.GetInstance<INavigationService>();
        nav.NavigateTo(App.Page2Key);
    };
}
  • Open the Page2.xaml.cs and modify the constructor as follows:
public Page2()
{
    InitializeComponent();

    NavigateWithParameterButton.Click += (s, e) =>
    {
        var nav = ServiceLocator.Current.GetInstance<INavigationService>();
        nav.NavigateTo(
            App.Page3Key,
            "Hello Xamarin " + DateTime.Now.ToString("HH:mm:ss"));
    };

    GoBackButton.Click += (s, e) =>
    {
        var nav = ServiceLocator.Current.GetInstance<INavigationService>();
        nav.GoBack();
    };
}

Note that in this method, we are calling NavigateTo with a parameter. In this case we pass a string, but it could be any object. We also implemement the GoBackButton’s event handler to programmatically go back to the main page. Because Windows tablets often don’t have a dedicated Back button, it is necessary to have a back button on every page.

Retrieving the passed parameter, going back

In Page3.xaml.cs, we will retrieve the parameter passed by Page2. Then we will display this value in the DisplayText. Note that the parameter retrieval happens in the OnNavigatedTo method, which is common in Windows Store applications. We will also implemement the GoBackButton’s event handler to programmatically go back to page 2.

public Page3()
{
    InitializeComponent();

    GoBackButton.Click += (s, e) =>
    {
        var nav = ServiceLocator.Current.GetInstance<INavigationService>();
        nav.GoBack();
    };
}

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    if (e.Parameter != null)
    {
        DisplayText.Text = (string)e.Parameter;
    }
}

Retrieving the CurrentPageKey

It can be useful for the viewmodel to know which page is currently displayed. To do this, you can use the CurrentPageKey property. To illustrate this, implement the following code:

  • Open Page2.xaml.cs.
  • Implement the following method:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    var nav = ServiceLocator.Current.GetInstance<INavigationService>();
    Debug.WriteLine("Current page key:" + nav.CurrentPageKey);
}
  • Run the application in Debug mode (F5).
  • Navigate to Page 2 and observe the Debug console. You should see "Current page key: Page2".
  • Then navigate to Page 3. Using the button labeled "Go back to page 2", navigate back.
  • Observe again the Debug console.

Conclusion

This article demonstrated how to create a new Windows Store application with 3 pages, install MVVM Light and implement navigation between the pages, with and without a parameter. We also showed how to retrieve the parameter, and how to navigate back programmatically. Finally, we showed how to retrieve the key corresponding to the current page.

Resources

The code shown in this article is available in a sample TODO.