10 Minute Tutorial - Silverlight: Event handling using Managed Code (C#)

Managed code.

In the browser.

All my dreams have come true.

Well, not quite. Catherine Zeta-Jones and Lucy Liu still haven’t returned my calls. But, it’s a start! ;)

I wrote this tutorial to illustrate how Silverlight communicates with managed code. So, as a simple example, we’ll use C# to handle click events inside of a rectangle rendered on a Silverlight control. And, like always, you can complete this tutorial sans-IDE, for those users who don’t want to install Orcas Beta 2 just to get a taste of Silverlight (users like me :) ).

Prerequisites

QuickStart

If you want to see the end result of this tutorial and you have installed all the prerequisites, then please download the ZIP file below, unzip it and open the rectangle-click.html file in your browser.

You can see it in action, here.

Lesson

Step 1: Create the HTML

Let’s put the framework concepts discussed in the last tutorial to good use and start by creating an HTML page named “rectangle-click.html” that contains a Silverlight control and references the JavaScript files necessary to initialize it:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 	<head>
 	 	<title>Rectangle Click Sample</title>
 	 	<script type=”text/javascript” src=”Silverlight.js”></script>
 	 	<script type=”text/javascript” src=”createSilverlight.js”></script>
  	</head>
  	<body>
  		<div id=”silverlightControlHost”>
  		</div>
  		<script type=”text/javascript”>
  		  	// Find the div by id
  		  	var hostElement = document.getElementById(”silverlightControlHost”);     

  		    	// Create the Silverlight control
  		  	createSilverlight(hostElement);
  		 </script>
  	</body>
</html>
Step 2: Initialize the Silverlight control with JavaScript

Similar to last time we need to create a file named createSilverlight.js. This fill will contain a call to the Silverlight.createObjectEx function found in the Silverlight.js file delivered in the Microsoft Silverlight Alpha 1.1 Refresh SDK:

function createSilverlight( controlHost )
{
	Silverlight.createObjectEx({
		source: "rectangleclick.xaml",
		parentElement: controlHost,
		id: "silverlightControl",
		properties: {
			width: "350",
			height: "350",
			version: "0.95",
			background: "white",
			isWindowless: "true",
			enableHtmlAccess: "true"
		},
		events: {}
	});
}

This time, we pass in “rectangleclick.xaml” as the XAML file for the Silverlight control to render. This file doesn’t exist yet, so let’s create it.

Step 3: Create the XAML

Create a file named “rectangleclick.xaml”. In it, declare a Canvas object that holds the Rectangle element we need for this tutorial, like so:

<Canvas
  xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 Width="100" Height="100">
</Canvas>

Simple enough. Although the last article didn’t mention it, take note of the two namespaces declared in the Canvas tag, especially the namespace “http://schemas.microsoft.com/winfx/2006/xaml” which we assigned the name “x”. We will put this namespace to use shortly.

Now, within the Canvas, declare the Rectangle we need:

<Canvas
  xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 Width="100" Height="100">
	  <Rectangle
	    x:Name=”TheRectangle”
	    Width=”50″
	    Height=”50″
	    Fill=”Blue”
	    Canvas.Left=”25″
	    Canvas.Top=”25″ />
</Canvas>

Another simple declaration, however this time we added a new attribute called “Name” and defined it in the “x” namespace, thus “x:Name”. We will use this name later.

Step 4: Create the C# code

Now for the main course. Create a file called RectangleClick.xaml.cs. This file will contain our code for handling the click event. Within this file, we will create the namespace RectangleClickApplication that contains a C# class named RectangleClickCanvas which represents the Canvas object we declared in Step 3:

namespace RectangleClickApplication
{
    using System;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Controls;
    using System.Windows.Shapes;     

    public class RectangleClickCanvas : Canvas
    {
        public RectangleClickCanvas()
        {
        }
    }
}

So, this begs the question, how and when do we access the Rectangle in order to set its click event handler?

I guess that’s two questions. :)

Anyway, first, the how - This is where the x:Name attribute on the <Rectangle> element we declared in Step 3 will help. Since the Rectangle resides within the <Canvas> the RectangleClickCanvas corresponds to, we can use the FindName function inherited by RectangleClickCanvas to find our Rectangle and then set its MouseLeftButtonUp event.

Now, the when - Silverlight will notify us when it finishes loading the Canvas. So, we simply need to respond to this “load event” and execute the instructions I mentioned above. For now, we will just declare the load event handler. Later, we will discuss how to “hook into” the load event.

Here’s the code:

(I left out the namespace declaration and imports for readability)

 public class RectangleClickCanvas : Canvas
 {
	private Rectangle theRectangle = null;     

	public RectangleClickCanvas()
	{
	}     

	public void RectangleClickCanvas_Loaded(object o, EventArgs e)
	{
		theRectangle = this.FindName(”TheRectangle”) as Rectangle;
		theRectangle.MouseLeftButtonUp += new MouseEventHandler(OnClick);
	}
}

The new RectangleClickCanvas_Loaded function will handle the load event sent from Silverlight. That function calls the FindName function which should return a reference to a Rectangle object that we tuck away in a private variable named theRectangle, for use later. Finally, we set the MouseLeftButtonUp event to a new MouseEventHandler delegate that uses the as-yet-undefined function OnClick.

So, let’s define the “OnClick” function:

