HOWTO: Silverlight Preloader with Downloader

UPDATE: See a sample of this Preloader that allows many files to be downloaded.

There are some great videos and links on the downloader object from Microsoft for Silverlight.

In Silverlight you can create an object called a downloader that probably stems from the htc ie5.5 downloader that was part of ajax beginnings, it is ver similar to the XMLHTTP object but it has zip capabilities. This downloader can download individual files or zip file packages that you can grab xaml, xml, images, script etc from them and use them or load them in to xaml files. This helps to keep things compact and allows for preloaders and smoother beginnings of your animations where needed.

The zip downloading is attractive and much of this is going on in Flash AS3 with FZip or ASZip AS3 packages. These are made possible with ByteArray and BinarySockets and other fun tools that give no limits. In Silverlight all you have is javascript or the silverlight downloader object to get other data at runtime.

Downloading assets in Silverlight is different than in Flash. Flash compiles libraries to swf files, it can load pngs, it can preload anything in numerous ways. Silverlight does not compile to one file or into compressed binary currently and this offers flexibility but it also makes file sizes at their default size very big. PNGs for instance can’t be zipped any smaller usually but in Flash9 these are sometimes 1/10th the size of the actual file when compressed better in the SWF file. Even if you zip them in Silverlight they are still around the same size. Silverlight XAML files compress well and these can get very large if lots of pathing is used.

Flash has always been the master at smallest file sizes and even the player itself is extremely small, under a MB. Silverlight 1.0 which is just javascript is 1MB, the Silverlight 1.1 plugin with DLR support is going to be 4MB currently (it still is in alpha so it could come down).

Currently in Silverlight 1.0 this is just a javascript release, the DLR and C# version of Silverlight 1.1 Alpha probably has 6 months or a year. So with no byte array binary handling or sockets of any type except javascript ajax, downloader is your only option now. But it is a good tool for now to help with preloaders and bringing files in smaller to make your rich applications and games faster.
Currently the only createObject call that is supported is the “downloader” object. I would like to see more here like a “socket” object but when Silverlight 1.1 launches with C#/python/ruby support things may change in this regard.

To create a downloader you do this in javascript:

// Event handler for initializing and executing a download request.
function onMouseLeftButtonUp(sender, eventArgs)  //sample mouse button click
{
// Retrieve a reference to the plugin.var slPlugin = sender.getHost();    // Create a Downloader object.
var downloader = slPlugin.createObject("downloader");

// Add DownloadProgressChanged and Completed events.
downloader.addEventListener("downloadProgressChanged", onDownloadProgressChanged);

downloader.addEventListener("completed", onCompleted);

// Initialize the Downloader request.
// NOTE: downloader APIs disallow file: scheme
// you must run this sample over localhost: or off a server or the following call will fail
downloader.open("GET", "promo.zip");

// Execute the Downloader request.
downloader.send();
}

// Event handler for updating visual progress indicator
function onDownloadProgressChanged(sender, eventArgs)
{
// Calculate the downloaded percentage.
var percentage = Math.floor(sender.downloadProgress * 100);
// Update the Rectangle and TextBlock objects of the visual progress indicator.
progressText.text = percentage + "%";
progressRectangle.width = percentage * 2;
}

function onDownloadCompleted(sender, eventArgs)
{
// Retrieve the XAML content from the downloaded package file.
var jacketBrowserXaml = sender.getResponseText("jacketBrowser.xaml");

// Create the objects from the XAML content.
var jacketBrowser = plugin.content.createFromXaml(jacketBrowserXaml);

// Add downloaded XAML content to the plugin.
sender.findName("rootCanvas").children.insert(0, jacketBrowser);

// Retrieve a reference to the Image object representing the jacket.
var jacketImageSlice = sender.findName("jacketSlice");

// Set the Source property of the Image object to the specific jacket image
// within the downloaded Zip package file.

jacketImageSlice.setSource(sender, "rotation01_green.png");
}

This video is the quickest way to understand the whole downloader setup.But this is also a very simple example. The hard part is deciding where to put your preloaders and how to load things in. If you are putting your XAML in a zip file you will need to have a preloader in a container XAML file as the main control and then a Canvas object to load that XAML into. This complicates many things and is really a design approach from the beginning.

In coming posts I will be posting a multifile preloader, a single file preloader, a zip preloader and some sample setups for silverlight projects and Flash projects based on zip and direct preloading.

