navigating pages in wp8 like in win8

Currently, there are quite some inconsistencies between the Windows Phone SDK and the Windows 8 SDK. One of the very first that you’ll run into when developing for both platforms is the navigation api. The navigation api is used for navigating between different pages inside your app. It contains a method to navigate to a certain page, a method to navigate back one page, a few properties and so on. The thing that you’ll probably use most is the Navigate method and here’s quite a big difference between both platforms. For example, this is how you navigate to a page in Windows Phone

Code Snippet
  1. NavigationService.Navigate(new Uri("/SecondPage.xaml", UriKind.Relative));

And this is the same but in Windows 8

Code Snippet
  1. NavigationService.Navigate(typeof (SecondPage));

The Windows 8 way of navigating has one big advantage, intellisense. By navigating to a type instead of a Uri we eliminate the chance for typos or that we keep forgetting the first “/” in the Uri, or forgetting to mark it as Relative. All things I believe we’ve run into at least once before.

The service

Let’s build our own NavigationService for Windows Phone that supports navigating to a type, just like in Windows 8.

One important thing to remember when using this class is that the namespace of the page you want to navigate to has to be the same as the folder structure where your page lives in. For example, if you have a SecondPage.xaml that sits in a Views folder then the namespace should be MyApp.Views and the complete class name is MyApps.Views.SecondPage

First some properties

Code Snippet
  1. private PhoneApplicationFrame _rootFrame;
  2.  
  3. public bool CanGoBack { get { return _rootFrame.CanGoBack; } }
  4. public bool CanGoForward { get { return _rootFrame.CanGoForward; } }
  5.  
  6. public object RootFrame
  7. {
  8.     get { return _rootFrame; }
  9.     set
  10.     {
  11.         _rootFrame = (PhoneApplicationFrame)value;
  12.     }
  13. }

Our NavigationService needs a reference to the application’s RootFrame, the NavigationService in my case implements an interface that lives in a PCL. That PCL has no idea what PhoneApplicationFrame is so I made the property an object, the reason for the interface is that I might want to build this exact same service for other platforms.

CanGoBack and CanGoForward are read-only properties that just pass the values from the rootframe properties.

Next we’ll have a look at the most important function, navigating to another page.

Code Snippet
  1. public bool Navigate(Type destination)
  2. {
  3.     try
  4.     {
  5.         string fqname = destination.FullName;
  6.         var path = Regex.Split(fqname, @"\.");
  7.  
  8.         string destinationUri = string.Empty;
  9.  
  10.         for (int i = 1; i < path.Length; i++)
  11.         {
  12.             destinationUri = destinationUri + "/" + path[i];
  13.         }
  14.  
  15.         _rootFrame.Navigate(new Uri(destinationUri + ".xaml", UriKind.Relative));
  16.  
  17.         return true;
  18.     }
  19.     catch (Exception)
  20.     {
  21.         return false;
  22.     }
  23. }

The method takes in a Type, that type will be the page we want to reach. First thing we do is getting the full name of the type (namespace + class name), once we have that we can split the full name at each dot using a very simple Regular Expression. The first part of the namespace will be the app name, that’s something we don’t need so the for loop starts at the second item (index 1). The for loop will start building a string, the result will be something like “/Views/SecondPage.xaml”. Once we have that string we can navigate as usual by calling the Navigate function on the rootframe and passing in the Uri. Quite simple, and very effective. Other things I did was mapping some functions of the rootframe into my service like GoForward, GoBack, RemoveBackEntry and ResetBackStack. I’ve also created some overloads so that the service can still navigate the good old way by passing in either a string or a Uri.

Using the service

Using the service is pretty straightforward. You’ll need an instance of it in your app, one that’s available throughout the entire app. So either use an IOC or create a static property in your App.xaml.cs, in this example we’ll go with the App.xaml.cs way, just to keep it short.

In App.xaml.cs add this

Code Snippet
  1. public static NavigationService NavigationService { get; set; }

Then look for the InitializePhoneApplication method in App.xaml.cs (the one that says “Don’t add any additional code to this method”) and add some code to it Glimlach (lines 18 & 19)

