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


  • AI for GitHub Collaboration? Maybe Not So Much

    No doubt GitHub Copilot has been a boon for developers, but AI might not be the best tool for collaboration, according to developers weighing in on a recent social media post from the GitHub team.

  • Visual Studio 2022 Getting VS Code 'Command Palette' Equivalent

    As any Visual Studio Code user knows, the editor's command palette is a powerful tool for getting things done quickly, without having to navigate through menus and dialogs. Now, we learn how an equivalent is coming for Microsoft's flagship Visual Studio IDE, invoked by the same familiar Ctrl+Shift+P keyboard shortcut.

  • .NET 9 Preview 3: 'I've Been Waiting 9 Years for This API!'

    Microsoft's third preview of .NET 9 sees a lot of minor tweaks and fixes with no earth-shaking new functionality, but little things can be important to individual developers.

  • Data Anomaly Detection Using a Neural Autoencoder with C#

    Dr. James McCaffrey of Microsoft Research tackles the process of examining a set of source data to find data items that are different in some way from the majority of the source items.

  • What's New for Python, Java in Visual Studio Code

    Microsoft announced March 2024 updates to its Python and Java extensions for Visual Studio Code, the open source-based, cross-platform code editor that has repeatedly been named the No. 1 tool in major development surveys.

Subscribe on YouTube