Silverlight 4 Project Types part II – Silverlight Navigation Application

Last time, I took a look at what gets created when you create a new Silverlight project and choose Silverlight Application as your project type in the New Project wizard.  Now I’d like to look at the Silverlight Navigation Application project type that is new for Silverlight 4.

As usual, I’d like to walk through the process of creating a new project and then take a quick peek at what’s under the covers.  There are a number of pieces here that are complex enough for their own blog post.  So I’ll probably use the phrase “cover this later” a lot.  My goal right not is to just get a high-level view of the Silverlight Navigation Application.

Just a quick note on the tooling: I’m currently still using the Beta 2 build of Visual Studio 2010.  So some of the behavior or layout might be different from the final release.

Below is an image of the New Project dialog in Visual Studio, showing the new Silverlight Navigation Application choice.  This is the type of project that I’ll be creating.

If you pay attention to the text describing each template, displayed over on the right, you’ll see a slight difference between the Silverlight Application and the Silverlight Navigation Application.

  • Silverlight Application – A blank project for creating a rich internet application using Silverlight
  • Silverlight Navigation Application – A project for creating a rich internet application using Silverlight

So with the Silverlight Navigation Application, you get just a bit more of the framework for an actual production Silverlight application.

If we click OK to continue, we get the familiar dialog for creating a sample web project in which to host the Silverlight application.  As before, we can choose between a Web Application, a Web Site, or an MVC Web Site.  I’ll just pick a Web Application project type.

Note the new checkbox on this dialog labeled Enable .NET RIA Services.  RIA Services (now called WCF RIA Services) is an n-tier design pattern in which you have Silverlight on the client, ASP.NET as the middle tier and then some sort of data tier.  More on this later.  For now, you can get an introduction at the WCF RIA Services home page.  I first heard about RIA Services at Microsoft’s PDC 2008 conference and remembering that it sounded very similar in its goals to Rocky Lhotka’s CSLA.NET for Silverlight framework.

Let’s compare the Silverlight Application and Silverlight Navigation Application projects side by side.  Here’s the high-level view.  (The Silverlight Navigation Application is on the right).

The first difference you’ll notice are the Assets and Views folders in the Silverlight Navigation Application.  Taking a quick peek at these folders, you get an idea of what they contain.

The navigation application adds a Resource Dictionary, Styles.xaml, which serves as a sort of stylesheet for the application.  In the Views folder, we get a new control for displaying errors, ErrorWindow.xaml, and a couple pages where we’ll show our actual web site content, About.xaml and Home.xaml.

We’ll find the biggest changes in the MainPage.xaml file and its code-behind.  But before we take a look at the code, let’s just run our application to see what it looks like so far.

Wow.  That’s slick.  Instead of the blank page that we got with the Silverlight Application, it looks like we get a small, but fully functional web site, implemented entirely in Silverlight.

If you move the mouse around a little bit, you’ll discover that you can click on the home and about labels in the upper right corner of the page to navigate between a Home page and an About page.  When the Silverlight application first starts, we get the Home page.  If you click on the about label, you navigate to the About page.

This highlights that there are two fundamentally different ways to use Silverlight:

  • Silverlight controls embedded in ASP.NET web pages
  • Silverlight as the entire application

In the first case, you create individual Silverlight controls for the areas of your web site where you need a richer user experience and embed them in ASP.NET (or plain old HTML) web pages.  You can think of the Silverlight as little islands of interaction embedded in a traditional ASP.NET web site.

The other basic way to use Silverlight, highlight by the Silverlight Navigation Application, is to make Silverlight handle the entire user experience.  Instead of a web page, you have Silverlight running in the browser as a true RIA (Rich Internet Application).

Which is a better way to use Silverlight?  Neither.  You might consider creating your entire web application in Silverlight, to give your users a richer experience.  But doing that also means that you’re hiding your content in a Silverlight black box that search engines might not be able to crack open to get at the content.  It also means that you’re out of luck for users who haven’t downloaded and installed the Silverlight plug-in.

The Main Page

Ok, let’s go back to the XAML for the main page and figure out how this page navigation is working.

If we’re curious about how things get started, we can go back to the project and note that the App object is listed as the startup object for our application.  If we look at its code behind, we see that it sets the main object to be displayed as an instance of MainPage, just like the standard Silverlight Application.

