Library tutorials & articles
Have you seen the Silverlight? – More Silverlight
- Handling Events
- Animations & Transformations
- Downloading & Dynamic Content
- Server-side Dynamic Content
Downloading & Dynamic Content
Downloading content
You’ll often want to pull down content, be it XAML, images or media. In many cases you can simply set the Source property of the relevant control or element, but what happens if you want some finer-grained control over the downloading process? Fortunately, Silverlight includes a Downloader object to do the heavy lifting for you. Let’s take a quick look at how you might use it to download a video, in this case whenever the user clicks the Load button.We’re aiming for a nice (at least to the limits of my graphical capabilities) download bar, as shown in Figure 2.
Figure 2: A simple progress bar
To achieve this effect we can show a Rectangle and adjust its Width as the download progresses. The code for this is shown in the following listing:
<Canvas ...> ... <MediaElement x:Name=”thePlayer” ... /> <Canvas x:Name=”progressBar” Visibility=”Hidden” Canvas.Top=”413” Canvas.Left=”272”> <Rectangle Stroke=”#FF0A358C” StrokeThickness=”2” Width=”204” Height=”30” RadiusX=”10” RadiusY=”10” /> <Rectangle Width=”0” Canvas.Top=”2” Height=”28” x:Name=”progressRect” Canvas.Left=”2” RadiusX=”8” RadiusY=”8”> <Rectangle.Fill> <LinearGradientBrush StartPoint=”0,0” EndPoint=”1,0”> <GradientStop Color=”Blue” Offset=”0”/> <GradientStop Color=”Purple” Offset=”1”/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> </Canvas> </Canvas>The progress bar consists of a Canvas that contains a couple of Rectangles that will be used to provide the outline and the fill of the bar. To implement the bar, we need to show the canvas and then adjust the width of the filled rectangle to reflect the download progress. All that is required once the media file has been downloaded is to hide the Canvas.
The key to the whole download mechanism is the Downloader object. This both performs the download and raises events to indicate its progress and to indicate that the download is complete. This is clearly very similar to making an XmlHttpRequest download in AJAX.
The full code to perform the media download is shown below:
handleMouseUp: function(
sender, eventArgs)
{
var downloader = sender.getHost().
createObject( “downloader” );
downloader.addEventListener(
“downloadProgressChanged”,
Sys.Silverlight.createDelegate(
this, this.onProgressChanged ) );
downloader.addEventListener(
“completed”,
Sys.Silverlight.createDelegate( this,
this.onDownloadCompleted ) );
sender.findName( “progressBar”
).visibility = “Visible”;
downloader.open( “GET”,
“http://localhost/mediasite/
handler.ashx?movie=brushes”,
true );
downloader.send();
},
onProgressChanged: function(
sender, eventArgs )
{
var progressRect = sender.findName(
“progressRect” );
if( sender.downloadProgress <= 1.0 )
progressRect.width =
sender.downloadProgress * 200.0;
},
onDownloadCompleted: function(
sender, eventArgs )
{
sender.findName( “progressBar” ).
visibility = “hidden”;
sender.findName( “progressRect” ).
width = 0.0;
sender.findName( “thePlayer” ).
setSource( sender, “” );
},
...
The handleMouseUp method is called in response to the user clicking the Load button. This method uses the Silverlight control’s createObject() method to create the Downloader object. In fact, in Silverlight 1.0 this is the only type of object that you can create with createObject().
We then connect up the two main events of the Downloader so that we can report progress, before commencing the download. One thing to be aware of is that the Visibility property of an element is not a Boolean, but one of three values: hidden, visible or collapsed.
In the onProgressChanged event handler the width of the progress rectangle is changed to reflect the percentage that’s been downloaded. There’s only one thing to watch out for here: the downloadProgress value returned by the Downloader object will be in the range 0 to 1, unless the content-length header has not been set by the server. In this case, it will return infinity, which is not a legal value for the width of a rectangle!
Finally, in the onDownloadCompleted event handler we hide the Canvas that contains all the progress bar information and then set the Source property on our MediaElement. The setSource() method takes a reference to the Downloader, plus the name of a the part that should be used, which should be set to “” when only a single file (rather than a .zip file) has been downloaded.
As you can appreciate, the Downloader object offers functionality that’s very similar to making a standard AJAX callback.
Dynamic content
One of the joys of Silverlight is the way that you can dynamically create and alter content. Again, this is something that’s being done increasingly with AJAX applications, but I find that Silverlight is just that little bit easier.Let’s start with a simple client-only example. Figure 3 shows an updated version of the page, which now includes a facility.
Figure 3: Dynamically loading XAML
This is perhaps not the sort of feature that you’d want to provide in a typical media player, but it certainly shows how flexible the XAML scene can become.
<script type=”text/javascript”>
<!--
function loadXAML()
{
var control =
document.getElementById(
“SilverlightControl” );
var xamlFragment =
document.getElementById(
“txtXAML” ).value;
var elem =
control.content.createFromXAML(
xamlFragment );
var btn =
control.content.findName(
document.getElementById(
“selectTarget”).value );
btn.fill = elem;
}
// -->
</script>
...
<textarea id=”txtXAML” ... />
<select id=”selectTarget”>...</select>
<input id=”btnLoadXAML” type=”button”
value=”Load” onclick=”loadXAML();” />
...
As you can see, the code in the listing merely extracts the value from the textarea and uses it to create some elements from the XAML, which it then sets as the fill for the selected button. Clearly, this assumes that the user enters valid XAML for a Brush, such as a SolidColorBrush or LinearGradientBrush.
Note that it will rarely make sense to allow the user to enter XAML directly, but the purpose of this code was really to show you how to create XAML on the client and add it into the current scene.
Related articles
Related discussion
-
Gizmox Announces release of Visual WebGui SDK version 6.2.2
by Visual WebGui (0 replies)
-
DeveloperDeveloperDeveloper! Day 7
by James Crowley (2 replies)
-
vbug's winter conference 2008
by James Crowley (0 replies)
-
Profile Class does not work after Translation
by converter2009 (1 replies)
-
what is the SQL Server Provider
by hayperaktib (1 replies)
Related podcasts
-
Episode 30: Year-end wrapup
K Scott leads the discussion as we look back at 2008, and speculate wildly on what 2009 has to offer. Note: Scott K's taking a podcasting break to change diapers and stuff. Looking back at 2008 Google Chrome Kevin's new iPhone Kevin's Firefox extension a...
Events coming up
-
Mar
15
DevWeek 2010
London, United Kingdom
DevWeek is Europe’s leading independent conference for software developers, database professionals and IT architects, and features expert speakers on a wide range of topics, including .NET 4.0, Silverlight 3, WCF 4, Visual Studio 2010, REST, Windows Workflow 4, Thread Synchronization, ASP.NET 4.0, SQL Server 2008 R2, LINQ, Unit Testing, CLR & C# 4.0, .NET Patterns, WPF 4, F#, Windows Azure, ADO.NET, Entity Framework, Debugging, T-SQL Tips & Tricks, and more.
This thread is for discussions of Have you seen the Silverlight? – More Silverlight.