Undoubtedly Silverlight offers a myriad of useful features that can enhance the user and development experience – Binding, Multithreading, Layout System, Animations to name a few. But the fact that it is in essence a browser plug-in leads to certain limitations or “hurdles” for the user experience.
One such thing is the lack of Deep Linking, i.e. the browser’s address bar contains the starting page for the application but any change in its state is not reflected in the address. Some people argue that there is difference between Web Applications and Web Pages and while the latter need linking and navigation, the Web Applications can do without them.
This might has been a reasonable argument a while back but today the back-forward buttons and address bar are making their way into applications as well so fixing them in the browser is s must. Generally there are certain types of content for which paginating is the most natural and logical way to go. For example take a look at:
In the real world you would like to go back after making a selection, copy the address and save it for later reference or send it to someone else. Sending links is even more important in the following video website:
You can refer to the website but not to any particular video.
Silverlight comes with several classes that help us interact with the Html container of the plug-in (and therefore the browser). You might like to have a look at the HtmlPage and HtmlElement classes if you need to manipulate some Html from Silverlight. What we need though is to access the bookmark of the current page.”Bookmark” refers to everything in the address after a ‘#’. Changing the current bookmark does not refresh the page and can be used for the sub address, in other words the address in the Silverlight application.
The easiest way to do this is with the CurrentBookmark property:
This way the address bar will change from
The bookmarks help us maintain the relation between the content and the address but not the other way around. So if you change the bookmark manually then nothing would change. The back button would behave unexpectedly as well.
To put everything into a context, lets have a look at a simple example: We have a music catalog that is in essence a ListBox and a TextBlock. When you click through the list of albums, the TextBlock updates to show the songs in the album.
As of ASP.NET 3.5 you can set the EnableHistory property of the asp:ScriptManager and then use it to manipulate the history on the client side. In code this translates to the following:
We would be using the Sys.Application.addHistoryPoint(entry, title) which takes two arguments: a state object and a window title. Passing a state object is like passing a string dictionary which translates to #key=value pairs in the bookmark. I personally prefer more readable links so I have modified the history manager a little to allow for a simpler addresses of the kind: #something/something-else/. The contents of the Default.js file are now:
A point of interest might be:
In order to avoid recursions we need to agree on the following: The change of content in the Silverlight application would only be a result of a change of address callback, i.e.:
We would also introduce a static navigation manager – the Navigator class shown earlier. The xaml of the application is a simple ListBox with a DataTemplate to give a hint of credibility to the Music Catalog:
When you click on an album the address is changed which in turn raises a callback which changes the contents of the Tracks list.
Signing up for the events and modifying content is simple so we won’t go into details how this is done. If you are curious and would like to run the example yourself, you can get the source here: SilverlightHistoryManager.zip
If you try to create the example yourself you may run into the following problems:
Subscribe to be the first to get our expert-written articles and tutorials for developers!
All fields are required