<div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0ef5fcc9-1a48-4db5-890e-7d727f5ec64c" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#008000">// Do not add any additional code to this method</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> InitializePhoneApplication()</span></li> <li><span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">if</span><span style="background:#ffffff;color:#000000"> (phoneApplicationInitialized)</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">// Create the frame but don&#39;t set it as RootVisual yet; this allows the splash</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">// screen to remain active until the application is ready to render.</span></li> <li>    <span style="background:#ffffff;color:#000000">RootFrame = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">PhoneApplicationFrame</span><span style="background:#ffffff;color:#000000">();</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">RootFrame.Navigated += CompleteInitializePhoneApplication;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">// Handle navigation failures</span></li> <li>    <span style="background:#ffffff;color:#000000">RootFrame.NavigationFailed += RootFrame_NavigationFailed;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">// Handle reset requests for clearing the backstack</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">RootFrame.Navigated += CheckForResetNavigation;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">NavigationService = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">NavigationService</span><span style="background:#ffffff;color:#000000">();</span></li> <li>    <span style="background:#ffffff;color:#000000">NavigationService.RootFrame = RootFrame;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#008000">// Ensure we don&#39;t initialize again</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">phoneApplicationInitialized = </span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">;</span></li> <li><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div>    <p>Line 18 instantiates the service and line 19 sets the rootframe property, these two lines of code are the most important ones in the app.</p>  <p>Add some page to the app, make sure that the namespace is correct, add a button on the first page and set this as code for the button.</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4aa9c1b2-14d2-4f2e-bfb9-0fc1f02bec6d" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> Button_Click(</span><span style="background:#ffffff;color:#0000ff">object</span><span style="background:#ffffff;color:#000000"> sender, </span><span style="background:#ffffff;color:#2b91af">RoutedEventArgs</span><span style="background:#ffffff;color:#000000"> e)</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">{</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">App</span><span style="background:#ffffff;color:#000000">.NavigationService.Navigate(</span><span style="background:#ffffff;color:#0000ff">typeof</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">SecondPage</span><span style="background:#ffffff;color:#000000">));</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div>  <p>This will call the Navigate function on the static property in App.xaml.cs, pass in the type of the page and our NavigationService will do the rest.</p>  <h2>Conclusion</h2>  <p>In this post I’ve shown you a way to mimic the Windows 8 way of navigating between pages. Using this can make it easier to share code between platforms.</p>  <p>There are only two differences between this method and the native Windows 8 implementation.</p>  <ul>   <li>We need to do some plumbing in App.xaml.cs to make the service work </li>    <li>We can’t pass parameters into the navigation, but 1) that&#160; should be doable and 2) you shouldn’t do that. Use some messaging mechanism to send data between views / viewmodels </li> </ul>  <p>To end this, here’s the complete class and interface that I use regularly in my projects </p>  <p>Interface (lives in a PCL project)</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7cac8944-ebf9-4c48-9290-850a504bb688" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;summary&gt;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> Allows page navigation in the app, RootFrame needs to be set in App.xaml</span></li> <li><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;/summary&gt;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">interface</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">INavigationService</span></li> <li><span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;summary&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> The rootframe for the app, this will take care of all the navigation</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;/summary&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">object</span><span style="background:#ffffff;color:#000000"> RootFrame { </span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000">; </span><span style="background:#ffffff;color:#0000ff">set</span><span style="background:#ffffff;color:#000000">; }</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;summary&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> true when there&#39;s a page on the backstack</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;/summary&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> CanGoBack { </span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000">; }</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;summary&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> true when there&#39;s a page on the forwardstack</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;/summary&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> CanGoForward { </span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000">; }</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;summary&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> go one step back on the backstack</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;/summary&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> GoBack();</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;summary&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> go one step forward on the stack</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;/summary&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> GoForward();</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;summary&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> resets the entire backstack</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;/summary&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> ResetBackstack();</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;summary&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> remove the last entry from the backstack</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;/summary&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> RemoveBackEntry();</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;summary&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> navigate to a page using the type of the page</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;/summary&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;param name=&quot;destination&quot;&gt;</span><span style="background:#ffffff;color:#008000">the type of the page we want to navigate to</span><span style="background:#ffffff;color:#808080">&lt;/param&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;param name=&quot;parameter&quot;&gt;</span><span style="background:#ffffff;color:#008000">an optional parameter</span><span style="background:#ffffff;color:#808080">&lt;/param&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;returns&gt;</span><span style="background:#ffffff;color:#008000">true/false</span><span style="background:#ffffff;color:#808080">&lt;/returns&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> Navigate(</span><span style="background:#ffffff;color:#2b91af">Type</span><span style="background:#ffffff;color:#000000"> destination);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;summary&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> navigate to a page using a uri string, paramers are passed using querystring</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;/summary&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;param name=&quot;uri&quot;&gt;</span><span style="background:#ffffff;color:#008000">string pointing to the page we want to navigate too</span><span style="background:#ffffff;color:#808080">&lt;/param&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;returns&gt;&lt;/returns&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> Navigate(</span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> uri);</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;summary&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> navigate to a page using a uri, paramers are passed using querystring</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;/summary&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;param name=&quot;uri&quot;&gt;</span><span style="background:#ffffff;color:#008000">uri we want to navigate too</span><span style="background:#ffffff;color:#808080">&lt;/param&gt;</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#808080">///</span><span style="background:#ffffff;color:#008000"> </span><span style="background:#ffffff;color:#808080">&lt;returns&gt;&lt;/returns&gt;</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> Navigate(</span><span style="background:#ffffff;color:#2b91af">Uri</span><span style="background:#ffffff;color:#000000"> uri);</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div>  <p>Implementation in a Windows Phone project</p>  <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:49253a26-9aa9-4e63-8f9a-e6863a2a57e3" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">class</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">NavigationService</span><span style="background:#ffffff;color:#000000"> : </span><span style="background:#ffffff;color:#2b91af">INavigationService</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">{</span></li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">PhoneApplicationFrame</span><span style="background:#ffffff;color:#000000"> _rootFrame;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> CanGoBack { </span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000"> { </span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> _rootFrame.CanGoBack; } }</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> CanGoForward { </span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000"> { </span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> _rootFrame.CanGoForward; } }</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">object</span><span style="background:#ffffff;color:#000000"> RootFrame</span></li> <li>    <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000"> { </span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> _rootFrame; }</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">set</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">{</span></li> <li>            <span style="background:#ffffff;color:#000000">_rootFrame = (</span><span style="background:#ffffff;color:#2b91af">PhoneApplicationFrame</span><span style="background:#ffffff;color:#000000">)</span><span style="background:#ffffff;color:#0000ff">value</span><span style="background:#ffffff;color:#000000">;</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">}</span></li> <li>    <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> GoBack()</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">{</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">if</span><span style="background:#ffffff;color:#000000"> (!_rootFrame.CanGoBack) </span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000">;</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>        <span style="background:#ffffff;color:#000000">_rootFrame.GoBack();</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">}</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> ResetBackstack()</span></li> <li>    <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">_rootFrame.BackStack.GetEnumerator().Reset();</span></li> <li>    <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> RemoveBackEntry()</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">{</span></li> <li>        <span style="background:#ffffff;color:#000000">_rootFrame.RemoveBackEntry();            </span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">}</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> GoForward()</span></li> <li>    <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">if</span><span style="background:#ffffff;color:#000000"> (!_rootFrame.CanGoForward) </span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000">;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">_rootFrame.GoForward();</span></li> <li>    <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> Navigate(</span><span style="background:#ffffff;color:#2b91af">Type</span><span style="background:#ffffff;color:#000000"> destination)</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">{</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">{</span></li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> fqname = destination.FullName;</span></li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> path = </span><span style="background:#ffffff;color:#2b91af">Regex</span><span style="background:#ffffff;color:#000000">.Split(fqname, </span><span style="background:#ffffff;color:#a31515">@&quot;&#92;.&quot;</span><span style="background:#ffffff;color:#000000">);</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> destinationUri = </span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000">.Empty;</span></li> <li>&nbsp;</li> <li style="background: #f3f3f3">            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">for</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#0000ff">int</span><span style="background:#ffffff;color:#000000"> i = 1; i &lt; path.Length; i++)</span></li> <li>            <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3">                <span style="background:#ffffff;color:#000000">destinationUri = destinationUri + </span><span style="background:#ffffff;color:#a31515">&quot;/&quot;</span><span style="background:#ffffff;color:#000000"> + path[i];</span></li> <li>            <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="background:#ffffff;color:#000000">_rootFrame.Navigate(</span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Uri</span><span style="background:#ffffff;color:#000000">(destinationUri + </span><span style="background:#ffffff;color:#a31515">&quot;.xaml&quot;</span><span style="background:#ffffff;color:#000000">, </span><span style="background:#ffffff;color:#2b91af">UriKind</span><span style="background:#ffffff;color:#000000">.Relative));</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">;</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">}</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000">)</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">{</span></li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">false</span><span style="background:#ffffff;color:#000000">;</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">}</span></li> <li>    <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> Navigate(</span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> uri)</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">{</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">{</span></li> <li>            <span style="background:#ffffff;color:#000000">_rootFrame.Navigate(</span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Uri</span><span style="background:#ffffff;color:#000000">(uri, </span><span style="background:#ffffff;color:#2b91af">UriKind</span><span style="background:#ffffff;color:#000000">.Relative));</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">;</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">}</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000">)</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">{</span></li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">false</span><span style="background:#ffffff;color:#000000">;</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">}</span></li> <li>    <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>    <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> Navigate(</span><span style="background:#ffffff;color:#2b91af">Uri</span><span style="background:#ffffff;color:#000000"> uri)</span></li> <li style="background: #f3f3f3">    <span style="background:#ffffff;color:#000000">{</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">try</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">{</span></li> <li>            <span style="background:#ffffff;color:#000000">_rootFrame.Navigate(uri);</span></li> <li style="background: #f3f3f3">&nbsp;</li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">;</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">}</span></li> <li>        <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">catch</span><span style="background:#ffffff;color:#000000"> (</span><span style="background:#ffffff;color:#2b91af">Exception</span><span style="background:#ffffff;color:#000000">)</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">{</span></li> <li>            <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">false</span><span style="background:#ffffff;color:#000000">;</span></li> <li style="background: #f3f3f3">        <span style="background:#ffffff;color:#000000">}</span></li> <li>    <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div>  <p>Enjoy!</p>

This is an imported post. It was imported from my old blog using an automated tool and may contain formatting errors and/or broken images.

Leave a Comment