Something is killing some RIA applications : the time it sometimes takes to see the first page. So, let's see how to keep the master page as small as possible (a few KB for the master page and the initial content page) and progressively load (in the background) other content pages and all high resolution images. We will also show how to pass information between pages.
Project / source code
As in previous posts dedicated to master pages, we create a solution that initially (as usual) contains just one project. This initial project contains the master page (Page.xaml). In this project, we add the initial content page (Page1.xaml). Images are not included as resources in the project to restreint the initial XAP file to a very reasonable size : 11 KB, that dramatically decreases the initial load time. These images (in high resolution) have to be copied in the ClientBin folder and will be loaded from the server, in the background. They will be displayed as soon as they become available on the client machine.
Page2 and Page3 content pages are created as projects in the solution : right-click on the solution (first line in the Solution Explorer window), Add New Project, Silverlight Application. Check the "Link this Silverlight control into an existing web site" checkbox but uncheck the "Add a test page" checkbox. The two projects newly created are named Proj4Page2 and Proj4Page3. Both projects contain Page.xaml and Page.xaml.cs. Feel free to change names. Prepare Page2 and Page3 as usual. After compilation, Proj4Page2.xap and Proj4Page3.xap files are created in the ClientBin folder. These files will have to be copied to the server.
How to pass information between pages ? We create another new project named Proj4Data. In the Page.xaml file, remove the Grid tag, though it is not mandatory (the goal is to keep Proj4Data.xap as small as possible). Let's assume Page2 and Page3 have to pass a list of strings to other pages. In Page.xaml.cs file of the Proj4Data project, we add :
public static List<string> Page2Lst;
public static List<string> Page3Lst;
In all projects but Proj4Data, we add a reference to Proj4Data : right-click on a project, Add Reference, Projects. This increases each XAP file by 4 KB, quite acceptable though it could still be possible to decrease that footprint. In our case, the master page makes the status bar accessible from any page. To do so, we also add (the control - a TextBlock- is named stBar in the master page) :
public static TextBlock statusBar;
Now, let's link things and progressively load high resolution images and pages in the background (while the initial page is already displayed). In Page.xaml.cs of the main project (the one containing the master page and the initial content page), we add :
int nStep = 1;
WebClient client;
public Page()
{
InitializeComponent();
page1 = new Page1();
PageContainer.Children.Add(page1);
client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
client.OpenReadAsync(new Uri("Clouds.jpg", UriKind.Relative));
Proj4Data.Page.statusBar = stBar;
}
Page1 is included in the initial XAP file. There is thus no need to explicitly load it from the server. The different loads are performed in the background. We start with the background image for the master page (the Clouds.jpg is not inserted as resource but just copied in the ClientBin folder). The last line means that Proj4Data.Page.statusBar is another way to reference the stBar control in the master page. The OpenReadCompleted function is the same as seen in the previous post :
using System.Windows.Media.Imaging;
using System.Windows.Resources;
using System.Reflection;
.....
void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
BitmapImage img;
StreamResourceInfo sri, sri4dll;
AssemblyPart asmPart;
Assembly asm;
UserControl uc;
switch (nStep)
{
case 1 : // got background image for masterpage
nStep++;
..... // initiate async read for Page1 background image
break;
case 2 : // get background image for Page1
.....
nStep++;
..... // initiate async read for Page2
break;
case 3 : // got Page3
.....
nStep++;
..... // initiate async read for Page3
break;
case 4: // got Page3
.....
break;
}
}
There is no need to repeat what was explained in the previous post. Moreover, source code is provided, as usual.
See you soon for another improvement, with the dynamic load of controls that have an heavy footprint.