Before we look in any detail at the MainPage object, let’s take a quick look at how it looked for our standard Silverlight Application–the template that Visual Studio calls a “blank” Silverlight project.  Here’s the XAML:

MainPage is just a UserControl that contains a white grid, onto which you can put anything that you like.  This is the tabla rasa for Silverlight controls.

Now let’s take a look at the same XAML, for the MainPage object, in our Silverlight Navigation Application.  We find that it also derives from UserControl and the XAML consists of a UserControl tag, which contains a Grid.  But this time, the grid is far from empty.

There’s a lot of junk in the XAML for the MainPage control.  But if we strip it down to the main elements, we get the following basic outline (starting with the outer Grid, which is contained in the UserControl):

<pre><Grid Name="LayoutRoot">
    <Border Name="ContentBorder">
        <navigation:Frame Name="ContentFrame">
    </Border>
    <Grid Name="NavigationGrid">
        <Border Name="BrandingBorder">
            <StackPanel Name="BrandingStackPanel"/>
        </Border>
        <Border Name="LinksBorder">
            <StackPanel Name="LinksStackpanel"/>
        </Border>
    </Grid>
</Grid>

This looks a bit busy, but it’s pretty straightforward.  The two main objects in the XAML match the two main areas of the screen that we saw when we ran our Silverlight application–a navigation area at the top of the window that contains the “home” and “about” navigation buttons and then our main content area.  This content area is a container (a Frame object) that will contain our actual content (individual Page objects).

In this XAML fragment, ContentFrame is the container where we put all of our main web page content.  It’s contained, in turn, in a Border object that will add some basic formatting to the frame.

The NavigationGrid object, which contains the navigation buttons, is a little less interesting.  So let’s look first at the ContentBorder and the ContentFrame.

Here’s the full XAML fragment for these guys:

<Border x:Name="ContentBorder" Style="{StaticResource ContentBorderStyle}">
    <navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}"
                      Source="/Home" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed">
        <navigation:Frame.UriMapper>
            <uriMapper:UriMapper>
                <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>
                <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>
            </uriMapper:UriMapper>
        </navigation:Frame.UriMapper>
     </navigation:Frame>
</Border>

The ContentBorder is just a wrapper around the ContentFrame that adds:

  • A margin at the top of the page, making room for the navigation controls
  • A gradient brush for the frame’s background

You can see the details by opening the Styles.xaml file and looking at the ContentBorderStyle style.

The Navigation Frame

The frame object (System.Windows.Controls.Frame) is where all of the magic happens.  MSDN says that this control is a “content control that supports navigation”.

The basic idea of a Frame is that you can tell it the URI of the content that you want to have it display.  You normally do this by setting its Source property or by calling its Navigate method.

When our application first starts up, the Source property of the ContentFrame gets set to “/Home”, since it’s set in the XAML.  This causes the /Views/Home.xaml page to get loaded by default.

But we also load content into the frame when we click on the home and about buttons in the navigation grid at the top of the screen.  These two buttons are actually HyperlinkButton objects.  Here’s the XAML for our about button (you can find this in MainPage.xaml):

<HyperlinkButton x:Name="Link2" Style="{StaticResource LinkStyle}"
                 NavigateUri="/About" TargetName="ContentFrame" Content="about"/>

The HyperlinkButton lets us navigate to a new web page by specifying a URI and the target control where that URI should get loaded.  In our case, we tell it to load “/About” as the URI in our ContentFrame.  This will have the same effect as if we’d set the Source property of the ContentFrame to “/About”.

So we change the content in the ContentFrame object at three different points:

  • At startup, we navigate to Home.xaml
  • When user clicks on the about button, we navigate to /Views/About.xaml
  • When user clicks on the home button, we navigate to /Views/Home.xaml

URI Mapping

But how is it that we specified “/About” as a URI and we end up at the page /Views/About.xaml”?  When we just specify “/About”, how does the Frame get the exact URI that describes how to find the actual .xaml file?

This happens through something called URI Mapping.  URI mapping simply means that you can map one URI to another, using a simple lookup table.  In general, this is used to map longer URIs to shorter, or internal, URIs.  In our case, when we pass the URI “/About” to our Frame, it uses its UriMapper object to map this URI to “/Views/About.xaml”–the true path to the page that we want to load.

