Random geekery since 2005.

Husband, father, programmer, speaker, writer, blogger, podcaster, collector, traveler, golfer.

This is the third post in my series of thirty-one, called, not surprisingly, “31 Days of Silverlight”. You can find the master list here.

Also, before we get started here, don’t forget that today is Contribupendence Day. Take a moment to read this post about what Contribupedence Day is, and how you can participate.

If you’ve ever seen a Silverlight application before, you’ve likely seen the default loading screen. Here’s a example of what I’m talking about:

Now, there’s nothing wrong with it, except that it’s the thing you see EVERYWHERE. There’s a way to customize this screen, and you should. It’s an opportunity to re-inforce your branding, entertain your user, and differentiate yourself from everyone else. Let’s get started.

Building Our Loading Screen

The first thing to know about this loading screen is that it functions completely outside of our .xap file. If you think about it though, it makes sense. We’re trying to monitor the loading percentage of our XAP file, so we could hardly expect our loading code to be inside it, right?

So, instead of creating a new XAML file inside of our Silverlight project, we’re going to create a XAML file inside our Web Project this time. When you choose “Add > New Item…”, you’re going to choose the “Silverlight JScript File.” This will create a XAML file in our web project, but otherwise, it’s your standard XAML. I’ve created one that has a TextBlock to display the percentage as a number, as well as a rectangle underneath. This rectangle will be my percentage progress bar. Here’s the code (I named it LoadingScreen.xaml):

<Canvas xmlns="http://schemas.microsoft.com/client/2007" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300">
<
Canvas x:Name="LayoutRoot" Background="#FFB5EFFF">
<
Rectangle Height="4" Width="0" Fill="#FFE8B03A" Stroke="#FF999999" StrokeThickness="1" x:Name="ProgressBar" Canvas.Left="14" Canvas.Top="156"/>
<
TextBlock Width="100" FontFamily="ROCK.TTF#Rockwell" FontSize="48" Text="Blankenthoughts" Foreground="#FF6D6D6D" x:Name="Title" Canvas.Top="56" Canvas.Left="150" />
</
Canvas>
</
Canvas>

Getting Our Loading Screen Loaded

So we’ve got a loading screen now, but we also need to make sure that our Silverlight <object> tag knows that we’ve got a custom loading screen. We do this with a param tag in the HTML. The splashscreensource tag specifies a XAML file that should be used instead of the default. Here’s how my entire HTML file looks now:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html xmlns="http://www.w3.org/1999/xhtml" >
<
head>
<
title>SilverlightLoadingScreen</title>
</
head>

<
body>
<
div id="silverlightControlHost">
<
object id="xamlobject" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<
param name="splashscreensource" value="LoadingScreen.xaml"/>
<
param name="source" value="ClientBin/SilverlightLoadingScreen.xap"/>
<
param name="background" value="white" />
</
object>
</
div>
</
body>
</
html>

What you may notice, if you’re building along with me, is that the loading screen loads, but it doesn’t change as the load progresses. This is because we need to pay attention to the “onSourceDownloadProgressChanged” event. Thankfully, we do with with another param tag in our <object> tag. The value that we provide is actually the name of the Javascript function we will write. That tag looks like this:

<param name="onSourceDownloadProgressChanged" value="onSourceDownloadProgressChanged" />

You didn’t tell me there’d be Javascript

Ah, never doubt for a second that the Internet runs on Javascript. Of course it does! This function is simple, and is the glue that puts our XAML together with actual data. I’ll give you my function first, and then we can discuss the different parts of it.

function onSourceDownloadProgressChanged(sender, eventArgs)
{
var slObject = document.getElementById("xamlobject");
var progressBar = slObject.content.findName("ProgressBar");
var progressTitle = slObject.content.findName("Title");
if (eventArgs.progress)
{
progressBar.Width = eventArgs.progress * 370;
progressTitle.Text = parseInt(eventArgs.progress * 100) + "%";
}
else
{
progressBar.Width = eventArgs.get_progress() * 370;
progressTitle.Text = parseInt(eventArgs.get_progress() * 100) + "%";
}
}
  • slObject – this is a reference to my Silverlight <object> tag on the page. I need to get this in order to find the child elements, specifically my Rectangle and TextBlock elements.
  • progressBar – this is a reference to my ProgressBar Rectangle element within my XAML document. Don’t you wish getting through XML was always that easy? It just searches through the document tree until it finds an element with the name I specified.
  • progressTitle – a TextBlock in the XAML that will hold the actual percentage of completion.
  • eventArgs.progress – this is the physical number that represents our completion percentage. We use this to modify the width of our rectangle, so that it grows as the percentage increases. I am also displaying this number in the TextBlock, appending a “%” to the end.
  • eventArgs.get_progress()
  • – basically, we need to call the get_progress method in case our page is not already paying attention to it. Once this has been called, however, it will default to the previous part of the if statement, using just the progress property of the eventArgs.

Can I See A Working Example?

Absolutely. Below is a working example of this custom loading screen in action. If you don’t see it, you’re probably reading this post from an RSS reader. Click here to see the Silverlight Loading Screen as a working example. You can also click here to download my entire set of working code.

function onSourceDownloadProgressChanged(sender, eventArgs)
{
var slObject = document.getElementById(“xamlobject”);
var progressBar = slObject.content.findName(“ProgressBar”);
var progressTitle = slObject.content.findName(“Title”);
if (eventArgs.progress)
{
progressBar.Width = eventArgs.progress * 370;
progressTitle.Text = parseInt(eventArgs.progress * 100) + “%”;
}
else
{
progressBar.Width = eventArgs.get_progress() * 370;
progressTitle.Text = parseInt(eventArgs.get_progress() * 100) + “%”;
}
}

Tags

5 responses to “Day #3: Custom Silverlight Loading Screen”

  1. Erich Avatar
    Erich

    After I added new items in VS, I can't open .xaml(in web project) in Blend 3. Anyone has the same issue?

  2. Todd V. Avatar
    Todd V.

    **FOLLOW UP – Sorry, I was just trying to do this tutorial without a web project… I just wrote the xaml file and saved it to the bin and created my own html file to call the javascript and files the way you did… but my loading screen was blank (sort of)

  3. PHenry Avatar
    PHenry

    Thank you for the blog entry, you inspired me to try it out and write a blog too! Thanks.http://www.pchenry.com/Home/tabid/36/EntryID/201/Default.aspx

  4. Nan Avatar
    Nan

    Where I puts Java code,thanks for advance.(I beginner.^^) I try to code in .js file but it not work,it show only TextBlock.

  5. vCracker Avatar
    vCracker

    Hey Johnny, you can use following line with asp tag:SplashScreenSource="~/LoadingScreen.xaml" OnPluginSourceDownloadProgressChanged="onSourceDownloadProgressChanged"

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create a website or blog at WordPress.com

%d bloggers like this: