Silverlight SDK

[This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.]

Using a Downloader Object

Silverlight provides a Downloader object, which represents a set of download functionality for a Silverlight control.

This topic contains the following section:

Role of the Downloader Object

The Downloader object is a special-purpose Silverlight object that provides the ability to download application data, such as XAML content, JavaScript content, or media assets, such as images. By using the Downloader object you do not have to provide all application content when the Silverlight control is instantiated. Rather, you can download content on demand in response to application needs. More importantly, you can render downloaded content without the need to refresh the entire Web page. The Downloader object provides functionality for initiating the data transfer, monitoring the progress of the data transfer, and retrieving the downloaded content.

The properties and methods of the Downloader object are modeled after the XMLHttpRequest (XHR) set of APIs. XMLHttpRequest provides JavaScript and other web browser scripting languages the ability to transfer and manipulate XML data to and from a web server using HTTP.

Download Packages

Silverlight provides the ability to download content as a package, which is a collection of independent files containing XAML content, media assets, and other application data. The Zip file format is supported as a download package. The following diagram illustrates a collection of application content contained within a Zip download package:

Download package contains a collection of application files
Once the package is successfully downloaded, you can use methods, such as GetResponseText, SetSource, and CreateFromXamlDownloader, to selectively retrieve a specific named part of the package. In this case, a part reference is the filename reference of the individual content within the package, such as "rotation01_green.png".

Retrieving a part from a download package

Creating and Initializing a Downloader Object

To create a Downloader object, use the CreateObject method of the Silverlight control. Do not invoke the CreateObject method until the Silverlight control has been instantiated. The following Javascript example shows how to invoke the CreateObject method to create a Downloader object:

JavaScript
// Event handler for initializing and executing a download request.
function onMouseLeftButtonUp(sender, eventArgs)
{
    // Retrieve a reference to the control.
    var control = sender.getHost();

    // Create a Downloader object.
    var downloader = control.createObject("downloader");
}

The next step involves setting event handler functions to the Downloader events, DownloadProgressChanged and Completed. The DownloadProgressChanged event, which is optional, allows you to monitor the progress of the download. One way of responding to this event is to provide visual feedback, such as a progress bar indicator.

The Completed event allows you to determine the state of the download request. The following Javascript example shows how to add DownloadProgressChanged and Completed events to a Downloader object:

JavaScript
// Event handler for initializing and executing a download request.
function onMouseLeftButtonUp(sender, eventArgs)
{
    // Retrieve a reference to the control.
    var control = sender.getHost();

    // Create a Downloader object.
    var downloader = control.createObject("downloader");

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

The next step involves initializing the download request by using the Open method, and executing the download request by using the Send method. The Open method initializes the Downloader object by specifying the action to perform, the content to perform the action on, and whether to perform the action asynchronously.

The Send method executes the download request asynchronously or synchronously, depending on the async parameter of the corresponding Open method invocation. The following Javascript example shows the completed sequence of how to create, initialize, and execute a download request:

JavaScript
// Event handler for initializing and executing a download request.
function onMouseLeftButtonUp(sender, eventArgs)
{
    // Retrieve a reference to the control.
    var control = sender.getHost();

    // Create a Downloader object.
    var downloader = control.createObject("downloader");

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

    // Initialize the Downloader request.
    downloader.open("GET", "promo.png", true);

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

Defining Downloader Event Handlers

The Downloader object provides the following set of events:

Event Description
Completed Occurs when the state of the download request has changed.
DownloadProgressChanged Occurs while content is being downloaded during a download request.
 

Defining a DownloadProgressChanged Event

The DownloadProgressChanged event is often used with a visual progress indicator, which displays the percentage of content that has been downloaded. A visual progress indicator can be a simple set of XAML content, such as Rectangle and TextBlock objects:

XAML
<!-- Visual progress indicator -->
<Canvas Canvas.Top="70">
  <Rectangle
    x:Name="progressRectangle"
    Canvas.Left="20"
    Height="10" Width="0"
    Fill="Maroon" />
  <Rectangle
    Canvas.Top ="-1"
    Canvas.Left="19" Height="12"
    Width="202"
    StrokeThickness="1" Stroke="Black" />
  <TextBlock
    x:Name="progressText"
    Canvas.Top ="-4" Canvas.Left="230"
    Text="0%" FontSize="12" />
</Canvas>

The following Javascript example shows how to define a DownloadProgressChanged event handler function that updates the visual progress indicator shown in the preceding XAML:

JavaScript
// 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; 
}

The following image shows the visual progress indicator at the starting, middle, and ending position of the download:


                Visual progress indicator

A visual progress indicator can be constructed from a wide variety of XAML content, including animated objects.

Defining a Completed Event

The Completed event occurs when the state of the download request has changed. The Status and StatusText properties reflect the HTTP status code values for the completed download request. The following JavaScript example shows how to define a Completed event handler function that accesses the downloaded content:

JavaScript
// Event handler for the Completed event.
function onCompleted(sender, eventArgs)
{
    // Retrieve downloaded XAML content.
    var xamlFragment = sender.getResponseText("");

    // Create the objects from the XAML content.
    var control = sender.getHost();
    var button = control.content.createFromXaml(xamlFragment);

    // Add downloaded XAML content to the root Canvas control.
    var rootCanvas = sender.findName("rootCanvas");
    rootCanvas.children.add(button);
}

Retrieving Downloaded Content

When a Downloader object request is successful, the return value from the GetResponseText method represents the downloaded content as a string value. The GetResponseText method return value can represent XAML content, JavaScript content, or a media asset, such as an image.

Note  If you are downloading media assets for use by the Source property of Image and MediaElement objects, you should use the SetSource method, as this is a more efficient way to transfer large-sized  media assets.

Using the URI Property to Identify Downloaded Content

When you invoke the Send method of the Downloader object, you specify a uri parameter that represents the data to be downloaded. The URI property corresponds to the value of the uri parameter of the Send method. The URI property allows you to differentiate downloaded content when you use the share DownloadProgressChanged or Completed event handler functions for multiple Downloader object requests.

The following JavaScript example shows how to use the URI property in a Completed event handler function to determine what actions to take for the returned value of the GetResponseText method invocations. Since the downloaded content does not represent packaged content, the part parameter for GetResponseText must be set to an empty string. Notice that the Status property value is used to determine whether the content was successfully downloaded:

JavaScript
// Event handler for the Completed event.
function onCompleted(sender, eventArgs)
{
    // If HTTP status code indicates "OK", determine action based on URI property.
    if ((sender.status == 200) && (sender.uri == "OK_button.js"))
    {
        // Evaluate JavaScript code -- causes code to be memory-resident.
        eval(sender.getResponseText(""));
    }

    if ((sender.status == 200) && (sender.uri == "OK_button.xaml"))
    {
        // Retrieve downloaded XAML content.
        var xamlFragment = sender.getResponseText("");

        // Create the objects from the XAML content.
        var control = sender.getHost();
        var button = control.content.createFromXaml(xamlFragment);

        // Add downloaded XAML content to the control.
        var rootCanvas = sender.findName("rootCanvas");
        rootCanvas.children.add(button);
    }
}

Using the CreateFromXamlDownloader Method to Create XAML Content

The CreateFromXamlDownloader method allows you to create XAML content dynamically by using the downloaded content in the Downloader object. If successful, the CreateFromXamlDownloader method returns an object reference, which you can then add to the existing Silverlight object hierarchy. You can create a single Silverlight object, such as a TextBlock, or an entire tree of Silverlight objects.

Note  The CreateFromXamlDownloader method is an efficient mechanism for creating XAML objects, since it avoids having to copy downloaded content from the GetResponseText method return value to a temporary buffer and then back again for use by the XAML parser.

The following JavaScript example shows to add XAML content to an existing Canvas object using the CreateFromXamlDownloader method. Since the downloaded content does not represent packaged content, the part parameter for CreateFromXamlDownloader must be set to an empty string:

JavaScript
// Event handler for the Completed event.
function onCompleted(sender, eventArgs)
{
    // Retrieve a reference to the control.
    var control = sender.getHost();

    // Retrieve the XAML fragment and create an object reference.
    // In this case, since the downloaded content represents a single file, OK_button.xaml,
    // the part parameter is set to an empty string.
    var xamlFragment = control.content.createFromXamlDownloader(sender, "");

    // Add the XAML object as a child of the root Canvas object.
    var root = sender.findName("rootCanvas");
    root.children.add(xamlFragment);
}

XAML content created by using the CreateFromXamlDownloader method is not rendered until it is added to an object using the Add method. The following diagram illustrates the relationship between the Silverlight object hierarachy and the downloaded XAML content before and after the content is added to the object hierarchy:


You can also use the CreateFromXamlDownloader method to retrieve a specific part within the downloaded content package. When the downloaded content package is a Zip file, the CreateFromXamlDownloader method allows you to retrieve the contents of a filename within the Zip file. The following JavaScript example shows how to use the CreateFromXamlDownloader method, using the part parameter to reference a specified part within the downloaded content:

JavaScript
function onDownloadCompleted(sender, eventArgs)
{
    // Determine whether the download was successful.
    if (currentDownloadProgress != 1)
    {
    	alert("Failed to succesfully download zip file");
        return;
    }

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

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

    // Add downloaded XAML content to the control.
    sender.findName("root").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");
}

Using the SetSource Method to Set Media Content

The SetSource method can be used as a way of setting downloaded media content to the Source property of the Image and MediaElement objects, or the ImageSource property of the ImageBrush object. The first parameter of the SetSource method identifies the Downloader object representing the downloaded content. The second parameter identifies the specific part to retrieve within the downloaded content. If the downloaded content does not represent packaged content, such as a Zip file, the second parameter must be set to an empty string. The following JavaScript example shows how to use the SetSource method to set the Source property of an Image object to the downloaded content:

JavaScript
// Event handler for the Completed event.
function onCompleted(sender, eventArgs)
{
    // Retrieve the Image object.
    var myImage = sender.findName("myImage");

    // Set the Source property to the contents of the downloaded object,
    // In this case, since the downloaded content represents a single image file, promo.png,
    // the part parameter is set to an empty string.
    myImage.setSource(sender, "");
}

You can also use the SetSource method to retrieve a specific part within the downloaded content package. When the downloaded content package is a Zip file, the SetSource method allows you to retrieve the contents of a filename within the Zip file. The following JavaScript example shows how to use the SetSource method to set the Source property of an Image object to a specified part within the downloaded content:

JavaScript
function onDownloadCompleted(sender, eventArgs)
{
    // Determine whether the download was successful.
    if (currentDownloadProgress != 1)
    {
    	alert("Failed to succesfully download zip file");
        return;
    }

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

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

    // Add downloaded XAML content to the control.
    sender.findName("root").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");
}

Using SetFontSource for Downloaded Fonts

The SetFontSource method can be used as a way of adding downloaded font content to the existing collection of type faces for a TextBlock object. The downloader parameter identifies the Downloader object representing the downloaded content. The downloaded content can either be an individual font file or packaged content, such as a Zip file, that contains one or more font files.

Note: Font files used with the SetFontSource method must be OpenType or TrueType® fonts, and have the file extension, "TTF".

The following JavaScript example shows how to use the Downloader object to download an individual font file.

JavaScript
// Event handler for initializing and executing a font file download request.
function onMouseLeftButtonUp(sender, eventArgs)
{
    // Retrieve a reference to the control.
    var control = sender.getHost();

    // Create a Downloader object.
    var downloader = control.createObject("downloader");

    // Add Completed event.
    downloader.addEventListener("Completed", "onCompleted");

    // Initialize the Downloader request.
    downloader.open("GET", "SHOWG.TTF", true);

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

When the font file has been downloaded, it needs to be added to the TextBlock's collection of type faces. Once it has been added to the collection, it can then be selected using the FontFamily property. The following JavaScript example shows how to use the SetFontSource method to add the the font file to the type face collection, and then set the FontFamily property to display the TextBlock with the downloaded font:

JavaScript
// Event handler for the Completed event.
function onCompleted(sender, eventArgs)
{
    // Retrieve the TextBlock object.
    var myTextBlock = sender.findName("myTextBlock");

    // Add the font files in the downloaded object to the TextBlock's type face collection.
    myTextBlock.setFontSource(sender);

    // Set the FontFamily property to the friendly name of the font.
    myTextBlock.fontFamily = "Showcard Gothic";

    myTextBlock.text = "Showcard Gothic";
}

You can also download font files contained in a packaged format, such as a Zip file. The Zip file can contain other content files, such as image files.

The following JavaScript example shows how to use the Downloader object to download a Zip file containing an image file and multiple font files.

JavaScript
// Initialize the Downloader request. Zip file contains: Coco.png, Britanic.ttf, Erasbd.ttf, Showg.ttf
downloader.open("GET", "myMediaAssets.zip", true);

When the Zip file has been downloaded, the font files it contains must be added to the TextBlock's collection of type faces. Once the font files have been added to the collection, they can then be selected using the FontFamily property. The following JavaScript example shows how to use the SetSource and SetFontSource methods to use the downloaded content.

JavaScript
// Event handler for the Completed event.
function onCompleted(sender, eventArgs)
{
    // Retrieve the Image object.
    var myImage = sender.findName("myImage");

    // Set the Source property of the Image object to the specific image
    // within the downloaded Zip package file.
    myImage.setSource(sender, "Coco.png");

    // Retrieve the TextBlock object.
    var myTextBlock = sender.findName("myTextBlock");

    // Add the font files in the downloaded package object to the TextBlock's type face collection.
    myTextBlock.setFontSource(sender);

    // Set the FontFamily property to the friendly name of the font.
    myTextBlock.fontFamily = "Showcard Gothic";
}

To return to the default font used to display the TextBlock, set the downloader parameter of the SetFontSource method to null. The following JavaScript example shows how to use the SetFontSource method with a null parameter value.

JavaScript
// Retrieve the TextBlock object.
var myTextBlock = sender.findName("myTextBlock");

// Remove the custom font setting.
myTextBlock.setFontSource(null);

Handling Downloader Errors

The Status and StatusText properties provide the HTTP status code and corresponding text string value that represent the current state of the Downloader object request. The status values reflect the type of Downloader object request, as specified by the verb parameter in the Open method. For example, if the verb parameter is "GET" and the resulting download is successful, the value of Status is 200, and the value of StatusText is "OK".

The following table lists some of the more commonly received HTTP status codes. For more information, see HTTP Status Codes.

Status codeStatus textDescription
200OKThe request has succeeded.
403ForbiddenThe server understood the request, but is refusing to fulfill it. The request may not have authorized access to the resource.
404Not FoundThe server has not found anything matching the request URI.

The following JavaScript example shows how to use the Status property to test for a successful download:

JavaScript
// Event handler for the Completed event.
function onCompleted(sender, eventArgs)
{
    // Determine whether the download was successful.
    if (sender.status == 200)
    {
        // Retrieve downloaded content.
    }
    else
    {
        // Perform error handling actions.
    }
}

Using the Abort Method

The Abort method cancels the download request that has been executed by using the Send method of the Downloader object. In addition, the Abort method resets the following Downloader properties to their initial state:

Property nameInitial state
DownloadProgress0
Status0
StatusTextEmpty string

 

The following JavaScript example shows how to invoke the Abort method:

JavaScript
// Cancel download on mouse click.
function onLeftMouseButtonUp(sender, eventArgs)
{
    // Cancel Downloader activity and restore state.
    downloader.abort();
}

See Also

Downloader, CreateFromXamlDownloader, CreateObject, SetFontSource, SetSource,