Compartilhar via


Different ways for loading images and files in Silverlight 2 applications

When loading files in Silverlight 2 applications, this can range from images, video, fonts, etc, there are several options available. You might want to call files that reside on another server, files that are embedded into the .xap application or zip files that are downloaded and unpackaged on the client. In this post I’m reviewing the different options available for this, differences between them and how to implement each of the options.

As an example to load the files I’m using a UserControl with an image on it. A very simple example that is clear enough to show the different approaches. All of the examples I'm showing here have a XAML based approach with a code based counterpart, except for the sample for on demand download.

Base UserControl

 <UserControl x:Class="SLLoadResourcesApproaches.Page"
    xmlns="https://schemas.microsoft.com/client/2007" 
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
    <Grid x:Name="LayoutRoot" Background="White">
        <Image x:Name="imageElement" Stretch="Uniform" />
    </Grid>
</UserControl>

This just displays the image, nothing more:

image 

Referencing files in the same directory as the Silverlight application (ClientBin directory )

In other words, this is the default location of your .xap file, so files that are located in the same directory as the base application. By default when you create the Silverlight application with a test web site in Visual Studio this is the ClientBin directory. No extra code is needed to load files in this location.

If the file is placed in the ClientBin directory, call the file in XAML:

 <Image x:Name="imageElement" Stretch="Uniform" Source="_DTH8643.jpg" />

Or in code:

 imageElement.Source = new BitmapImage(new Uri("_DTH8643.jpg", UriKind.Relative));

Note: for the above sample you can use a forward-slash preceding the image name to express that it is located relative to the .xap file (same directory in this case). This is important to not as here it is not the root of the domain name (absolute path) that is taken into account. Take this example where I have a sub-directory to ClientBin, I’m referencing the file as /images/imagename.jpg.

image

To reference the file in the images directory in the ClientBin:

 imageElement.Source = new BitmapImage(new 
   Uri("/images/_DTH8643.jpg", UriKind.Relative));

First time I used this it caused some confusion as I'm used to referrring to files in the root of the domain in this way, not in a sub-directory, so it's important to note this difference with Silverlight.

Copying files to ClientBin upon build in Visual Studio

In the case you are using the files directly in your Silverlight application and don't want to copy them manually to the ClientBin directory you can set this in Visual Studio. Note this is a copy to the ClientBin directory of the Silverlight application project, not the test web project you may have created.

Build action: None.

Copy to Output Directory: Copy always.

image

Loading files located outside of ClientBin (.xap location) directory

In the above screenshot I have an image files located in the "images2" directory. To load images from that directory I can enter the full URL of the image:

 <Image x:Name="imageElement" Stretch="Uniform" 
Source="https://localhost:55907/SLLoadResourcesApproaches_Web/
images2/_DTH8643.jpg" />

