Silverlight 3's New Navigation Framework

7 Comments April 7, 2009

One of Silverlight 3's prominent new features is its built-in navigation framework. This framework allows you to break your content into navigable chunks, or "pages," that derive from the new System.Windows.Controls.Page class. Pages are addressable by URI, just like pages in a conventional Web application, and the new System.Windows.Controls.Frame class provides an API for navigating among pages and integrating with the browser's history mechanism. One of the benefits of using the navigation framework is that it (gasp!) enables the browser's Back and Forward buttons. It also lends a degree of SEO friendliness to Silverlight since individual pages can be identified by URL.

I wrote a simple application to demonstrate the basics of the navigation framework. You can download the app and check it out for yourself. MainPage.xaml hosts a Frame control that provides visibility into two pages: Index.xaml, which displays a collection of aircraft, and Detail.xaml, which displays a detailed view of a particular aircraft. Index.xaml is displayed when the application first comes up; here's what it looks like:

Navigation Demo Home Page

And here's what you see when you click one of the aircraft images (in this case, the one in the middle):

Navigation Demo Detail Page 

Index.xaml uses Silverlight 3's new WrapPanel control with some manual data binding to display all the aircraft. The aircraft are represented by instances of a simple custom class named Aircraft, and a separate class named Hangar has methods for retrieving collections of Aircraft objects as well as individual Aircraft objects.

A good starting point for exploring the sample application is MainPage.xaml, which declares a Frame control and sets the default page to "Aircraft:"

<nav:Frame x:Name="Main" Source="Aircraft" ... /> 

An instance of UriMapper declared in App.xaml maps requests for "Aircraft" to Index.xaml. Note that in Silverlight 3 Beta 1, the UriMapper must be named "uriMapper," or else it will not work:

<nav:UriMapper x:Key="uriMapper">

  <nav:UriMapping Uri="Aircraft" MappedUri="/Index.xaml" />

  <nav:UriMapping Uri="Detail/{id}" MappedUri="/Detail.xaml?id={id}" />

</nav:UriMapper>

When you click one of the images in Index.xaml, the following event handler retrieves the corresponding aircraft ID from the image's Tag property and navigates to Detail.xaml, passing the aircraft ID in the URI:

void OnImageClicked(object sender, MouseButtonEventArgs e)

{

    string id = ((FrameworkElement)sender).Tag.ToString();

    NavigationService.Navigate(new Uri(String.Format

        ("Detail/{0}", id), UriKind.Relative));

}

Thanks to the second URI mapping in the UriMapper above, "Detail/1000" becomes "/Detail.xaml?id=1000," and the following statement in Detail.xaml.cs extracts the aircraft ID from the query string:

string sid = NavigationContext.QueryString["id"];

Once the aircraft ID is known, a few additional statements in Detail.xaml.cs retrieve the corresponding Aircraft object and use properties of that object to initialize the Image and TextBlock declared in the page.

When you run the application, notice that after you've clicked a few times, you can use the browser's Back and Forward buttons to navigate around. Also notice that you can bookmark a page that shows a particular aircraft (for example, "NavigationDemoTestPage.html#Detail/1001") and go back to that page simply by pasting the URL into the browser's address bar.

Using UriMapper isn't strictly necessary, but the beauty of URI mapping is that it allows you to control your URIs. I would rather a user see "NavigationDemoTestPage.html#Aircraft" in the browser's address bar than "NavigationDemoTestPage.html#/Index.xaml." The more complex the URI, the more you'll appreciate URI mapping.

There is much, much more to the navigation framework than I have presented here, but this sample covers the essentials. Tim Heuer and others have blogged about the navigation framework more extensively and have even posted some helpful videos, including this one. If your chief concern about previous versions of Silverlight is lack of navigability and incompatibility with search engines, the navigation framework is something you'll find worth digging into.


7 Comments

  • Gravatar Image
    Friday Links #46 | Blue Onion Software * April 10, 2009 5:22 PM

    PingBack from http://blueonionsoftware.com/blog.aspx?p=c6458c1d-1684-463c-b03e-8796851f4f69

  • Gravatar Image
    Adam April 23, 2009 2:21 AM

    Does the navigation framework allow for method calls like:

    NavigationService.Navigate(new Uri(String.Format ("/mypage.html"), UriKind.Relative));

    NavigationService.Navigate(new Uri(String.Format ("http://www.google.com"), UriKind.Absolute));

    Thanks and good article!

    -Adam

  • Gravatar Image
    Adam April 23, 2009 2:23 AM

    In silverlight can the following be called at all?

    NavigationService.Navigate(new Uri(String.Format("/Test.html"), UriKind.Absolute));

    NavigationService.Navigate(new Uri(String.Format("http://www.google.com"), UriKind.Absolute));


    Thanks and it was a good article!

  • Gravatar Image
    Il blog di Luca Mauri June 23, 2009 9:03 AM

    Silverlight 2.0 Navigation Page

  • Gravatar Image
    John Mcfetridge August 18, 2009 11:50 AM

    I downloaded your code and tried running with Silverlight 3 but the application fails at startup:

    Navigation is only supported to URIs that are fragments or begin with slash.

  • Gravatar Image
    Marie November 5, 2009 1:54 AM

    You sample is not working
    Error 1 The type or namespace name 'WrapPanel' does not exist in the namespace 'System.Windows.Controls' (are you missing an assembly reference?) Silverlight 3's New Navigation Framework\NavigationDemo\NavigationDemo\obj\Debug\Index.g.cs 54 56 NavigationDemo

    Which missing assembly should I reference?

    Note the complaint is in the generated code!!!
    Thank you.

  • Gravatar Image
    jprosise November 5, 2009 6:36 AM

    WrapPanel was in the Silverlight 3 beta but was not shipped in the RTW bits. You either have to remove the WrapPanel or get it from the Silverlight Toolkit.

Have a Comment?

Archives

Tags