Skip to main content Skip to footer

Create an Interactive Silverlight Gallery with Images from the Server

You don't have to package all of your images into your Silverlight application. It's quite possible to load images from a Web server.

image.Source = new BitmapImage(new Uri("http//www.somedomain.com/image.png"));

This approach uses an absolute address. How can you use a relative address to access an image? First, you'd probably try this code:

image.Source = new BitmapImage(new Uri("images/image.png", UriKind.Relative));

But this will only work if the image is included in the Silverilght XAP as a resource. To access an image on a server using a relative address, you can pass in the BaseUri dynamically to the image source like this:

image.Source = new BitmapImage(new Uri(App.Current.Host.Source, "/images/image.png"));

This actually turns a relative address into absolute dynamically given the app's host. This allows you to 1) avoid having to embed images in your Silverlight XAP so the images will be loaded as needed, and 2) now you can easily move the XAP to any domain and it will work (so long as the image exists relative to the XAP).

The 3rd line of code above is the key piece which makes creating a customizable image gallery with C1CoverFlow possible. The requirements of this gallery include 1) Images are customizable on the fly and 2) It can be useful on multiple pages or hosts. The images should be customizable on the fly, meaning you should not have to package each image with the Silverlight XAP, nor should you have to rebuild the XAP each time we want to add or remove an image. Instead you can maintain an XML file on the server which can be easily edited. The Silverlight app will read the image URLs from the XML file. And since the images are loaded relatively in a domain agnostic way, we can reuse this image gallery application anywhere without having to build multiple versions.

The Silverlight XAP will load an XML file via parameter. The XML file will have the relative paths for each image to be displayed in the gallery. We can easily update the images and the XML file over and over again. For starters, you need to define an XML format for keeping track of the images. Create a simple XML file like the one below and put this file on the server (it does not get included in the Silverlight project).


<?xml version="1.0" encoding="utf-8" ?>  
<images>  
  <image>  
    <url>/images/image1.png</url>  
  </image>  
  <image>  
    <url>/images/image2.png</url>  
  </image>  
  <image>  
    <url>/images/image3.png</url>  
  </image>  
  <image>  
    <url>/images/image4.png</url>  
  </image>  
</images>  

The images can be located anywhere relative to where you will put the Silverlight XAP on the server. You can name the file galleryimages.xml. Next, create a Silverlight project using C1CoverFlow. Name the project C1Gallery. The XML file will be passed to the Silverlight XAP through the initParams parameter. You can use the initParams to pass any variable information to the app. You declare these parameters in the object tag hosting the Silverlight plugin. For example: Then you need to get this parameter in the Application Startup event (App.xaml) through e.InitParams.Keys, like this:

private void Application_Startup(object sender, StartupEventArgs e)  
{  
    MainPage _mainPage = new MainPage();  
    string _url = "";  
    foreach (string key in e.InitParams.Keys)  
    {  
        if (key.Equals("url"))  
        {  
            _url = e.InitParams[key].ToString();  
        }  
    }  

    \_mainPage.ImageListUrl = \_url;  
    this.RootVisual = _mainPage;  
}

In this code above we're also setting up our MainPage as the RootVisual. You can pass the url parameter to the page by declaring a public property, such as ImageListUrl. The code below shows the basic setup for our MainPage.xaml including this property.

public partial class MainPage : UserControl  
{  
    private string _imageListUrl;  
    private List _galleryImages;  

    public MainPage()  
    {  
        InitializeComponent();  
    }  

   //gets or sets the location of the image list XML  
   public string ImageListUrl  
    {  
        get  
        {  
            return _imageListUrl;  
        }  
        set  
        {  
            _imageListUrl = value;  
        }  
    }  
}  

public class GalleryImage  
{  
    public string Url { get; set; }  
}

The XAML for the UI is very simple:


<Grid x:Name="LayoutRoot" Background="White">   
    <c1:C1CoverFlow x:Name="c1CoverFlow1"></c1:C1CoverFlow>   
</Grid>  

Finally, you can load the XML file, parse out each image and load it into C1CoverFlow. The code below uses a WebClient to download the XML file as a string asynchronously from the server. Note, that the URL of the XML file can also be a relative path like each of our images.

private void Page_Loaded(object sender, RoutedEventArgs e)  
{  
    //load xml file  
    WebClient wc = new WebClient();  
    wc.DownloadStringCompleted  = new System.Net.DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);  
    wc.DownloadStringAsync(new Uri(ImageListUrl, UriKind.RelativeOrAbsolute));  
}  

void wc_DownloadStringCompleted(object sender, System.Net.DownloadStringCompletedEventArgs e)  
{  
    if (e.Error == null)  
    {  
        //load xml to list  
        XDocument doc = XDocument.Parse(e.Result);  
        _galleryImages = (from image in doc.Descendants("image")  
                            select new GalleryImage  
                            {  
                                Url = image.Element("url").Value  
                            }).ToList();  

        //load coverflow  
        foreach (GalleryImage gi in _galleryImages)  
        {  
            BitmapImage bi = new BitmapImage();  
            bi.UriSource = new Uri(App.Current.Host.Source, gi.Url);  
            c1CoverFlow1.Items.Add(new Image() { Source = bi });  
        }  
    }  
}

And voila! You can check out this C1Gallery used elsewhere on the ComponentOne web site, and download the source below. The sample also allows you to customize the starting index of the CoverFlow by passing a 2nd parameter to the application.

Download C1Gallery Sample (C#)

You can even just download the packaged XAP and use this gallery as-is on your site! Download C1Gallery.xap

ComponentOne Product Manager Greg Lutz

Greg Lutz

comments powered by Disqus