I will put this sample script to work below for preloading files in Silverlight 1.0:

///////////////////////////////////////////////////////////////////////////////
//
// PreloaderMultifileClassLibrary.js
// The MIT License
// 
// Copyright (c) 2007 Ryan Christensen, drawk llc
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////

// setup the namespace objects to be good javascript form
// Ag1 = Silverlight 1.0 library
if(!window.B)
window.B={};
if(!window.B.Ag1)
window.B.Ag1={};

if (!window.Sys)
window.Sys = {};

if (!window.Silverlight)
window.Silverlight = {};

Silverlight.createDelegate = function(instance, method) {
return function() {
return method.apply(instance, arguments);
}
}

B.Ag1.PreloaderMultifileAssets = function()
{
// TODO alow JSON or Array passed
// loads up the asset arry to cycle through
this.resourceArray = new Array();
}

B.Ag1.PreloaderMultifileAssets.prototype =
{
loadAssetsArray : function()
{
this.resourceArray[0] = "spinner.png";
// add your images/zips/files to load here
for (var i=1; i<=16; i++)
{
this.resourceArray[i] = "drive_in_files/image" + i + ".png";
}
this.resourceArray[i++] = "drive_in_files/bg.png";
this.resourceArray[i++] = "drive_in_files/c1.png";
this.resourceArray[i++] = "drive_in_files/c2.png";
this.resourceArray[i++] = "drive_in_files/c3.png";
this.resourceArray[i++] = "drive_in_files/c4.png";
}
}

// total pages available
B.Ag1.PreloaderMultifile = function(control)
{
this.plugIn = control;      // Store the host plug-in
this.currentDownload = 0;   // Current resource to be downloaded
// this.maxNumPages = maxNumPages;
this.preloaderMultifileAssets = new B.Ag1.PreloaderMultifileAssets();
this.preloaderMultifileAssets.loadAssetsArray();
// alert(this.preloaderMultifileAssets.resourceArray);
this.downloadAssets();
}

B.Ag1.PreloaderMultifile.prototype =
{
downloadAssets : function()
{
//alert(this.preloaderMultifileAssets.resourceArray);
var _file = this.preloaderMultifileAssets.resourceArray[this.currentDownload];
if(_file != null && _file != undefined)
{
this.downloader = this.plugIn.createObject("downloader");
this.downloader.addEventListener("downloadProgressChanged", Silverlight.createDelegate(this, this.downloadProgressChanged));
this.downloader.addEventListener("completed", Silverlight.createDelegate(this, this.downloadCompleted));
this.downloader.open("GET", this.preloaderMultifileAssets.resourceArray[this.currentDownload]);
this.downloader.send();
}
},
downloadProgressChanged : function(sender, args)
{
try
{
var progressRect = this.plugIn.content.findName("progressRect");
progressRect.width = (sender.downloadProgress) * 450;
}
catch(e)
{
}
},
downloadCompleted : function(sender, args)
{
this.currentDownload++;
var progressText = this.plugIn.content.findName("progressText");
var progressPercent= this.plugIn.content.findName("progressPercent");
if (this.currentDownload < this.preloaderMultifileAssets.resourceArray.length)
{

progressText.text = "Downloading: " + this.preloaderMultifileAssets.resourceArray[this.currentDownload];
progressPercent.text = parseInt((this.currentDownload/this.preloaderMultifileAssets.resourceArray.length)*100) + "%";
this.downloader.open("GET", this.preloaderMultifileAssets.resourceArray[this.currentDownload]);
this.downloader.send();
}
else
{
// Hide progress UI
var downloadUI = this.plugIn.content.findName("downloadUI");
this.plugIn.content.findName("fadeDownloadUI").begin();
downloadUI.isHitTestVisible = false;

progressPercent.text = "100%";
progressText.text = "Downloading Complete";

// initialize canvas and anmiations
this.plugIn.content.findName("innerCanvas").Visibility = 'Visible';
this.plugIn.content.findName("IntroAnimation").begin();
}
}
}

If you change your Silverlight handleLoad to something like this you can use the class above for list of files before it plays the xaml animations and presentation.

