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 Visual Studio just to get a taste of Silverlight.
Prerequisites
- All the prerequisites defined in the Silverlight MSBuild tutorial.
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.
- Rectangle Click Sample (you may read this software’s license here)
You can see it in action, here.
Lesson
Step 1: Create the HTML
Let’s put the concepts discussed in the Silverlight framework 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
Now, 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 SDK:
function createSilverlight( controlHost )
{
Silverlight.createObjectEx({
source: "ClientBin/RectangleClickApplication.xap",
parentElement: controlHost,
id: "silverlightControl",
properties: {
width: "350",
height: "350",
version: "2.0.31005.0",
background: "white",
isWindowless: "true",
enableHtmlAccess: "true"
},
events: {}
});
}
So, we’ll tell MSBuild to will wrap the end result of all our work in a file named “RectangleClickApplication.xap”. We’ve got a long way to go before we have that file so let’s keep going.
Step 3: Create the XAML
We’ll start with the XAML. Create a file named “RectangleClickControl.xaml”. In it, declare a UserControl object that holds a Canvas element, like so:
<UserControl
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="100" Height="100">
<Canvas Width="200" Height="200">
</Canvas>
</UserControl>
Simple enough. 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:
<UserControl
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="100" Height="100">
<Canvas Width="200" Height="200">
<Rectangle
x:Name="TheRectangle"
Width="50"
Height="50"
Fill="Blue"
Canvas.Left="25"
Canvas.Top="25" />
</Canvas>
</UserControl>
Another simple declaration, however this time, for the Rectangle, 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 RectangleClickControl.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 RectangleClickControl which represents the UserControl 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 partial class RectangleClickControl : UserControl
{
private Rectangle theRectangle = null;
public RectangleClickControl()
{
InitializeComponent();
}
}
}
When I say RectangleClickControl class represents the UserControl element declared in XAML, I mean exactly that. Microsoft uses he same “code-behind” concept here as they did with ASP.NET. If you haven’t quite wrapped your brain around that yet, please read my Silverlight Intro post and Microsoft’s Windows Presentation Foundation introduction post.
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 UserControl the RectangleClickControl corresponds to, we can use the FindName function inherited by RectangleClickControl 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, you’ll see how to “hook into” the load event.
Here’s the code:
(I left out the namespace declaration and imports for readability)
public class RectangleClickControl : UserControl
{
private Rectangle theRectangle = null;
public RectangleClickControl()
{
InitializeComponent();
}
public void RectangleClickControl_Loaded(object o, EventArgs e)
{
theRectangle = this.FindName("TheRectangle") as Rectangle;
theRectangle.MouseLeftButtonUp += new MouseButtonEventHandler(OnClick);
}
}
The new RectangleClickControl_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 partial class RectangleClickControl : UserControl
{
private Rectangle theRectangle = null;
public RectangleClickControl()
{
InitializeComponent();
}
public void RectangleClickControl_Loaded(object o, EventArgs e)
{
theRectangle = this.FindName("TheRectangle") as Rectangle;
theRectangle.MouseLeftButtonUp += new MouseButtonEventHandler(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 :).
Step 5: Connect the XAML to the C# code
Now, we need to point the UserControl tag to the class defined in RectangleClickControl.xaml.cs. The UserControl has an attribute named x:Class specifically for this purpose:
<UserControl
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="RectangleClickApplication.RectangleClickControl"
Width="100" Height="100">
<Canvas Width="200" Height="200">
<Rectangle
x:Name="TheRectangle"
Width="50"
Height="50"
Fill="Blue"
Canvas.Left="25"
Canvas.Top="25" />
</Canvas>
</UserControl>
As you can clearly see, the x:Class’s attribute value, RectangleClickApplication.RectangleClickControl, points to our C# class (namespace.class name). And, it’s as simple as that.
Lastly, with the C# class wired to our XAML, we need to hook our C# class into the UserControl load event.
Step 6: Handling the Canvas load event
In Step 4, we created a function named RectangleClickControl_Loaded to handle the load event sent by Silverlight. We handle into this event by setting the “Loaded” attribute on our UserControl tag:
<UserControl
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="RectangleClickApplication.RectangleClickControl"
Width="100" Height="100"
Loaded="RectangleClickControl_Loaded">
<Canvas Width="200" Height="200">
<Rectangle
x:Name="TheRectangle"
Width="50"
Height="50"
Fill="Blue"
Canvas.Left="25"
Canvas.Top="25" />
</Canvas>
</UserControl>
Step 7: Create the application code
I went over this in detail during my MSBuild tutorial, so I won’t discuss it much here. Just create two files named App.xaml and App.xaml.cs, and put this code in them:
App.xaml
<Application
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="RectangleClickApplication.App"
Startup="Application_Startup">
</Application>
App.xaml.cs
using System.Windows;
namespace RectangleClickApplication
{
public partial class App : Application
{
public App()
{
InitializeComponent();
}
void Application_Startup(object sender, StartupEventArgs e)
{
// Load the main control
this.RootVisual = new RectangleClickControl();
}
}
}
Now, we can finally build this bad boy.
Step 8: Build it
I explained all the components of a build file in my MSBuild tutorial so, I will paste the build file for this application below and, if you don’t understand it, please reference that tutorial where I explain each component in depth.
RectangleClickApplication.csproj
<Project
ToolsVersion="3.5"
DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Compilation options -->
<PropertyGroup>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<SchemaVersion>2.0</SchemaVersion>
<NoStdLib>true</NoStdLib>
<NoStdCfg>true</NoStdCfg>
<RootNamespace>RectangleClickApplication</RootNamespace>
<AssemblyName>RectangleClickApplication</AssemblyName>
<OutputType>Library</OutputType>
<OutputPath>ClientBin</OutputPath>
</PropertyGroup>
<!-- Deployment options -->
<PropertyGroup>
<SilverlightApplication>true</SilverlightApplication>
<SilverlightAppEntry>RectangleClickApplication.App</SilverlightAppEntry>
<SilverlightManifestTemplate>AppManifest.xml</SilverlightManifestTemplate>
<GenerateSilverlightManifest>true</GenerateSilverlightManifest>
<XapOutputs>true</XapOutputs>
<XapFilename>RectangleClickApplication.xap</XapFilename>
</PropertyGroup>
<!-- References -->
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="system" />
<Reference Include="System.Windows" />
</ItemGroup>
<!-- Files -->
<ItemGroup>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:MarkupCompilePass1</Generator>
</ApplicationDefinition>
</ItemGroup>
<ItemGroup>
<Page Include="RectangleClickControl.xaml">
<Generator>MSBuild:CompileXaml</Generator>
</Page>
<Compile Include="RectangleClickControl.xaml.cs">
<DependentUpon>RectangleClickControl.xaml</DependentUpon>
</Compile>
</ItemGroup>
<!-- Targets -->
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight\v2.0\Microsoft.Silverlight.CSharp.targets" />
</Project>
And, don’t forget the AppManifest template:
AppManifest.xml
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" RuntimeVersion="2.0.30523.1">
</Deployment>
You can build this application by running this command from the command-line, in your working directory:
"C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild.exe" RectangleClickApplication.csproj
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, you can do more complex event handling in your applications.



