This is part 1 of my Silverlight 3 Feature By Feature series of blog posts.
No More Blank Slate
The first thing you may try after installing the Silverlight 3 Beta 1 Tools is creating a new Silverlight application. There is a new project template available called Silverlight Navigation Application. Using this project template creates a Silverlight project with a few things already set up for you. This is a departure from what we've had so far - a blank slate that is intimidating and doesn't really help new developers.
The new project contains the typical App.xaml but now with a bunch styles used in the main page. The MainPage.xaml is a generic, but nice looking, layout for an example Silverlight application. There are links to the Home and About views, which are both located in the Views folder of the project along with a view reserved for errors.

Running the application without any changes shows the full page Silverlight application. Click on the links will change the URL in your browser and update the browsing history. You can use these URLs to go to a specific view. For example, from the About view copy the URL, then open an alternative browser and paste in the URL. Viola! Deep linking!
How It Works
The trick to the navigation, as implemented in the project template, is the Frame control in MainPage.xaml.
1: <UserControl x:Class="SilverlightNavigation.MainPage"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation">
5: ...
6: <navigation:Frame x:Name="Frame" Source="/Views/HomePage.xaml"
7: HorizontalContentAlignment="Stretch"
8: VerticalContentAlignment="Stretch"
9: Padding="15,10,15,10"
10: Background="White"/>
11: ...
12: </UserControl>
In particular, notice the navigation namespace. The project has a reference to the System.Windows.Controls.Navigation assembly which contains new controls and other things used for navigation.
The Frame is instructed to navigate in the Click event handler of the buttons.
1: private void NavButton_Click(object sender, RoutedEventArgs e)
2: { 3: Button navigationButton = sender as Button;
4: String goToPage = navigationButton.Tag.ToString();
5: this.Frame.Navigate(new Uri(goToPage, UriKind.Relative));
6: }
I don’t exactly like the method of storing the destination page in the buttons’ Tag property, but that could easily be encapsulated by a custom NavigationButton control. Perhaps we’ll get one before RTW? I’ll definitely have to expand on this in a separate blog post.
HomePage.xaml and AboutPage.xaml are both Page objects instead of UserControl, which is typically the base control of new XAML files in a Silverlight 2 project. Its easy enough to add new navigable content to your application. Just add a new item to your project, and choose the Silverlight Page template in the Add New Item dialog.
Custom Navigation
What I wanted to do with my Silverlight Overview application was have a tree view control listing all of the examples, and each of these example pages showing up as a unique URL so I could link to a specific example. My original Silverlight Demo application had examples split into tab controls. Each tab was a separate XAML file. I could have modified these to be a Page instead of UserControl, but I wanted to break them down further and didn’t relish the thought of having 30+ Page files.
Using Reflector, I found that the Frame control’s Navigate method is using the NavigationService. Looking into this code wasn’t leading me anywhere so I decided to look at the Silverlight 3 documentation on MSDN. Interestingly, the only page that I found related to navigation, Navigation Overview, hasn’t been updated for Silverlight 3 and contains incorrect information. Finally I found Tim Heuer’s Navigation Framework screencast and blog post which shows how to use the UriMapper to accomplish what I’m looking for.
<nav:UriMapper x:Key="uriMapper">
<nav:UriMapping Uri="Examples/{example}" MappedUri="/ExamplePage.xaml?example={example}" /></nav:UriMapper>
Currently the UriMapper can only be defined in the App.xaml. Hopefully we’ll be able to move this to resource dictionary or even the same file as the Frame control.
Along with my changes to the App.xaml I added one Page to my project, ExamplePage.xaml.
<navigation:Page x:Class="SilverlightOverview.ExamplePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
Title="Example Page"
xmlns:slo="clr-namespace:SilverlightOverview"
Loaded="Page_Loaded">
<Grid x:Name="LayoutRoot" Background="White">
<slo:XamlViewer x:Name="viewer" />
</Grid>
</navigation:Page>
1: public partial class ExamplePage
2: { 3: public ExamplePage()
4: { 5: InitializeComponent();
6: }
7:
8: private void Page_Loaded(object sender, RoutedEventArgs e)
9: { 10: if (this.NavigationContext.QueryString["example"] != null)
11: { 12: viewer.XamlFilename = string.Format("SilverlightOverview.Xaml.{0}.xaml", 13: this.NavigationContext.QueryString["example"]);
14: }
15: }
16: }
Running the project shows that my URLs to look like this.
You can even try it for yourself if you have the Silverlight 3 Beta 1 runtime installed.
I really wanted to avoid the “Examples/” part of the URL since I only have one view, but there is a limitation built in which throws exceptions if I don’t have at least a something in there.
At this point all I had to do was add a TreeView and Frame to a Grid in my MainPage.xaml, bind the tree to a static list of example data, and my application is running. I’d like to figure out a way to dynamically change the page’s title, but I ran out of time. At first glace it appears that the only place to do this is from within the Page control, but I bet there’s way to get the currently displayed page from the Frame.
You can view the Silverlight Overview application here. At the time of writing this blog post, the deep linking is the only Silverlight 3 feature that’s been added.
Summary
The Good: The Navigation Framework is a really great addition to Silverlight!
The Bad: I’d rather be able to manually add items to the browser history and display pages based on the URL, but this solution will be fine for now. I think there might be a way to do that, but I could not find any other documentation and I ran out of time to look through everything with Reflector.
The Beautiful: I finally have something to point to when Flash developers ask what Silverlight has to offer that Flash/Flex does’t.
(note – I wanted to summarize with the good, the bad and the ugly, but there’s nothing truly ugly about Silverlight 3 so I went with the opposite)