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.
Prerequisites
The article assumes a basic knowledge of routed events, and that you've read Routed events overview. To follow the examples in this article, it helps if you're familiar with Extensible Application Markup Language (XAML) and know how to write Windows Presentation Foundation (WPF) applications.
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
AddressOf
operator 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
ButtonCreatedByCode
to the already constructed XAML element tree. - Specifies properties for the new button, such as the name, content, and background color.
- Assigns the
ButtonCreatedByCode_Click
event handler toButtonCreatedByCode
. - Assigns the same
ButtonCreatedByCode_Click
event handler toStackPanel1
.
When ButtonCreatedByCode
is clicked:
- The Click routed event is raised on
ButtonCreatedByCode
. - The
ButtonCreatedByCode_Click
event handler assigned toButtonCreatedByCode
is triggered. - The
Click
routed event traverses up the element tree toStackPanel1
. - The
ButtonCreatedByCode_Click
event handler assigned toStackPanel1
is triggered. - The
Click
routed event continues up the element tree potentially triggering otherClick
event 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
sender
will beButtonCreatedByCode
the first time the handler runs, andStackPanel1
the second time. - The RoutedEventArgs.Source object, which is the element that originally raised the event. In this example, the
Source
is alwaysButtonCreatedByCode
.
Note
A key difference between a routed event and a CLR event is that a routed event traverses the element tree, looking for handlers, whereas a CLR event doesn't traverse the element tree and handlers can only attach to the source object that raised the event. 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.
See also
.NET Desktop feedback