You can see the rule that does this mapping in the XAML fragment above that contains the ContentFrame and XAML elements that specify the UriMapper property of the Frame.  We basically have two rules:

  • Map an empty URI to “/Views/Home.xaml”  (the default/home page)
  • Map “/something” to “/Views/something.xaml”

The second rule is the interesting one.  In the individual UriMapping objects, we can do some basic pattern matching, using one or more variables, denoted by braces.  So the rule lets a user enter just a page name and our mapping fills in the rest.  The mapping rule looks like this:

    <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/></pre>

The whole point here, when we’re talking about user-entered URIs, is that we can hide the details of the URI path from the user and give them something easier to remember and easier to enter.

In the Silverlight Navigation Application example, users aren’t directly entering URIs.  But it still helps to simplify the URIs that we need to specify when setting up the HyperlinkButton objects.

By the way, it’s interesting to note that the Frame class in the main .NET Framework does not support URI mapping, while the Frame class in the Silverlight version of the framework does.

More Fun With Frames

One other very interesting thing about the Frame control is that not only can you tell it to navigate to various pages, but that it remembers its navigation history.  We could then tap into that history and tell the Frame to navigate forward or backward through its history.  For example, I could add a couple of buttons, label them Forward and Back and then add the following code behind.

    private void btnBack_Click(object sender, RoutedEventArgs e)
    {
        if (ContentFrame.CanGoBack)
            ContentFrame.GoBack();
    }

    private void btnForward_Click(object sender, RoutedEventArgs e)
    {
        if (ContentFrame.CanGoForward)
            ContentFrame.GoForward();
    }

We check the CanGoBack and CanGoForward properties before navigating, because if you try to navigate past either the beginning or end of the history, Silverlight will throw an exception.

Even better, the Frame’s navigation history is automatically integrated to the web browser’s history itself (the journal), using the JournalOwnership property.

You can prove this to yourself by running the application generated by the wizard, clicking on the home and about buttons several times and then using the browser’s Back button to see that you can navigate through the pages that you’ve just visited.

This is actually pretty important.  One of the drawbacks of implementing a Rich Internet Application in a black-box technology like Flash is that if you’re navigating between pages, the user loses the ability to use the browser’s navigation buttons to move back/forward through these pages.  Using a Silverlight Frame control addresses this because it ties directly in with the browser’s navigation history.

Wrapping Up

That’s about it for the Silverlight Navigation Application.  The one remaining thing that you can look at is the ContentFrame_Navigated code, in MainPage.xaml.cs. This function is responsible for changing the visual look of the navigation buttons after you click on one of them, to show which content is currently being shown.

The other thing that’s worth doing is opening one of the pages from this project in Expression Blend(As of May, 2010, there is currently a Release Candidate of Blend 4 out that includes support for Silverlight 4).

The easiest way to pop over to Blend from Visual Studio is to just right-click on one of the pages and selected the Open in Expression Blend menu option.

You just click on this option and Blend 4 fires up, opens your project, and then opens the same page in Blend.  Wow.

It’s a good idea to get into the habit of being just as comfortable editing your pages in Blend as you are in Visual Studio.  And that little shortcut in the context menu helps with that quite a bit.

That’s all for now.  Next time I’ll take a look at the next Silverlight project type–the Silverlight Class Library.

4 thoughts on “Silverlight 4 Project Types part II – Silverlight Navigation Application

  1. Pingback: Silverlight 4 Project Types part III – Silverlight Class Library « Sean’s Stuff

  2. Pingback: Silverlight 4 Project Types part I – Silverlight Application « Sean’s Stuff

  3. Hi, I am learning Silverlight. I am a Web designer who designs screens with GUI for asp.net project, html simple websites etc.
    I want to know whether we can design business applications in silverlight. In silverlight navigation application project, can I use my own stylesheet instead of the Built in style which is quite complex.
    Which is best suitable for a business website? Silverlight Navigation app or Silverlight App. Can we use xaml pages with c# code behind?

    • You should consider silverlight (because it’s quick and easy to develop) only if the business is using the tool in house where you can specify to users what browser or OS to run on. If this is for customers to access your business, Silverlight is not fully cross platform (Unix, Mac) compatible or cross browser compatible (plugin installation on firefox/safari have been known to happen). The worst would be to have a client hit your business site and they get a blank screen. I remember a couple of years ago (2010) when microsoft had the silverlight product website built in silverlight and it was such a dog that they removed it and went HTML. That’s gotta tell you something.

Leave a comment