public class RectangleClickCanvas : Canvas
 {
	private Rectangle theRectangle = null;     

	public RectangleClickCanvas()
	{
	}     

	public void RectangleClickCanvas_Loaded(object o, EventArgs e)
	{
		theRectangle = this.FindName("TheRectangle") as Rectangle;
		theRectangle.MouseLeftButtonUp += new MouseEventHandler(OnClick);
	}     

	private void OnClick(object sender, MouseEventArgs e)
	{
		SolidColorBrush rectanglePaintBrush = new SolidColorBrush();
		rectanglePaintBrush.Color = Colors.Red;
		theRectangle.Fill = rectanglePaintBrush;
	}
}

The logic in the OnClick function says that when the user clicks the Rectangle, the Rectangle will re-paint itself red. Not too impressive, but it gets the point across :). Now, let’s compile this bad boy.

Step 5: Compile the C# code for Silverlight (without Visual Studio Orcas :))

Keeping the same minimalist mindset that has plagued my other tutorials, we will compile our C# class from the command line. Let’s build this step-by-step (or should I say, command line option by command line option)

First, we have to run C# compiler. For a default installation this is found in the Windows directory:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe

Next, we need to tell the compiler the type of output we want to produce. In this case, Silverlight requires us to make a Class Library, so we use the library switch:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:library

Silverlight ships with its own libraries, so we have to tell the compiler not to include the standard .NET libraries using the /nostdlib+ switch

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:library /nostdlib+

We don’t want to reference any of the assemblies shipped with the .NET Framework, so we’ll do this by including the /noconfig option

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:library /nostdlib+ /noconfig

Next, we need to tell the compiler the name of our output file. You use the /out: option for this. For this tutorial, I set /out: to RectangleClickCanvas.dll:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:library /nostdlib+ /noconfig /out:RectangleClickCanvas.dll

Now, we must reference all the library files needed by Silverlight. For a default Silverlight installation, these files reside in C:\Program Files\Microsoft Silverlight. Successful compilation will require referencing the following files:

  • agclr.dll
  • mscorlib.dll
  • system.dll
  • System.Core.dll
  • System.Silverlight.dll
  • System.Xml.Core.dll

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:library /nostdlib+ /noconfig /out:RectangleClickCanvas.dll /lib:"C:\Program Files\Microsoft Silverlight" /r:agclr.dll;mscorlib.dll;system.dll;System.Core.dll;System.Silverlight.dll;System.Xml.Core.dll

Last but not least, we need to tell the C# compiler which file to compile:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:library /nostdlib+ /noconfig /out:RectangleClickCanvas.dll /lib:"C:\Program Files\Microsoft Silverlight" /r:agclr.dll;mscorlib.dll;system.dll;System.Core.dll;System.Silverlight.dll;System.Xml.Core.dll RectangleClick.xaml.cs

Running this entire line at a command prompt in the same directory where RectangleClick.xaml.cs exists should produce a RectangleClickCanvas.dll file.

For repeat compiles, creating a batch file can make your life easier. I used this batch file to compile this sample.

Step 6: Connect the XAML to the C# code

Now, we need to point the <Canvas> tag to the class in our freshly compiled Class Library. The <Canvas> allows an attribute named x:Class specifically for this purpose:

<Canvas
  xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class=”RectangleClickApplication.RectangleClickCanvas;assembly=RectangleClickCanvas.dll”
  Width=”100″ Height=”100″>
	  <Rectangle
	    x:Name=”TheRectangle”
	    Width=”50″
	    Height=”50″
	    Fill=”Blue”
	    Canvas.Left=”25″
	    Canvas.Top=”25″ />
</Canvas>

Visually parsing along the semi-colon delimiter, the first part of x:Class’s attribute value, RectangleClickApplication.RectangleClickCanvas, clearly points to our C# class (namespace.class name). The assembly=RectangleClickCanvas.dll portion tells Silverlight that the aforementioned class resides within the RectangleClickCanvas.dll. You can put a path here, for example “assembly=Bin/RectangleClickCanvas.dll”, but as outlined in this post, keep in mind that Silverlight currently evaluates the path relative to the HTML file declaring the control consuming the XAML.

Lastly, with the C# class wired to our XAML, we need to hook our C# class into the Canvas load event.

Step 7: Handling the Canvas load event

In Step 4, we created a function named RectangleClickCanvas_Loaded to handle the load event sent by Silverlight. We handle into this event by setting the “Loaded” attribute on our <Canvas> tag:

<Canvas
  xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="RectangleClickApplication.RectangleClickCanvas;assembly=RectangleClickCanvas.dll"
  Loaded=”RectangleClickCanvas_Loaded”
  Width=”100″ Height=”100″>
	  <Rectangle
	    x:Name=”TheRectangle”
	    Width=”50″
	    Height=”50″
	    Fill=”Blue”
	    Canvas.Left=”25″
	    Canvas.Top=”25″ />
</Canvas>
Step 8: Run it!

When you open the HTML file you should see a blue rectangle. When you click on this Rectangle, it should turn red. Mind blowing, I know. :) But by building on this simple example, we will be able to do more complex event handling in a future tutorial.

Share and Enjoy:
These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • StumbleUpon
  • Reddit
  • del.icio.us
Leave a Donation

If you found this article helpful, please leave a donation for Dave, so he can help you again. As always, thank you for your support!

Related Posts:
10 Minute Tutorial - Silverlight: Using JavaScript to Call Scriptable Managed Code (C#)
10 Most Important Points From Dr. Tim Sneath’s and Scott Guthrie’s Silverlight videos on Channel 9
10 Things I Learned From the September MSDN Event in Atlanta
Software License

Comments are closed.