In C# code:

 imageElement.Source = new BitmapImage(
new Uri("https://localhost:55907/SLLoadResourcesApproaches_Web
/images2/_DTH8643.jpg", UriKind.Absolute));

Referencing files on external web sites

If you want to call images that reside on external sites you can use the standard download method by using WebClient. Remember that cross domain restrictions apply.

Other than that it is just like calling images using the full URL like above.

 imageElement.Source = new BitmapImage(new 
Uri("https://farm3.static.flickr.com/2013/2438725399_4fa3c6eb2f.jpg?v=0", UriKind.Absolute));

There is however maybe a better way to load a file in from an external site where you can better control the loading of your file before showing it in the UI. By using the WebClient class you can download external files on demand, be it from the current origin site or external sites (see below notes on cross domain restrictions). Using the WebClient you can control what to display while the image or file is being downloaded using event handlers. This approach however is not available in XAML but only in code.

1. Create a WebClient object, an OpenReadCompleted event handler and start the download process

 WebClient webClientImgDownloader = new WebClient();
webClientImgDownloader.OpenReadCompleted += new 
  OpenReadCompletedEventHandler(webClientImgDownloader_OpenReadCompleted);
webClientImgDownloader.OpenReadAsync(photo);

2. Set the source to the image in the OpenReadCompleted event handler

  void webClientImgDownloader_OpenReadCompleted(object sender, 
     OpenReadCompletedEventArgs e)
        {
            BitmapImage bitmap = new BitmapImage();
            bitmap.SetSource(e.Result);
            imageElement.Source = bitmap;
        }

Referencing files included in application package (the .xap file, not the assembly)

When you need your Silverlight application to be independent of any files stored on the server separately you can include everything into a single .xap file. The same applies to file that are integral part of the application. If you know a certain file is always used when running the application it makes sense to include it in the .xap file as there is no reason to download it separately. Including files to be part of the package is what we call Content files.

Files that are packaged into the .xap file need to have the Build Action in Visual Studio set to "Content".

image

To call the file from XAML:

 <Image x:Name="imageElement" Stretch="Uniform" Source="/_DTH8643.jpg" />

Calling from code:

 imageElement.Source = new BitmapImage(new Uri("/_DTH8643.jpg", UriKind.Relative));

Because the files is located at the same level in the application package as the assembly in which the code is running, the forward-slash preceding the name is required here as well.

Files can also be located in sub-directories of the application package. You will notice that the directories are also included in the .xap file (as they would in any .zip archive file).

Application resources: calling files embedded in the application assembly (DLL)

As with other .NET assemblies, files can be embedded into the assembly as resources. For Silverlight applications, set the file Build Action to Resource.

image

Referencing resources embedded into the assembly is implemented in the same way as loading files included in the application (.xap). The difference is they are added to the DLL and thus no longer visible in the .xap file if you unzip it. 

In XAML:

 <Image x:Name="imageElement" Stretch="Uniform" 
Source="/_DTH8643.jpg" />

Code call:

 imageElement.Source = new BitmapImage(new 
Uri("/_DTH8643.jpg", UriKind.Relative));

This is working well for the current assembly but if you want to use a file located in a referenced assembly (a Silverlight class library) you will need to add a special reference to indicate the assembly you are calling the file from. This is done by adding the following prefix to calling the file:

/AssemblyName;component/

So, in the example below I'm calling an image from the assembly named ReferencedSlLibrary.

 <Image x:Name="imageElement" Stretch="Uniform" 
Source="/ReferencedSlLibrary;component/_DTH8643.jpg" />

Code call:

 imageElement.Source = new BitmapImage(new 
Uri("/ReferencedSlLibrarys;component/_DTH8643.jpg", UriKind.Relative));

VS 2008 - SL 2 Beta 1 note: you will notice that the image does almost only get displayed in the Visual Studio designer if you set the source in the above manner, even for own assembly files. I'm guessing this is a bug in beta 1.

Embedding fonts

To embed fonts there is actually a specific implementation to call upon font files, see this great post by Tim Heuer on the different ways to do this.

Comments

  • Anonymous
    April 27, 2008
    PingBack from http://microsoftnews.askpcdoc.com/visual-studio/different-ways-for-loading-images-and-files-in-silverlight-2-applications

  • Anonymous
    May 01, 2008
    In one previous blog I discussed about uploading applications or video asset files to a Silverlight Streaming

  • Anonymous
    June 13, 2008
    (This information relates to Silverlight 2 Beta 2) What does XAP mean? XAP (pronounced ZAP) is the file

  • Anonymous
    October 03, 2008
    One question we receive very often from our customers, is how to load an image, fromdifferent relative

  • Anonymous
    July 25, 2010
    The comment has been removed

  • Anonymous
    November 15, 2011
    How can I load programatically an image from a local path without include it in the Project ?? for example: C:/Images/TestImage.jpg

  • Anonymous
    November 16, 2011
    @Cristobal: you can load local images (My Pictures) only in Elevated Mode, however this is out of the browser. More info here: www.silverlightshow.net/.../Silverlight-4-elevated-permissions.aspx

  • Anonymous
    June 13, 2012
    great work... This saves me a lot of time...

  • Anonymous
    December 02, 2012
    @Katrien DG you could use the OpenFileDialog in SL5 to get a stream for the selected file

  • Anonymous
    May 30, 2013
    Thanks for the thorough coverage of this topic. I've noticed that Silverlight (as of version 5.1) does not natively render images that are icons (.ico file). Hope this support will be added in the next version.

  • Anonymous
    August 27, 2013
    I think you can use the Silverlight file dialog to open a local image as stream and then show it without any security issue. However the file dialog will have to appear from user initiated action (e.g. button click etc.)

  • Anonymous
    August 27, 2013
    The comment has been removed