如何使用代码添加事件处理程序(WPF .NET)
可以通过标记或后台代码为 Windows Presentation Foundation(WPF)中的元素分配事件处理程序。 虽然在可扩展应用程序标记语言(XAML)中分配事件处理程序是习惯性的,但有时可能需要在后台代码中分配事件处理程序。 例如,在以下情况下使用代码:
- 在包含该元素的标记页加载之后,再将事件处理程序分配给元素。
- 在包含该元素的标记页加载后,添加一个元素并分配它的事件处理程序。
- 完全在代码中为应用程序定义元素树。
先决条件
本文假定读者对路由事件有基本的了解,并且已阅读 路由事件概述。 若要遵循本文中的示例,如果你熟悉可扩展应用程序标记语言(XAML),并且知道如何编写 Windows Presentation Foundation (WPF) 应用程序,则它很有帮助。
事件处理程序赋值的语法
C# 支持使用以下方法分配事件处理程序:
+=
运算符,该运算符也用于公共语言运行时 (CLR) 事件处理模型。- UIElement.AddHandler 方法。
VB 支持使用以下方法分配事件处理程序:
- 带有 AddressOf 运算符的 AddHandler 语句,该运算符也用于 CLR 事件处理模型中。
- 事件处理程序定义中,处理 关键字。 有关详细信息,请参阅 Visual Basic 和 WPF 事件处理。
- UIElement.AddHandler 方法与
AddressOf
运算符配合使用以引用事件处理程序。
例
以下示例使用 XAML 定义名为 ButtonCreatedByXaml
的 Button,并将 ButtonCreatedByXaml_Click
方法分配为其 Click 事件处理程序。 Click
是派生自 ButtonBase的按钮的内置路由事件。
<StackPanel Name="StackPanel1">
<Button
Name="ButtonCreatedByXaml"
Click="ButtonCreatedByXaml_Click"
Content="Create a new button with an event handler"
Background="LightGray">
</Button>
</StackPanel>
该示例使用代码隐藏来实现 ButtonCreatedByXaml_Click
和 ButtonCreatedByCode_Click
处理程序,并将 ButtonCreatedByCode_Click
处理程序分配给 ButtonCreatedByCode
和 StackPanel1
元素。 事件处理程序方法只能在后台代码中实现。
// 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
当单击 ButtonCreatedByXaml
时并运行其事件处理程序,ButtonCreatedByXaml_Click
将通过编程方式进行操作:
- 将名为
ButtonCreatedByCode
的新按钮添加到已构造的 XAML 元素树。 - 指定新按钮的属性,例如名称、内容和背景色。
- 将
ButtonCreatedByCode_Click
事件处理程序分配给ButtonCreatedByCode
。 - 将同一
ButtonCreatedByCode_Click
事件处理程序分配给StackPanel1
。
单击 ButtonCreatedByCode
时:
ButtonCreatedByCode
上引发 Click 路由事件。- 分配给
ButtonCreatedByCode
的事件处理程序ButtonCreatedByCode_Click
被触发。 Click
路由事件在元素树中向上遍历,到StackPanel1
。- 分配给
StackPanel1
的ButtonCreatedByCode_Click
事件处理程序被触发。 Click
路由事件在元素树上继续向上传递,可能会触发其他遍历元素上分配的Click
事件处理程序。
ButtonCreatedByCode_Click
事件处理程序获取有关触发它的事件的以下信息:
- 发送方 对象,该对象是事件处理程序分配给的元素。 首次运行时,
sender
将会是ButtonCreatedByCode
,第二次运行时则为StackPanel1
。 - RoutedEventArgs.Source 对象,该对象是最初引发事件的元素。 在此示例中,
Source
始终ButtonCreatedByCode
。
注意
路由事件和 CLR 事件之间的一个关键区别在于,路由事件遍历元素树,查找处理程序,而 CLR 事件不会遍历元素树,处理程序只能附加到引发事件的源对象。 因此,路由事件 sender
可以是元素树中的任何遍历元素。
有关如何创建和处理路由事件的详细信息,请参阅 如何创建自定义路由事件 和 处理路由事件。