Practical ASP.NET

Adding Events to User Controls

To fully exploit User Controls, you need to treat them as object -- which includes having them fire events. If firing your own events is new to you, here's a step-by-step guide.

In an earlier column, I talked about how to treat a User Control as an object, but I skipped over how to get your User Control to fire an event. Firing events isn't an ASP.NET-specific topic but because it's critical to integrating User Controls with their host page, it's worth discussing here.

The Notification Problem
The original problem was raised by one of this column's readers (yes, they do exist). My reader had a User Control with 26 buttons, one for each letter of the alphabet, and wanted to integrate the control with the host page by passing the letter represented by the button to the host page. The best solution is to fire an event from the User Control that the host page can catch.

To fire an event from your UserControl, you first need to declare a delegate that specifies the format of your event. By convention, the delegate used for events has a name that ends in "Handler" and has two parameters: The first parameter is of type Object and is a reference to the object that fired the event, while the second event is a custom class that you initialize with information to pass to the host page. This example defines a delegate called ButtonDataEventHandler.

With the delegate defined, you can declare an event that uses it:

Public Event LinkEvent As ButtonDataEventHandler

And with the event defined, you can fire the event in one of the Click events for the buttons on the page. When you fire the event you must set the two parameters specified in the delegate. In my reader's case, he wanted to initialize the class in the second parameter with the letter that the Button that fired the event represented. For the "A" Button on the page, that code would look like this:

Private Sub AButton_Click(....) Handles AButton.Click
Dim bdea As ButtonDataEventArgs
    bdea = New ButtonDataEventArgs("A")
    RaiseEvent ButtonDataEvent(Me, bdea)
End Sub

Passing Data in the Event
The last step in this process is to create the class that you'll use to pass data in the event's second parameter. Your class must inherit from System.EventArgs and normally has a set of read-only properties that the host page will read when it catches the event. Typically, you set the values made available through the read-only properties in the New method of the class.

For my reader's case, we want the ButtonDataEventArgs class to have a ButtonLetter property that would allow the host page to find out what letter was stored in the object when it was created. The opening of the ButtonDataEventArgs class with the constructor that's used to initialize the class' internal variable would look like this:

Public Class ButtonDataEventArgs
     Inherits System.EventArgs
Private _ButtonLetter As String
Public Sub New(ButtonLetter As String)
   _ButtonLetter = ButtonLetter
End Sub

The read-only property that makes the data available (and the end of the class) would look like this:

Public ReadOnly Property ButtonLetter() As String
     Return _ButtonLetter
  End Get
End Sub
End Class

Normally, I'd put this code in the User Control's file after the User Control's "End Class" line.

Identifying the Button
In my previous column, I also recommended using one event routine to handle the Click events for all 26 buttons on the page. This raises the problem of determining which button called the event. The best solution is to set each Button's CommandArgument to the letter that the button represents (e.g., "A"). Since the first parameter passed to any event is a reference to the object that fired the event, you can retrieve a reference to the Button that called the event by converting your Click event's Sender parameter to a Button. The result is code in the User Control's Click event that looks like this.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at

comments powered by Disqus


  • Python in VS Code Adds Data Viewer for Debugging

    The January 2021 update to the Python Extension for Visual Studio Code is out with a short list of new features headed by a data viewer used while debugging.

  • GitHub Ships Enterprise Server 3.0 Release Candidate

    It's described as "the biggest ever change to Enterprise Server," with improvements to Actions, Packages, mobile, security and more.

  • Attacks on .NET Apps Grow in Number, Severity, Says Security Firm

    .NET apps were found to have more serious vulnerabilities and suffer more attacks last year, according to data gathered by Contrast Labs.

  • Microsoft Opens Up Old Win32 APIs to C# and Rust, More Languages to Come

    Microsoft is opening up old Win32 APIs long used for 32-bit Windows programming, letting coders use languages of their choice instead of the default C/C++ option.

Upcoming Events