5 Mar
2010

Creating a Custom Silverlight Pre-Loader

Category:UncategorizedTag: , , :

I have been doing Silverlight development since it was released. One question I get asked a lot is how do to create a custom pre-loader for my application. What do I mean by pre-loader? Well, it can be called many things; it could be called a pre-loader, splash screen, or a loading screen. No matter what you want to call it, here is the one you get by default.

default Silverlight pre-loader

I thought creating a custom pre-loader was common knowledge, but I guess I was wrong. So, what is a custom pre-loader really? Well, it is a small and lightweight Silverlight application that runs while your main Silverlight application is being downloaded to the client. Creating your own is really easy and only involves a few basic steps.

The first thing we need to do is add a Silverlight JavaScript  page to the Web project of your Silverlight application. So just right click your Web project and click add new item, then select Silverlight JScript Page.

add new silverlight jscript page

You can name it whatever you want. I named my SplashScreen.xaml. When you click ?Add? you will notice two files were created for you; a XAML file and a JavaScript file.

image

The XAML file is where you will create your pre-loader UI. So lets create a simple UI.

<Canvas
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="parentCanvas"
Width="850"
Height="600"
Background="OldLace"
>
<Canvas Canvas.Top="228.834" Canvas.Left="246.329" Width="357" Height="31.379">
<Rectangle Width="27.545" Height="1" x:Name="uxProgress" Canvas.Top="29.545" Canvas.Left="1.4">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="uxProgressBar" ScaleX="1" ScaleY="0"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="270"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Rectangle.RenderTransform>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="#FFFFFFFF" Offset="1"/>
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#FF2975D0" Offset="0.28"/>
<GradientStop Color="#FF2975D0" Offset="0.72"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>

<TextBlock x:Name="uxStatus" Height="25" Canvas.Left="125" Text="Loading..." TextWrapping="Wrap" Canvas.Top="4.16"/>

<Path Width="356.85" Height="1" Fill="#FF3A3A3A" Stretch="Fill" Stroke="#FF000000" Canvas.Top="0" Data="M0,170.5 L356.84209,170.5" Opacity="0.35"/>
<Path Width="1.662" Height="29.03" Fill="#FF3A3A3A" Stretch="Fill" Stroke="#FF000000" Canvas.Top="0.48" Canvas.Left="0.2" Data="M360,168 L360,0" Opacity="0.35" />

<Path Width="357.84" Height="1" Fill="#FF3A3A3A" Stretch="Fill" Stroke="#FF000000" Canvas.Top="29" Data="M0,170.5 L356.84209,170.5" Opacity="0.35"/>
<Path Width="358.85" Height="1" Fill="#FFA2A2A2" Stretch="Fill" Stroke="#FF000000" Canvas.Top="30" Data="M0,170.5 L356.84209,170.5" Opacity="0.25"/>
<Path Width="1.662" Height="30" Fill="#FF3A3A3A" Stretch="Fill" Stroke="#FF000000" Canvas.Left="356.01" Data="M360,168 L360,0" Opacity="0.35" Canvas.Top="-0.498"/>
<Path Width="1" Height="31" Fill="#FFA2A2A2" Stretch="Fill" Stroke="#FF000000" Canvas.Left="357.333" Data="M360,168 L360,0" Opacity="0.245" Canvas.Top="-0.498" />
</Canvas>
</Canvas>

I actually copied this XAML from MSDN because I was to lazy to write my own.

The JavaScript file is where you will interact with you pre-loader.  To do this there are three properties that are exposed by the Silverlight plug-in:

  1. splashscreensource: The URI of a XAML page that displays while the primary package (source) is being downloaded.
  2. onsourcedownloadprogresschanged: References a JavaScript event handler that will be invoked continuously while the source is being downloaded.
  3. onsourcedownloadcomplete: References a JavaScript event handler that will be invoked once, when the source download is complete.

Enter Params:

You will need to add two Object Params to your page hosting the Silverlight application.

<param name="splashscreensource" value="SplashScreen.xaml"/>
<param name="onSourceDownloadProgressChanged" value="onSourceDownloadProgressChanged" />

The first one tells the host where to find the custom XAML file you created. The second one tells it which JavaScript function to execute when the sourceDownloadProgressChanged event fires.

So go ahead and open up your JavaScript file and delete all the code that is in there and replace it with this:

function onSourceDownloadProgressChanged(sender, eventArgs) {
sender.findName("uxStatus").Text = "Loading: " + Math.round((eventArgs.progress * 1000)) / 10 + "%";
sender.findName("uxProgressBar").ScaleY = eventArgs.progress * 356;
}

The next step is very important. Make sure you add your JavaScript file into the head tag of your hosting page.

<script type="text/javascript" src="splashscreen.js"></script>

Now in order to test this thing, you need to add something very big to your main Silverlight application, set its Build Action to Content, and set Copy to Output Directory to Copy if newer.  I added a video file that was about 100MB in size. Now run your application.

custom pre-loader

And there is our custom pre-loader.

For more information on creating custom pre-loaders visit http://msdn.microsoft.com/en-us/library/cc838130(VS.95).aspx

Download the Source

5 thoughts on “Creating a Custom Silverlight Pre-Loader

  1. Hello,

    I’ve been testing this, and it does not work for me.
    I have a quite big application to load, but it goes instantly to 100%.

    Can you help me?

    Thanks.

  2. @Jya

    Unfortuntely, I don’t know how you implementated your custom preloader. Short of actually writing it for you, all I could suggest it to make sure that you haven’t overlooked anything that may be causing a problem. There is also great documentation on MSDN. Good luck.

  3. Hi Brian, Thanks, this is working, but i have one question regarding how to place this loader to the centre of the screen, cause basicly addition of
    HorizontalAlignment=”Center”
    VerticalAlignment=”Top”
    to Canvas

    didn’t help:(

    Regards,
    Karol

Comments are closed.