Tuesday, February 19, 2008

Load a file Asynchronously with Silverlight 1.1

Say you want to load some or all of the images for your new Silverlight game up front. Instead of Silverlight loading a image file when it is about to use it, we load the files before we begin the game.

To do this, we use the System.Windows.Downloader.

Set up our member variables:

/// <summary>
/// TestBlock to show progress
/// </summary>
TextBlock mProgressText = new TextBlock();

/// <summary>
/// Downloaded to do the download
/// </summary>
Downloader mImageDownloader = new Downloader();


Ready our scene and set up the Downloader:

/// <summary>
/// Using the mImageDownloader, start to load a file from the filesystem (on the server)
/// </summary>
/// <param name="fileName">file to load</param>
void LoadImagesAsynchronously(string fileName)
{
//set up progress label
mProgressText.Text = "Loading Images [--------------------------------------------------]";
mProgressText.SetValue(Canvas.ZIndexProperty, 100);//move above whatever else is on the canvas
this.Children.Add(mProgressText);

//set up completed event
mImageDownloader.Completed += new EventHandler(ImageDownloader_Completed);

//set up progress changed event
mImageDownloader.DownloadProgressChanged += new EventHandler(ImageDownloader_DownloadProgressChanged);

//set which file to load
mImageDownloader.Open("GET", new Uri(fileName, UriKind.Relative));

//start the download
mImageDownloader.Send();
}


Set up our progress changed event:
As the downloaded downloads the file, it reports back on its progress, and we report that back to the user via mProgressText.

/// <summary>
/// show progress of loading images
/// </summary>
/// <param name="sender">mImageDownloader</param>
/// <param name="e">eventArgs from downloader</param>
void ImageDownloader_DownloadProgressChanged(object sender, EventArgs e)
{
//every time the downloader updates its progress, update the textplock to show progress
//like: "Loading Images [IIIIIIIIIIII--------------------------------------]";
int tickCount = 50;
string newText = "Loading Images [";
for (int i = 0; i < tickCount; i += 3)
{
if (i < mImageDownloader.DownloadProgress * tickCount)
{
newText += "IIIIII";
}
else
{
newText += "---";
}
}
newText += "]";
mProgressText.Text = newText;
}


Set up our complete event:

/// <summary>
/// fires after images load
/// </summary>
/// <param name="sender">mImageDownloader</param>
/// <param name="e">eventArgs from downloader</param>
void ImageDownloader_Completed(object sender, EventArgs e)
{
//update the progress indicator one last time
//you would probably remove the indicator at this point
//and continue on with your application code
mProgressText.Text = "Load Complete!";
}


The Downloader can download a single file. You can download one file or zip which can contain many files.

To access the files:

/// <summary>
/// assigns an image from the downloader to a geometry path
/// </summary>
/// <param name="imageName">image name in downloader</param>
/// <param name="geometryPath">the path to assign the image to</param>
public void SetGeometryImage(string imageName, Path geometryPath)
{
ImageBrush ibrush = new ImageBrush();
//access the image in the downloader by file name i.e. "Image.jpg"
ibrush.SetSource(mImageDownloader, imageName);
this.GeometryPath.Fill = ibrush;
}

No comments: