by Andreas Hammar and Håkan Reis and Peter von Lochow - .Net
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.
This post is a part in a series – you can find the full index here.
UPDATE: As Philip Colmer correctly commented, passing objects will throw exception upon suspension. To survive suspend you can only send basic types around.
There are two big differences in how navigation works on Windows Phone and Windows 8.
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.
So, lets begin by looking at how navigation between two pages is done on Windows Phone.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
// navigate private void NavigateButton_Click(object sender, RoutedEventArgs e) { NavigationService.Navigate(new Uri("/Page.xaml?key=value", UriKind.Relative)); } //receive data protected override void OnNavigatedTo(NavigationEventArgs e) { string value = NavigationContext.QueryString["key"]; base.OnNavigatedTo(e); } |
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}"> <Frame x: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 |
public static class Navigate { private static Frame _rootFrame; public static void SetRootFrame(Frame rootFrame) { _rootFrame = rootFrame; } public static void To(Type page, object data) { _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 |
protected override void OnNavigatedTo(NavigationEventArgs e) { var searchQuery = (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.
When pressing the back key in a Windows Phone application to go back, two things will happen:
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 |
public SearchPage() { InitializeComponent(); NavigationCacheMode = NavigationCacheMode.Enabled; } |
That row will activate the cache and give the same behavior as Windows Phone has, very nice.
@Philip You are absolutely right, even thought the objects sent are serializable they will not survive suspend and the exception will show. I should clarify that in the post.
The problem with passing objects to the pages, though, is that the Suspension Manager doesn’t know how to save them out. It causes an exception to occur.
So it means, unfortunately, you are restricted to using simple types as the object to be passed, unless you can resolve the problem of the Suspension Manager, or not use it!
Philip
[...] One difference is that page caching has to be manually enabled for each page, as we explained in part 8 of our Windows Phone to Windows 8 conversion series. And, the page cache is active for both forward and backward navigation, which recently gave me [...]
[...] Navigation [...]
[...] Handling snapped views, Supporting different form factors, Supporting different cards sizes”Converting to Windows 8 from Windows Phone | Navigation (8 of 12) (Jayway Team Blog)“Navigation in Windows Phone has a clear legacy from Silverlight, you get [...]