Converting to Windows 8 from Windows Phone | Navigation (8 of 12)

Navigation in Windows Phone has a clear legacy from Silverlight, you get around using Uris and query strings. What might have been the best solution for the web is clumsy and cumbersome in a native environment. This has often led to custom wrappers around the navigation APIs.

All this has changed in Window 8, navigation feels more modern and easy to use. In this article we’ll take a closer look at the old and new way of navigating.

UPDATE: As Philip Colmer correctly commented, passing objects will throw exception upon suspension. To survive suspend you can only send basic types around.

Differences

There are two big differences in how navigation works on Windows Phone and Windows 8.

1. Forward

On Windows Phone, pages are navigated to using a Uri and data passed as a query string

On Windows 8, pages are navigated to by passing the type, and data passed as an object

2. Back

Windows Phone has a physical back button and a back stack

Windows 8 has to implement a back button, if one is wanted, within the UI

This means that the navigation code will have to be rewritten and data passed differently.

We feel that the Windows 8 way of navigating is preferable. Especially passing data is much better done by passing objects than sending simple values through the query string.

One could serialize an entire object as XML or JSON and pass on the query string, but that is a sub-optimal solution, and the query string is limited to 2050 characters and hard coded strings are needed to read from the query string.

Navigation

So, lets begin by looking at how navigation between two pages is done on Windows Phone.

Nothing you haven’t seen before, lets dive straight to the Windows 8 way of navigating. Our setup is a main page containing a Frame in which all pages will be shown.

1

2

3

<grid Background="{StaticResource BackgroundBrush}">

<framex:Name="ContentFrame"/>

</grid>

Then what we’ve done is sent our “ContentFrame” into a static Navigate class.

1

2

3

4

5

6

7

8

9

10

11

12

publicstaticclassNavigate

{

privatestaticFrame _rootFrame;

publicstaticvoidSetRootFrame(Frame rootFrame)

{

_rootFrame=rootFrame;

}

publicstaticvoidTo(Type page,objectdata)

{

_rootFrame.Navigate(page,data);

}

}

This gives us the ability to, wherever we are in our application, navigate like this:

1

Navigate.To(typeof(SearchPage),searchQuery);

And receiving data is as simple as:

1

2

3

4

protectedoverride voidOnNavigatedTo(NavigationEventArgse)

{

varsearchQuery=(SearchQuery)e.Parameter;

}

The big advantage here is getting rid of all magic strings. The risk of misspelling and running into run-time errors is gone now that we use the compiler as our spell checker. Plus, it’s a heck of a lot more convenient to pass data as objects instead of strings.

UPDATE: As Philip Colmer correctly commented, passing objects will throw exception upon suspension. To survive suspend you can only send basic types around.

Page cache

When pressing the back key in a Windows Phone application to go back, two things will happen:

You’re taken back to the previous page (or out of the application if you were on the start page)

A saved page is loaded, i.e. a page that still has all the data it had when you navigated away from it

If you implement a back button on Windows 8 and use it, you will soon realize that you are not taken back to a cached instance of the page, instead the page that you navigate back to is created again. Hence if you are on a search page, tap on an item in the search result and then go back the search result will be cleared, very frustrating.

To get around this you could either save your view models in a cache and load those, or…

1

2

3

4

5

publicSearchPage()

{

InitializeComponent();

NavigationCacheMode=NavigationCacheMode.Enabled;

}

That row will activate the cache and give the same behavior as Windows Phone has, very nice.