How to add an event handler using code (WPF .NET)
You can assign an event handler to an element in Windows Presentation Foundation (WPF) using markup or code-behind. Although it's customary to assign an event handler in Extensible Application Markup Language (XAML), sometimes you might have to assign an event handler in code-behind. For instance, use code when:
- You assign an event handler to an element after the markup page that contains the element loads.
- You add an element and assign its event handler after the markup page that will contain the element loads.
- You define the element tree for your application entirely in code.
Important
The Desktop Guide documentation for .NET 6 and .NET 5 (including .NET Core 3.1) is under construction.
Syntax for event handler assignment
C# supports event handler assignment using:
- The
+=operator, which is also used in the common language runtime (CLR) event handling model. - The UIElement.AddHandler method.
VB supports event handler assignment using:
- The AddHandler statement with the AddressOf operator, which is also used in the CLR event handling model.
- The Handles keyword in the event handler definition. For more information, see Visual Basic and WPF event handling.
- The UIElement.AddHandler method, together with the
AddressOfoperator to reference the event handler.
Example
The following example uses XAML to define a Button named ButtonCreatedByXaml and to assign the ButtonCreatedByXaml_Click method as its Click event handler. Click is a built-in routed event for buttons that derive from ButtonBase.
<StackPanel Name="StackPanel1">
<Button
Name="ButtonCreatedByXaml"
Click="ButtonCreatedByXaml_Click"
Content="Create a new button with an event handler"
Background="LightGray">
</Button>
</StackPanel>
The example uses code-behind to implement the ButtonCreatedByXaml_Click and ButtonCreatedByCode_Click handlers, and to assign the ButtonCreatedByCode_Click handler to the ButtonCreatedByCode and StackPanel1 elements. Event handler methods can only be implemented in code-behind.
// The click event handler for the existing button 'ButtonCreatedByXaml'.
private void ButtonCreatedByXaml_Click(object sender, RoutedEventArgs e)
{
// Create a new button.
Button ButtonCreatedByCode = new();
// Specify button properties.
ButtonCreatedByCode.Name = "ButtonCreatedByCode";
ButtonCreatedByCode.Content = "New button and event handler created in code";
ButtonCreatedByCode.Background = Brushes.Yellow;
// Add the new button to the StackPanel.
StackPanel1.Children.Add(ButtonCreatedByCode);
// Assign an event handler to the new button using the '+=' operator.
ButtonCreatedByCode.Click += new RoutedEventHandler(ButtonCreatedByCode_Click);
// Assign an event handler to the new button using the AddHandler method.
// AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(ButtonCreatedByCode_Click);
// Assign an event handler to the StackPanel using the AddHandler method.
StackPanel1.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(ButtonCreatedByCode_Click));
}
// The Click event handler for the new button 'ButtonCreatedByCode'.
private void ButtonCreatedByCode_Click(object sender, RoutedEventArgs e)
{
string sourceName = ((FrameworkElement)e.Source).Name;
string senderName = ((FrameworkElement)sender).Name;
Debug.WriteLine($"Routed event handler attached to {senderName}, " +
$"triggered by the Click routed event raised by {sourceName}.");
}
' The click event handler for the existing button 'ButtonCreatedByXaml'.
Private Sub ButtonCreatedByXaml_Click(sender As Object, e As RoutedEventArgs)
' Create a new button and specify button properties.
Dim ButtonCreatedByCode As New Button With {
.Name = "ButtonCreatedByCode",
.Content = "New button and event handler created in code",
.Background = Brushes.Yellow
}
' Add the new button to the StackPanel.
StackPanel1.Children.Add(ButtonCreatedByCode)
' Assign an event handler to the new button using the AddHandler statement.
AddHandler ButtonCreatedByCode.Click, AddressOf ButtonCreatedByCode_Click
' Assign an event handler to the new button using the AddHandler method.
' ButtonCreatedByCode.AddHandler(ButtonBase.ClickEvent, New RoutedEventHandler(AddressOf ButtonCreatedByCode_Click))
' Assign an event handler to the StackPanel using the AddHandler method.
StackPanel1.AddHandler(ButtonBase.ClickEvent, New RoutedEventHandler(AddressOf ButtonCreatedByCode_Click))
End Sub
' The Click event handler for the new button 'ButtonCreatedByCode'.
Private Sub ButtonCreatedByCode_Click(sender As Object, e As RoutedEventArgs)
Dim sourceName As String = CType(e.Source, FrameworkElement).Name
Dim senderName As String = CType(sender, FrameworkElement).Name
Debug.WriteLine($"Routed event handler attached to {senderName}, " +
$"triggered by the Click routed event raised by {sourceName}.")
End Sub
When ButtonCreatedByXaml is clicked and its event handler runs, ButtonCreatedByXaml_Click programmatically:
- Adds a new button named
ButtonCreatedByCodeto the already constructed XAML element tree. - Specifies properties for the new button, such as the name, content, and background color.
- Assigns the
ButtonCreatedByCode_Clickevent handler toButtonCreatedByCode. - Assigns the same
ButtonCreatedByCode_Clickevent handler toStackPanel1.
When ButtonCreatedByCode is clicked:
- The Click routed event is raised on
ButtonCreatedByCode. - The
ButtonCreatedByCode_Clickevent handler assigned toButtonCreatedByCodeis triggered. - The
Clickrouted event traverses up the element tree toStackPanel1. - The
ButtonCreatedByCode_Clickevent handler assigned toStackPanel1is triggered. - The
Clickrouted event continues up the element tree potentially triggering otherClickevent handlers assigned to other traversed elements.
The ButtonCreatedByCode_Click event handler obtains the following information about the event that triggered it:
- The sender object, which is the element that the event handler is assigned to. The
senderwill beButtonCreatedByCodethe first time the handler runs, andStackPanel1the second time. - The RoutedEventArgs.Source object, which is the element that originally raised the event. In this example, the
Sourceis alwaysButtonCreatedByCode.
Note
A key difference between a routed event and a CLR event is that a routed event traverses the element tree, whereas a CLR event occurs only on the sender. As a result, a routed event sender can be any traversed element in the element tree.
For more information on how to create and handle routed events, see How to create a custom routed event and Handle a routed event.