Silverlight: User Controls with events

.NET, Silverlight, Technical stuff, Work
See comments

This article is for Silverlight 2 beta 1

Update: Corrado Cavalli translated the example in VB.NET. Thanks Corrado!!

Apparently, one reader had issues declaring events for the User Control example that I posted earlier this week.

He is programming in VB and unfortunately I don’t have a lot of experience with VB.NET, so I first created a working example with C#, and my good friend and fellow MVP Corrado Cavalli translated the example in VB.NET (see below).

The big difference between WPF and Silverlight regarding events is that Silverlight doesn’t support Routed Events (yet?). To be precise, some events are routed (all input events like MouseLeftButtonDown, KeyDown, etc…

Instead of declaring RoutedEvents in our User Control, we have to resort to standard .NET events then. From a user point of view, it doesn’t make a very big difference in the subscribing, but of course these events will not tunnel nor bubble (for a summary of RoutedEvents, bubbling and tunneling in WPF, read this).

The sample here declares a User Control called LeftRightButton, with two buttons, a LeftButton and a RightButton. it also declares two events, a LeftClick and a RightClick. When the RightButton gets clicked, the UserControls catch this event and raises a RightClick event. The same happens with the LeftButton and the LeftClick event.

Declaring new events for any class requires a Handler declaration (a delegate), and then the event declaration itself.

public delegate void ClickHandler(object sender, EventArgs e);
public event ClickHandler RightClick;
public event ClickHandler LeftClick;

The next step is to catch the internal click events, and to raise the corresponding “external” event. Note that in this simplified example, I just re-route the RoutedEventArg for the event. Often, you need to declare your own class inheriting EventArgs, for example to pass additional parameters to the event subscriber.

So if the XAML LeftButton is declared as:

<Button x:Name="LeftButton"
        Click="LeftButton_Click" />

then we have:

void RaiseLeftClick(RoutedEventArgs e)
  if (LeftClick != null)
    LeftClick(this, e);

Note how we check if the event is null before we raise it. If no one subscribed to the event, LeftClick will be null, and there is a risk for a NullReferenceException to be thrown.

Then only thing that we need to do now is catch the internal click event, and raise the corresponding RightClick or LeftClick event.

private void LeftButton_Click(object sender, RoutedEventArgs e)

The User Control raising these events is located in an external assembly as shown here. I use 4 instances of the User Control in a Silverlight application. This way, we demonstrate how to raise new events, how to catch them in another assembly, and how to handle them.

<controls:LeftRightButton x:Name="ButtonTopLeft"
                          LeftClick="LeftRightButtonButton_LeftClick" />

private void LeftRightButtonButton_LeftClick(object sender, EventArgs e)
  LastEventControlNameTextBlock.Text = (sender as LeftRightButton).Name;
  LastEventEventNameTextBlock.Text = "LeftClick";

4 user controls with events

The source code in C# can be downloaded here.

The source code in VB.NET (translated by Corrado Cavalli) can be downloaded here.

Previous entry | Next blog entry

Comments for Silverlight: User Controls with events