Missing Piece

I’ve been lucky enough to work on a new project for a client involving Silverlight 3 and the Silverlight Virtual Earth CTP. One reoccurring issue that keeps coming up is performance, and I’m always looking for ways to balance functionality with speed. In the app we are loading up a Virtual Earth map and populating it with data (nothing new). We have a fair amount of data being loaded for various functions and layers. Users are able to show and hide layers as well as interact with the map’s basic functions (zoom, pan, etc). Users can then navigate to other areas based on selections from the map page.

Since we’re using SL3, we’re using the Navigation Framework to navigate between “pages.”  If you’re not familiar with the Navigation Framework, check out Martin Mihaylov’s article, or if you prefer videos, be sure to check out Tim Heuer’s video on the topic. Now let’s move on to the problem, and a solution…

The Problem

This is actually a two pronged problem, with thankfully a single solution. One thing we wanted was to have the Virtual Earth map (and the page) “remember” what you were doing. So let’s say you had zoomed in and panned over to Connecticut, you then selected something from the map that redirected you to another Silverlight page. Once you were done, you clicked on the navigation to go back to the map page. There were two problems here. The first was that navigation was slow. The map has a lot of layers that are being bound with various pieces of data. The map would rebind these layers since it was essentially a reload. The second problem was that all the zooming and panning were totally lost, since the page reloaded the default view.

As an aside, if you are interested in binding layers on the Virtual Earth map, look no further than Michael Scherotter’s awesome Binding Properties for the Virtual Earth Silverlight Control project (there is also a demo of these in use).

So of course, these two issues really weren’t something that we wanted to put in front of a customer, so the hunt for a solution was on.

The Solution

Thankfully within the Navigation Framework there is a fairly simple solution that solved both of these problems, however it’s not the most obvious if you aren’t sure what to search for. After a lot of searching, I came across the Page.NavigationCacheMode Property on MSDN. This property has three settings: Disabled (the default), Enabled, or Required. The usage is simple,  just append the property to your Page XAML like so:

<navigation:Page
     x:Class="Samples.SampleApp"
     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="Sample Page"
     NavigationCacheMode="Enabled">
    <!-- Content -->
</navigation:Page>

That’s it.

The difference between Required and Enabled is that with Enabled, the cache could be flushed based on the CacheSize setting.

In our app, we set the property to Required, which means the page will be cached regardless of the CacheSize property.

Hopefully, if you are looking for something along the lines of “reuse a page” or “don’t reload” associated with the Navigation Framework, you’ll come across this post.