handleLoad: function(plugin, userContext,  sender) { // be sure to add these parameters, by default they are not added
// alert(plugin.id + " : " + userContext + " : " + sender.toString());
plugin.content.findName("innerCanvas").Visibility ='Collapsed';
plugin.content.findName("innerCanvas").Opacity = 0;
var preloader = new B.Ag1.PreloaderMultifile(sender.getHost()); // pass in the silverlight control

I will have a complete tutorial of this soon.

Advertisements

7 Responses to “HOWTO: Silverlight Preloader with Downloader”

  1. Degrafa for Flex Looking Pretty Sweet (AS3 and Commonizing Paths Graphics Pipeline for Silverlight and Flex) « [ draw.logic ] Says:

    […] Illustrator into XAML. The one benefit of Flex/Flash is it compiles to a very small SWF where with Silverlight you have to package the XAML in a zip and use the downloader object to extract it out.  These XAML files and Paths can get massive as I am sure the ones for Degrafa will for Flex but […]

  2. [ bridgeware ] internal com station » Blog Archive » Degrafa Flex Silverlight-like Paths for Vector Graphics Pipeline (to Flash AS3 or Silverlight) Says:

    […] Illustrator into XAML. The one benefit of Flex/Flash is it compiles to a very small SWF where with Silverlight you have to package the XAML in a zip and use the downloader object to extract it out. These XAML files and Paths can get massive as I am sure the ones for Degrafa will for Flex but the […]

  3. Ed Wood Says:

    But for Silverlight 2? And without JavaScript?

  4. drawk Says:

    Yeh this is just for Silverlight 1, I need to update for Silverlight 2.

  5. Mocha Fudge Says:

    I’m having a bit problem in Silverlight version 1 and i hope it will get fix on the newer version..

  6. Neo Says:

    maxum magazine
    [URL=http://xyvodutajofaqu.my3gb.com/maxum-magazine/]maxum magazine[/URL]
    jillian barbarie
    [URL=http://vezokefivoladu.my3gb.com/jillian-barbarie/]jillian barbarie[/URL]
    lil wayne and solange
    [URL=http://puxibicecynive.my3gb.com/lil-wayne-and-solange/]lil wayne and solange[/URL]
    halaka scandal ph
    [URL=http://puxibicecynive.my3gb.com/halaka-scandal-ph/]halaka scandal ph[/URL]
    pbs kids games
    [URL=http://xyvodutajofaqu.my3gb.com/pbs-kids-games/]pbs kids games[/URL]
    veronica portillo
    [URL=http://xyvodutajofaqu.my3gb.com/veronica-portillo/]veronica portillo[/URL]
    denver broncos schedule
    [URL=http://xorurycetewuto.my3gb.com/denver-broncos-schedule/]denver broncos schedule[/URL]
    paul shanklin
    [URL=http://puxibicecynive.my3gb.com/paul-shanklin/]paul shanklin[/URL]
    rob marciano
    [URL=http://puxibicecynive.my3gb.com/rob-marciano/]rob marciano[/URL]
    polk county assessor
    [URL=http://xyvodutajofaqu.my3gb.com/polk-county-assessor/]polk county assessor[/URL]
    chihuahua for sale
    [URL=http://vezokefivoladu.my3gb.com/chihuahua-for-sale/]chihuahua for sale[/URL]
    rahsia tarikh lahir
    [URL=http://xorurycetewuto.my3gb.com/rahsia-tarikh-lahir/]rahsia tarikh lahir[/URL]
    carmike theater
    [URL=http://xorurycetewuto.my3gb.com/carmike-theater/]carmike theater[/URL]
    mugen character nintendo
    [URL=http://dihunanupugane.my3gb.com/mugen-character-nintendo/]mugen character nintendo[/URL]
    pilipinas sabong sports
    [URL=http://xyvodutajofaqu.my3gb.com/pilipinas-sabong-sports/]pilipinas sabong sports[/URL]
    papa murphys
    [URL=http://puxibicecynive.my3gb.com/papa-murphys/]papa murphys[/URL]
    niurka fotos especiales playboy
    [URL=http://xorurycetewuto.my3gb.com/niurka-fotos-especiales-playboy/]niurka fotos especiales playboy[/URL]
    democratic donkey
    [URL=http://dihunanupugane.my3gb.com/democratic-donkey/]democratic donkey[/URL]
    fireworks for sale
    [URL=http://xyvodutajofaqu.my3gb.com/fireworks-for-sale/]fireworks for sale[/URL]
    wickipedia
    [URL=http://xorurycetewuto.my3gb.com/wickipedia/]wickipedia[/URL]


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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: