OK so we've all got the hang of WPF right, so now we have another beast to slay, it's Silverlight. Silverlight is an internet browser plugin that rivals Adobe Flash for capabilities, and uses a cut down version of Windows Presentation Foundation (WPF) which used to be known as WPF/e (WPF everywhere).

Silverlight currently comes in two flavours, Silverlight 1.0 which is JavaScript based, and the slightly newer 1.1 Alpha which can use managed .NET code. I personally am not that fond of JavaScript so I have been putting the Silverlight mission off until version 1.1.

So now that the 1.1 alpha is out, I thought it high time that I got down and started writing a Silverlight article. I have to say I am fairly pleased with this article, and I think it covers most aspects of what Silverlight can currently do. Of course this may change over time, but let's just assume that things are the way they are right now.

Before we get started, there is one thing that you will really need in order to run the demo project, and that's Visual Studio 2008 Beta 2, which is available here, I went for the Professional edition, and it works a treat. Downloaded, installed and worked first time, unlike all other VS2008 versions I went for. Professional edition works, use that.

One of the first things that you will notice when you start VS2008, is that there is a new project type available, yep you guessed it - a Silverlight project.

Remember that Silverlight applications are web based, so the best place to start is probably with a ASP.NET web project. If we then proceed to add a Silverlight project to our existing Web project, we end up with two projects as shown below. In this example (the demo app) the projects are Web: ASP.NET web site, and SilverlightProject1 which is the Silverlight project. One thing to notice in the screen shot below is that the Web project can be configured to run on a certain port within Visual Studio. This setting tells Cassini (the inbuilt VS web browser) to use a static or dynamic port, there will be more mentioned about this later.

When we add a new Silverlight project we end up with some boiler plate files, much the same way one does when creating a new project using one of the other Visual Studio templates. Consider the figure below which is a brand new Silverlight project.

The Silverlight DLLs are installed to the Program Files\Silverlight location.

There are three files for a new Silverlight project:

Page.xaml /Page.Xaml.cs (or vb if you are using VB.NET)

TestPage.html which holds the Silverlight object

Silverlight.js which is the JavaScript to create the Silverlight object within the page (TestPage.html in this case)

I'm just going to show you a bit about each of these three files, so you get the demo app file structure.

1. Page.xaml

Is made up of two files, the XAML and the code behind. Let's start with the XAML.

As can be seen from the figure above, the Page is simply a Canvas, in fact most controls/page areas in Silverlight 1.1 start out as a Canvas as there are few actual controls in Silverlight, but we'll talk about that a bit later as well.

When I first started looking at Silverlight (about one week now) I was very disappointed that there were no input controls, such as Buttons, TextBoxes, Tabs, ScrollViewers etc. I mean jeez no input controls, come on now.

You have to create these sort of things yourself, which is a bit time consuming but doable. There are some free controls available as mentioned in the resources section at the bottom of this article. One bit of good news is that the Silverlight 1.1 Alpha Refresh does include some basic controls. Have a look there before you start.

When dealing with Silverlight one must remember it is still Alpha, so things will change and get included. I have to say I started out quite negative (cos I like Flash) but by the end I loved Silverlight.

If we look at the Silverlight 1.1 Tutorials and Code Starts one can see that the following appears to be a list of what we can reasonably expect a Silverlight 1.1 application to be able to do (at the moment):

Getting Started with Silverlight Development

Building Dynamic User Interfaces with Silverlight

Creating Custom Controls

Networking and Communication in Silverlight

Sending and Receiving Plain XML Messages

Using a Proxy to Call an ASP.NET Web Service

Interaction Between HTML and Managed Code

Accessing the DOM from Managed Code

Additional Programming Tasks

Upload/Downloading

The attached demo app will demonstrate and discuss each of these areas.

What Does it Do / What are the Requirements

Ok so that's a screen shot of what it looks like. But what does it do, what were my requirements?

