IE8 Forward/Back in a Silverlight 2 (Beta 2) Application
Yesterday I posted here, an application, with source code about how to do forward/back navigation with IE8 and a Silverlight 1.0 application and said that I would be coming up with a Silverlight 2 (Beta 2) application that does the same type of thing - with source code.
It was easier than I thought! I created an application that uses the Silverlight 2 Tab Control and used the document.location.hash to specify the starting page. In this case, the hash in the URL relates to the Tag property of each TabItem in the interface. I decided to use the Tag property instead of the x:Name or Header because it had no other meaning or usage.
Here's what I did:
I added the <meta/> tag to the head section of the HTML page, like before:
<meta http-equiv="X-UA-Compatible" content="IE=8"/>
In my C# code behind for the Silverlight Page I added a loaded handler for the page to both attach to the onhashchange event and to navigate to state specified in the hash:
private void PageLoaded(object sender, RoutedEventArgs e) { HtmlPage.Window.AttachEvent("onhashchange", new EventHandler<HtmlEventArgs>(OnHashChange)); NavigateToTab(); }
The OnHashChange hander would be called by IE8 either if the user navigates using the browser navigation interface or if the document.location.hash were to change programmatically. In this case, it calls the NavigateToTab() function as well:
void OnHashChange(object sender, HtmlEventArgs args) { NavigateToTab(); }
And then the NavigateToTab() function will navigate to the tab specified in the hash (if it's not there already):
private void NavigateToTab() { var hash = HtmlPage.Window.Eval("document.location.hash") as string; if (string.IsNullOrEmpty(hash)) { return; } hash = hash.Substring(1); if (Tabs.SelectedItem != null) { var selectedItem = Tabs.SelectedItem as TabItem; if (string.Compare(selectedItem.Tag.ToString(), hash, StringComparison.OrdinalIgnoreCase) == 0) { // Tab is already navigated to return; } } var selectedItem1 = from item in Tabs.Items.Cast<TabItem>() where string.Compare(item.Tag.ToString(), hash, StringComparison.OrdinalIgnoreCase) == 0 select item; Tabs.SelectedItem = selectedItem1.First(); }
And lastly, when the user changes the Tab, set the document.location.hash and the document.title accordingly:
private void TabChanged(object sender, SelectionChangedEventArgs e) { if (Tabs == null) { //Tabs will be null during InitializeComponent() return; } TabItem item = Tabs.SelectedItem as TabItem; if (item == null) { return; } string evalText = string.Format(System.Globalization.CultureInfo.InvariantCulture, "document.location.hash=\"{0}\"", item.Tag); HtmlPage.Window.Eval(evalText); evalText = string.Format(System.Globalization.CultureInfo.InvariantCulture, "document.title=\"Silverlight Paging: {0} Tab\"", item.Tag); HtmlPage.Window.Eval(evalText); }
I have uploaded the source code for this sample here you can try it out. Now here is what I'd love to see from the Silverlight community: if you run this application in FireFox, you'll notice that the browser navigation doesn't work (although the deep links do). I'd love to see a technique for doing this in FireFox and Safari so that I can update the code so that it's cross-platform.
Comments
Anonymous
July 11, 2008
PingBack from http://blogs.msdn.com/synergist/archive/2008/07/10/how-ie8-will-enables-silverlight-deep-linking-and-browser-back-forward-navigation.aspxAnonymous
July 14, 2008
Hi, I’m Sharath Udupa, developer on the IE team focusing on AJAX features for IE8. One of the AJAX improvementsAnonymous
July 14, 2008
Fons Sonnemans with RollMenu, Frank LaVigne with Community Megaphone SL Map, Martin Mihaylov on LINQAnonymous
October 14, 2008
Navigation is a fairly big subject, but there is not much built-in support for it in Silverlight 2 as