Silverlight - Navigate to a specific Page using a Hyperlink
Sometimes I think it’s hard to know what I should write about, my ideas comes from different sources. Some of my posts is based on questions people are asking on forums. If someone ask one specific question, it’s a big chance that someone else have the same kind of question, so I often blog about the solution so others kind find them. So this blog post will be about how we can from a HTML page navigate to a page hosting a Silverlight application and navigate to a specific .XAML page. Probably someone else have blogged about this before but I also use my blog as a reference for my self :P
If we have our Silverlight control hosted on a page, for
example default.aspx, the Silverlight will always show the
same .XAML page when the page is loaded. This is because the
visual root is set within the App file when the Application
is started:
private void Application_Startup(object sender, StartupEventArgs e) { this.RootVisual = new MainPage(); }
We must specify a RootVisual when the application is started
and that will make the Silverlight application always show a
specific page when we request the the page hosting the
Silverlight application. So how can we from a hyperlink
navigate to our Silverlight host page and specify which page
we want to show? The RootVisual is of type UIElement, so we
can set any kind of UIElement to be the RootVisual, for
example a Grid and add a UserControl as a Child to the Grid,
like this:
private void Application_Startup(object sender, StartupEventArgs e) { var rootGrid = new Grid(); this.RootVisual = rootGrid; rootGrid.Children.Add(new MainPage()); }
The following code will still show the MainPage
UserControl but this time inside of a Grid. Because we can
specify any kind of UIElement as the RootVisual, and in this
example a Grid, we can now dynamically add UIElements to the
RootVisual’s UIElement. By using Reflection we can create an
instance of the UserControl from a string, so we can for
example get the name of the UserControl we want to display
form a QueryString. We can use an URL like this
“default.aspx?page=Page2” when we want to request the page
hosting the Silverlight application and show the Page2.xaml
at startup.
Here is the code which will get the Page from a QueryString:
private void Application_Startup(object sender, StartupEventArgs e) { var rootGrid = new Grid(); this.RootVisual = rootGrid; var pageToShow = GetPageFromQueryString(); if (string.IsNullOrEmpty(pageToShow)) pageToShow = "MainPage"; var userControlToShow = LoadPage(pageToShow); rootGrid.Children.Clear(); rootGrid.Children.Add(userControlToShow); } private static UserControl LoadPage(string pageToShow) { var appType = App.Current.GetType(); var userControlTypeString = appType.Namespace + "." + pageToShow; var userControlToShowType = Type.GetType(userControlTypeString); if (userControlToShowType == null) throw new Exception(string.Format("Can't find the Page with the type {0}", userControlTypeString)); var userControlToShow = Activator.CreateInstance(userControlToShowType) as UserControl; if (userControlToShow == null) throw new Exception(string.Format("Can't create an instance of Page with the type {0}", userControlTypeString)); return userControlToShow; } private static string GetPageFromQueryString() { string pageToShow = null; if (HtmlPage.Document.QueryString.Count > 0 && HtmlPage.Document.QueryString.ContainsKey("page")) pageToShow = HtmlPage.Document.QueryString["page"]; return pageToShow; }
Note: This code will not do any security check etc,
it's only used to give you the basic ideas and the
concept. So type-injection and what kind of pages a user
are allowed to see etc is not taken care of in this
example, I wanted it to only show the basic concept and
not make the code too complex.
To do something similar as the above code we can
instead use the Frame control on our MainPage. The Frame
control can show a specific control based on a URL like this
“defaul.aspx#/Page2.xaml” (This URL will show the Page2.xaml
content inside of the Frame control). To use the Frame
Control you only need to add the Frame control to the XAML:
<UserControl xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" ....> <Grid x:Name="LayoutRoot"> <navigation:Frame></navigation:Frame> </Grid> </UserControl>
I hope this blog post have given you some ideas about how you you can navigate to your Silverlight application and specify which Page (UserControl) you want to show when the application is started.
If you want to know when I publish a new blog post, you can follow me on twitter: http://www.twitter.com/fredrikn