In post-after-post I've been digging deeper and deeper into the innards of nRoute, whilst neglecting a gentler way in - to correct that this post will provide a simple quick start. We'll create a sort of master page, and a couple of child pages to navigate. So let's get on..
Step 1.
We start with an empty Silverlight application, named what ever you prefer. It will probably ask you about hosting options, you can choose either but an automatically generated test page should suffice.
Step 2.
We need to add reference to nRoute's assembly, a downloadable version of the assembly is available at Codeplex or you can compile your own version if you have the source code.
Step 3.
Once we have referenced the assembly, on the main page (Page.xaml, which will act as our master page or shell if you like), we will import two namespaces from the nRoute.Silverlight assembly. The nRoute.Controls namespace provides us with a navigation container and the nRoute.Behaviours.Navigation provides us with attachable behaviours. An abbreviated version of the page.xaml is show below, note I also remove the Width and Height attributes.
<UserControl
...
xmlns:cntr="clr-namespace:nRoute.Controls;assembly=nRoute.Silverlight"
xmlns:nav="clr-namespace:nRoute.Behaviours.Navigation;assembly=nRoute.Silverlight">
<Grid x:Name="LayoutRoot" Background="White">
</Grid>
</UserControl>
Step 4.
Up next, we will create the main page's layout. I prefer the grid control to structure the layout, so in this case will take the existing Layout grid and add two rows to it, with the first one being locked at 50(px), and other filling up the rest of the space. We will also add two controls to the grid, one a horizontal oriented stack panel for the first row, and a navigation container for the second row named "DefaultContainer". The xaml for the grid is show below:
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- NAVIGATION LINKS -->
<StackPanel Grid.Row="0" Orientation="Horizontal"></StackPanel>
<!-- MAIN CONTAINER -->
<cntr:NavigationContainer Grid.Row="1" x:Name="DefaultContainer" />
</Grid>
Step 5.
Next we will add a couple of hyperlinks in the stack panel, this will represents a sort of flat menu which links to the various pages in the app. The hyperlink control will be appended with navigation related behaviours, one that identifies the Url to navigate to and another specifies which container should the navigation occur in, and the only answer available is the "DefaultContainer" element. Also, we will have three pages namely Home Page (available at Url "Pages/Home/") , About Us (available at Url "Pages/AboutUs") and Contact Us (available at Url "Pages/ContactUs"). The xaml below shows the stack panel, note the margin and alignment.
<!-- NAVIGATION LINKS -->
<StackPanel Grid.Row="0" Orientation="Horizontal"
VerticalAlignment="Center" HorizontalAlignment="Center">
<HyperlinkButton Content="Home Page" Margin="10"
nav:Click.NavigateUrl="Pages/HomePage/"
nav:Click.NavigateHandlerElementName="DefaultContainer"/>
<HyperlinkButton Content="About Us" Margin="10"
nav:Click.NavigateUrl="Pages/AboutUs/"
nav:Click.NavigateHandlerElementName="DefaultContainer" />
<HyperlinkButton Content="Contact Us" Margin="10"
nav:Click.NavigateUrl="Pages/ContactUs/"
nav:Click.NavigateHandlerElementName="DefaultContainer" />
</StackPanel>
Step 6.
Now that we have a navigation structure, we will create three user controls to represent the links enlisted. And I suggest we add a folder in Visual Studio named "Views", where we will add three user-controls appropriately named "HomePage.xaml", "AboutUs.xaml" and "ContactUs.xaml". Note, the folder and user-control names are not particularly important, since we abstract them as Urls (really a boon for refactoring). Now, in the code-behind files for all the three controls we will add an attribute on each of the classes, identifying them as an content addressable by the given Url, along with a title for the page. The MapNavigationContent Attribute is available in the nRoute.Navigation namespace.
Step 7.
As for the content pages we need to fill it with some visuals - obviously so that it is discernable. I suggest let's add a Textblock in each saying I am so and so page with a different background colour to jar the senses. Secondly, we need to get rid of the default Width and Height Attributes as it will inherit the size from the container. Below is what my abbreviated xaml looks like for each of user controls.
<!-- Home Page User Control -->
<UserControl x:Class="SimpleQuickStart.Views.HomePage" ... >
<Grid x:Name="LayoutRoot" Background="LightBlue">
<TextBlock Text="I am the home page." />
</Grid>
</UserControl>
<!-- About Us User Control -->
<UserControl x:Class="SimpleQuickStart.Views.AboutUs"... >
<Grid x:Name="LayoutRoot" Background="GreenYellow">
<TextBlock Text="I am the about us page."/>
</Grid>
</UserControl>
<!-- Contact Us User Control -->
<UserControl x:Class="SimpleQuickStart.Views.ContactUs" ... >
<Grid x:Name="LayoutRoot" Background="LightCoral">
<TextBlock Text="I am the contact us page."/>
</Grid>
</UserControl>
Step 8.
Lastly, we need to do two more things , one on the main page where we have the navigation container we need to tell it which page to show initially by setting it's "InitialUrl" property to the home page Url ("Pages/HomePage/") or which every Url you prefer. Secondly, in the application's code-behind file (App.xaml.cs) we need to call into the Navigation Service to automatically register all Urls mapped via attributes. This is a single call you place in the startup event-handler for the application, as show below.
<!-- In the main page, we set the InitialUrl property -->
<cntr:NavigationContainer Grid.Row="1" x:Name="DefaultContainer"
InitialUrl="Pages/HomePage"/>
// In the application start up event, we call for automatically mapping
// of all attributes defined navigation urls
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new Page();
nRoute.Navigation.NavigationService.MapLoadedAssembliesRoutes();
}
And that's it we are done, we should now have an ugly-ass app for all our hard-work. Let me just recap the steps, you create a navigation container, then append your content with the relevant attribute, importantly call for auto-mapping to occur, set the initial Url to show, and setup the links/behaviours to functionalize the app. To simplify some of these steps, and a better design-time experience expect a set of Visual Studio templates.
In the follow-up post I'll take on simplifying this code, introducing application-level containers, showing alternative ways of mapping, highlight both deep-linking and browser shell-integration and hopefully stylise the look and feel. So do stay tuned, below you'll find the sample app running and the code for this quickstart.
Quickstart Code (88 KB, includes nRoute.Silverlight.dll)