When I started (one week ago) I decided that I wanted to write a Silverlight application that would utilise most of the current Silverlight functions available. So I gave it a thought, and I came up with this: I wanted an application that would use a Web service that would query Flickr for images using a RSS feed, and would show these images in a scrollable panel from where the user may select an image to be viewed in the main page area. When an image was in the main area, I wanted it to be able to be dragged/resized and rotated (like MSFT surface) and removed from the main page area. The user may also get the next/previous page of results from Flickr, so it would have some sort of paging mechanism. I also wanted it to look cool.

This application has a lot of scope, it does indeed cover a lot of Silverlight functionality, and by the end of this article, I hope that you lot will get what you can do with Silverlight right now.

Here is another diagram for the finished demo app with some callouts showing which of the items shown are created by which classes in the attached application.

As I stated earlier, this demo app covers a lot of ground, it covers the following areas:

Using Web Services

Using XML (XLINQ cos I simply love it, and after all, this is a VS2008 article, so hey why not)

Using third party domains (Flickr in my case)

Using custom controls

Events

Using XAML/WPFe

Using the DOM from Silverlight

This image may help a little to see the dependencies and how all the classes and even projects relate to each other

It can be seen that there are two projects in the attached demo application, the Web project and the Silverlight project. The Silverlight project consists of the Silverlight page object and the hosting HTML page and setup JavaScript, along with code for all the custom controls that have been authored in order to carry out the demo application functionality.

The Web project has the compiled Silverlight project's DLL, and a copy of the Silverlight page object and the hosting HTML page and setup JavaScript. But the web project also has other classes, which are used by the Silverlight project. The rule of thumb with Silverlight 1.1 is that it can ONLY use localhost (127.0.0.1) resources, so that's why there are some extra items in the web project, basically they are used by the Silverlight project in one way or another. Don't worry, these will be described in detail in the following sections.

I'll briefly describe some of the extra files:

PhotoInfo.cs: A small class that represents a Photo

RSSFeed.cs: A RSS Feed parser for a Flickr RSS feed

WebService.asmx / WebService.cs: A web service that is used by the Silverlight Page.xaml.cs object

Getting Started with Silverlight Development

Networking and Communication in Silverlight

There are several different options for getting data into Silverlight, you can use either of the following approaches:

XML Files

Web Services

I'll talk about each of these a bit and then I'll show you what the demo application actually does to get its data.

XML Files

As I don't do this in my demo application (attached), I'm going to simply use the quickstart code from here to illustrate how to read XML data in your Silverlight applications.

The relevant MSFT quick start is located here. What they do is use a local XML file called rssfeed.xml, which they then parse and use within a Silverlight application. The format of the rssfeed.xml file is as shown below:

Whilst this certainly does the job just fine, a better approach may be to use a Web service to return a nice collection of some .NET objects that the Silverlight app could use, without having to do all this parsing. Enter Web Services / Silverlight communications.

Web Services and Silverlight

Silverlight can actually call an ASP.NET web service no problem. It's simply a question of creating a web reference in the Silverlight project. One thing that is important to note, is that cross domain calls (not localhost) aren't currently allowed using certain Silverlight objects, as I'll discuss later on when we get to the Downloader object explanation. And if like me, you don't have IIS installed and rely on Cassini (the Visual Studio web browser) you may find that it allocates a dynamic port each time it runs. You may think this is fine, as it's all on the same domain, but it's not. A quick check on Google assured me that the port is actually included as part of the checks that is made when checking for cross domain access. So that's a bit annoying. Luckily there's an easy fix, either host your Silverlight on IIS proper using fixed port (usually 80 I believe), or use Cassini and configure it to use a static port. The latter is what I have done for the demo application.

I'm going to go through the steps to get an ASP.NET web service up and running with Silverlight in VS2008.

If you want a good link to get you started with Silverlight and ASP.NET web services in VS2008, check out this excellent entry, by MSFTs Mike Taulty. This is what got me up and running. I've copied his post here for folk that just want to read everything in one article.

Steps as below:

File->New->Web Site. I've been working with Cassini so I just put the website into the file system

Quite an important part to note is that the web methods should be marked with the [ScriptMethod(ResponseFormat = ResponseFormat.Json)] attribute. I believe this is the only format that Silverlight 1.1 works with, so that's why it is needed.

Now we have a service, let's build something from Silverlight to call it:

File->Add->New Project->Silverlight Project

Now, add a web reference to the web service from the Silverlight project. Note: If you're using Cassini then I'd suggest setting it up to run on a fixed port at this point by changing your web site properties otherwise your web reference will break from time to time. Property sheet below shows dynamic ports is set to false and port number is set to 65534.

Add a web reference from the Silverlight Project to the web service (for me this is to http://localhost:65534/WebSite2/WebService.asmx?wsdl) - you'll perhaps have to spin up your web service project first in order to get Cassini sitting and listening for traffic (i.e. setting your ASMX file as the start page and pressing CTRL F5 should do that).

Now, when it comes to debugging it seems that running a Silverlight project just loads the page from the file system and I'm not sure whether that's going to work when your page is calling a service that comes from elsewhere, so what I've been doing is:

Add a link from the Web Site project to the Silverlight Project using the "Add Silverlight Link" menu option off the right mouse menu when you right click on your web project. This will get your assembly, PDB and XAML files copied to the web site and kept in sync (be careful not to edit the XAML file in the wrong place after doing this - it's bitten me more than once and if you edit the one in the web folder then it'll get overwritten on each build).

The Demo App Implementation

Ok so I've now shown you that you can use XML and Web Services from within your Silverlight app, which is cool, huh. I also stated that I was not that keen on using XML file parsing in my Silverlight application. So what do I do. Well I have a fairly simply ASP.NET web service that I reference, and call just like I described above, and I am using XML too. It's just how the XML is dealt with that's different. Let's have a look at what I do. Recall, I wanted to use Flickr. Flickr actually has a RssFeed which is available using the following URL: "http://www.flickr.com/services/rest/?method=flickr.interestingness.getList&api_key=" + _FLICKR_API_KEY;

When I bash this URL into the browser, the following XML is returned.

<rspstat="ok"><photospage="1"pages="5"perpage="100"total="500"><photoid="1809392098"owner="37451064@N00"secret="9ddb3512d4"server="2012"farm="3"title="Day 278/365......This is about as Halloween as I get"ispublic="1"isfriend="0"isfamily="0"/><photoid="1807982526"owner="51107197@N00"secret="1dd4e67541"server="2241"farm="3"title="Polihale Sunset"ispublic="1"isfriend="0"isfamily="0"/><photoid="1807122211"owner="55217458@N00"secret="4c333e73e4"server="2112"farm="3"title="waiting"ispublic="1"isfriend="0"isfamily="0"/><photoid="1808703464"owner="76743095@N00"secret="85d3010d77"server="2131"farm="3"title="Cyclops"ispublic="1"isfriend="0"isfamily="0"/>
....
....
</photos></rsp>

So I thought why not use XLINQ to do something cool. There may be some of you who have read some of my other WPF articles, and have seen this before. But I am a creature of habit, and really like Flickr, so sorry if this is old to you guys.

But with this XML feed available I am able to use XLINQ to select the data I'm interested in, into new .NET types, which are returned via the web service to the Silverlight application. Let's have a look shall we.

It can be seen that this call to the web service actually returns an array of SilverlightProject1.FlickrService.PhotoInfo[] which come straight from the web service call. So let's follow this chain of events. The web service looks like:

So it can also been seen that the web service holds an instance to an RssFeed object, which it calls on the GetFlickr() method, which calls the RssFeed objects LoadPictures() method. Mmm. Let's look at that.

Notice the cool XLINQ stuff, all too easy, no nasty XML file parsing. Sold that. Just use XLINQ and create a collection of new CLR objects, (PhotoInfo) in my case. Neat. And then return that to the web service as a list of PhotoInfo where the web service simply returns these to the Silverlight application. Once in the Silverlight application, we can use these PhotoInfo objects any way we like. They are in fact used to obtain images from Flickr as we'll discuss later. Now isn't that neater than messing around with XML parsing. XLINQ rocks. In fact LINQ rocks, MSFT have got it well right if you ask me.

Building Dynamic User Interfaces with Silverlight

Silverlight development is all about custom controls, there are very few native controls the way it stands at the moment. But it's only an alpha after all. That said there aren't any input controls, which I mentioned earlier. You have to write most of the stuff yourself. The Silverlight 1.1 reference poster quite clearly shows you which controls are available to you. It's basically the following controls:

Canvas

Control

Image

MediaElement

OpenFileDialog

TextBlock and a few more

So how are people creating such RIAs using Silverlight. Well it's down to hard work, and to be honest it's not that hard, and Silverlight is actually fun you know, so you get into it. I think the best place to start is to show you how to create a custom control or two. I'm going to show you how to create a button and then an image which is rotated and has an alpha applied to it when you mouse over it. I'll also briefly show screen shots and offer simple (yes, you'll have to investigate further) explanations of all other controls in the attached demo application.

Custom Button Control

I like to start with a screen shot.

This is what we are going to be making. A very simply button that glows when it has mouse focus, and can be disabled which will use a different disabled color brush. So that's what we are trying to achieve. So let's begin.

Most controls in Silverlight will either inherit from Control or from Canvas. In fact even Control ends up being a Canvas as you shall see. The first step is to decide if your control will have any markup (XAML) associated with it. If you want to do animations etc. you might like to use XAML (you can of course, do it in code too). If you want to use some XAML you probably want to inherit from Control, which you can do by deciding to add a new control is VS2008. If you do this, the new control will indeed inherit from Control, but it will also have an XAML file so that you can add elements to the XAML. So there will be two files, the xxxx.XAML and the xxxx.XAML.cs/vb which holds the controls logic. So you need some way of binding the two together, which is the first thing that must be done. This XAML must be loaded from a stream, into an actual element that can be used as a datum point (root element) for all other elements. The following code shows the XAML file for the button being loaded and a FrameworkElement being declared to hold the newly constructed element read from the XAML.

So once you've loaded the XAML and obtained a reference to the actual element (FrameworkElement), you can try and find objects within the XAML DOM. The complete code for the GrayButton is shown below to give you a flavour of what you need to do in order to create a custom control with events and XAML. This is a very simple button implementation, but it does the job.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;
namespace SilverlightProject1.Controls
{
///<spanclass="code-SummaryComment"><summary></span>

You can see that the root element is actually a Canvas, in fact nearly everything is actually a Canvas in Silverlight. Well, for the mean time anyway. I guess new controls will come with subsequent releases.

So that's one way of creating a custom control. But suppose you don't want any XAML and you just need code. Can you do that? Well sure you can, you can just inherit from Canvas directly. I do exactly this for one of my own controls, the ScrollCanas, which is a scrollable control which holds a page (using the LINQ Skip() Take() operations to perform paging) worth of SmallPhoto controls and looks like this. You can scroll the images by dragging with the mouse. The buttons can be used to fetch next/previous pages worth of images from Flickr, which is really just a call to the web service as I discussed earlier.

So I hope that's enough to get you started with custom controls. I did mention that I would briefly discuss all the custom controls in the demo app, so here we go.

The ScrollCanvas mentioned here hosts SmallPhoto controls.

SmallPhoto

It is a small control that holds an image and is randomly rotated and has mouse events for selecting, and has a selected event which is used by the parent (ScrollCanvas) control. It looks like this. The SmallPhoto control uses one of the PhotoInfo objects as returned by the web service, which we talked about earlier.

The ImageCanvas control is the main control that occupies the main Silverlight area and hosts Photo controls.

Photo

It is a control that holds an image and is randomly rotated and has mouse events for dragging/selecting/scaling/rotating. It looks like this. The combination of the ImageCanvas control and the hosted Photo controls offers an experience similar to that of MSFT surface. I should point out that I wanted to do this myself, but I found such a good example of this at Delays Blog and I couldn't have done it better, so I used it...sorry this is not good I know, it was just so cool already. But I feel I have added to it by getting the images from a different domain, I also introduced a close button and a caption. I also had to understand the code in the first place to change it. The Photo control uses one of the PhotoInfo objects as returned by the web service, which we talked about earlier.

The ImageCanvas control also hosts another control called ArtyCanvas which is just an image. However the ArtyCanvas itself also holds several flashing Ring controls. The Ring controls are just pulsing rings that I think brighten the place up. They are for aesthetic reasons. I like them, so should you.

Interaction between HTML and Managed Code

Silverlight has the ability to interact with the page that is hosting it. As mentioned above this may be one approach, where Silverlight could talk to ASP.NET input controls (remember Silverlight 1.1 doesn't have these as standard) that are actually not part of the Silverlight object that exist within the page hosting the Silverlight object. The reason I have not done this is that even if you go down the route of using ASP.NET web controls, they can't be positioned over the Silverlight object even if they are positioned using absolute positioning. Well that didn't work for me at any rate. But if you want them to be available outside of the Silverlight control area, this is entirely feasible. But I just think a better approach is to author the custom controls you think you need in .NET code. This way the controls are re-usable and are packaged into the Silverlight projects output DLL.

More typically what you may want to do is, set or get a value from the DOM for the page that is hosting the Silverlight object, so I'm going to talk you through how to do that. It's ever so easy, let's have a look at it.

That's the entire HTML/CSS for the hosting page for the attached demo application. The particular element to note is the label whose ID is set to bottomText, this is the one that I will be setting from Silverlight. One thing to note is that the GetElementByID() method is probably the most commonly used DOM method, so it's probably best to give the elements IDs. You could always use the GetElementsByTagName() but I just find it easier to use the GetElementByID() method.

Now let's have a look at how Silverlight gets and manipulates this element:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Collections.Generic;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;
//This is required to allow Silverlight to talk to hosting pages DOM
namespace SilverlightProject1
{
///<spanclass="code-SummaryComment"><summary></span>

It's really very simple, ensure that you have the using System.Windows.Browser; directive, and then you can create a new Document by asking the HtmlPage for its Document and then it's all fairly standard DOM stuff. You can even add event handlers to the DOM elements that will call Silverlight code. Let's have a look at an example of that. This example is simply a trimmed version of one of the MSFT Silverlight quickstarts.

You can also create new elements and append these to the DOM using the document.CreateElement() and document.DocumentElement.AppendChild(...) methods.

Additional Programming Tasks

Some other typical tasks may be to upload a file to the web server or download a file from the web server. This sounds a little tricky at first, but luckily MSFT has actually been kind to us and provided us devs with one nice class called Downloader, which as you could probably guess, is used to do a download of a file.

In the demo application, I am using the Downloader to download images from Flickr, which I'll talk about in just a minute, but let's just have a quick look at how to upload a file to the web server.

Uploading Files

Here is the relevant code to do an upload.

You would use something like this is a C#/VB code behind file within the Silverlight project.

Downloading Files

As I stated earlier, MSFT has been kind to us and has actually provided a nice little object called the Downloader, which we can use to download files. It's simple enough to use this Downloader class, simply create a new Downloader and tell it what to get, and subscribe to its Completed event, by which time the downloaded file should be ok to use. This is accessible on the Downloader which was created. Let's see a very simple example.

It's very simple to use the Downloader really. But, and there is a but, you can't (currently) use the Downloader to download files that are not on the same domain. And guess what, the cross domain check also includes port number. But wait, the attached demo application is getting images from Flickr, so how is it doing that, Flickr is indeed cross domain. Mmmm, curious. I also stated that I am using the Downloader to download files, so how is that.

Let's consider the following image, this is what we would like to do. We'd like a Silverlight application that can talk to both localhost resources and third party resources/services etc. But like I said, this isn't possible using the Downloader.

So what do we do about this. Well let's consider the following image, it can be seen that what actually happens is that we can still talk cross domain to Flickr, but we have to go via some proxy object. In my case as I only wanted to download images, I used an ASP.NET handler object, called DisplayImage.ashx. I found this trick on the internet, at Peter Kellners web site, so thanks for that Peter, top job.

By using the ASP.NET handler DisplayImage.ashx, which is a local resource, we are able to delegate the fetching of cross domain images from Flickr to the handler, and as each image is treated like this they are loaded asynchronously. Neat huh. So what does the code look like to do all this.

Well, like I stated earlier, both the Photo and SmallPhoto controls use images that come from a third party domain (Flickr) so how do they do that. Let's consider the code for the SmallPhoto control, it's the same principle for the Photo control. The SmallPhoto uses the following XAML:

You can see that there is an Image element there in the XAML. So that's where our image from Flickr (third party external domain) image will go. So how does the image end up there. Well let's look at the code behind for the SmallPhoto control.

You can see that there is a Downloader object, which I talked about earlier. But the Downloader object is actually calling the ASP.NET handler DisplayImage.ashx, and the job of fetching the cross domain image is actually done by the ASP.NET handler DisplayImage.ashx. Also of note, is that the SilverlightProject1.FlickrService.PhotoInfo is a new object that was created within the RSSFeed class which I talked about earlier. The SilverlightProject1.FlickrService.PhotoInfo was creating using the XLINQ selection technique that we saw earlier. So all that is left to discuss, is the ASP.NET handler itself. So let's have a look at that, shall we. It's important to remember that the ASP.NET handler DisplayImage.ashx is not part of the Silverlight project but is actually part of the associated web project, where the Silverlight object is actually hosted. But there is no issue with the Silverlight code talking to the ASP.NET handler DisplayImage.ashx. It's the same domain and port, so it's considered to be the same domain.

I would just like to ask, if you liked the article please vote for it, and leave some comments, as it lets me know if the article was at the right level or not, and whether it contained what people need to know.

I have enjoyed writing this article and I hoped that I've explained some useful information regarding Silverlight development. In closing, I would say I quite like this Silverlight stuff, I was pretty convinced that I was not going to like it at the start, just because I enjoyed Flash so much. But something strange happened during this last week, I actually did a complete U-Turn and found out I love Silverlight, and think that when the pukka fully released version of Silverlight comes out, it will be excellent, and will be a true competitor to Flash. And if MSFT listens to the feedback I'm sure future versions will be even better. What would be nice to see is some of the more powerful WPF features such as Templates/Styles and Binding and some user input controls/data controls may be nice too.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

I think I was reading another SL article that was doing something with flickr, then I spotted yours in the 'Other popular Silverlight articles' list and recalled it consumed a flickr feed also. Had to have a quick reminisce.

Unable to read the project file 'SilverlightProject1.csproj'.
C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\Test\Stick\Silverlight_WebService\SilverlightProject1\SilverlightProject1.csproj(127,11): The imported project "C:\Program Files\MSBuild\Microsoft\VisualStudio\v9.0\Silverlight\Microsoft.Silverlight.Csharp.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

to

Then I got... "ASP.NET runtime error: Could not load file or assembly ‘System.Data.DataSetExtensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified"
which I resolved with Chris Gaskell's Blog

Then I got a compiler error ofx:Class="SilverlightProject1.Page;assembly=ClientBin/SilverlightProject1.dll" is not valid. 'SilverlightProject1.Page;assembly=ClientBin/SilverlightProject1.dll' is not a valid fully qualified class name. C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\Test\Stick\Silverlight_WebService\SilverlightProject1\Page.xaml 1