Visual Basic 和 WPF 事件处理
专门针对 Microsoft Visual Basic .NET 语言,您可以使用语言特定的 Handles 关键字将事件处理程序与实例关联,而不是将事件处理程序附加到特性或使用 AddHandler 方法。 但是,用于将处理程序附加到实例的 Handles 方法存在一些限制,因为 Handles 语法不支持 WPF 事件系统的一些特定路由事件功能。
在 WPF 应用程序中使用“Handles”
通过 Handles 连接到实例和事件的事件处理程序必须全部在实例的分部类声明中定义,此要求也适用于通过元素上的特性值进行分配的事件处理程序。 只能为具有 Name 属性值(或声明了 x:Name 指令)的页上的元素指定 Handles。 这是因为 XAML 中的 Name 创建实例引用,该实例引用对于支持 Handles 语法所需的实例.事件 引用格式是非常必要的。 可用于 Handles 且没有 Name 引用的唯一元素是定义分部类的根元素实例。
您可以通过使用逗号分隔 Handles 后面的实例.事件 引用,来向多个元素分配相同的处理程序。
可以使用 Handles 将多个处理程序分配给相同的实例.事件 引用。 不要对处理程序在 Handles 引用中的指定顺序赋予任何重要性;您应假定可以以任何顺序调用处理相同事件的处理程序。
若要移除声明中使用 Handles 添加的处理程序,请调用 RemoveHandler。
可以使用 Handles 附加路由事件的处理程序,但前提是将处理程序附加到在其成员表中定义要处理的事件的实例。 对于路由事件,使用 Handles 附加的处理程序遵循的路由规则与附加为 XAML特性或使用 AddHandler 公共签名附加的处理程序遵循的路由规则相同。 这意味着如果事件已标记为已处理(事件数据中的 Handled 属性为 True),则在响应该事件实例时不会调用使用 Handles 附加的处理程序。 可以通过路由中的另一个元素上的实例处理程序,或者路由中的当前元素或更早元素上的类处理将事件标记为已处理。 对于支持成对隧道/冒泡事件的输入事件,隧道路由可能已经将事件对标记为已处理。 有关路由事件的更多信息,请参见路由事件概述。
用于添加处理程序的“Handles”的限制
Handles 无法为附加事件引用处理程序。 您必须对该附加事件使用 add 访问器方法,或使用 XAML 中的类型名称.事件名称 事件特性。 有关详细信息,请参见路由事件概述。
对于路由事件,只能使用 Handles 为该事件存在于实例成员表中的实例分配处理程序。 但是,对于一般的路由事件,父元素可以是来自子元素的事件的侦听器,即使该父元素的成员表中没有此事件也是如此。 在特性语法中,这可以通过类型名称.成员名称 特性形式来指定,此形式限定哪种类型实际定义要处理的事件。 例如,某个父 Page(未定义 Click 事件)可以通过分配 Button.Click 形式的特性处理程序来侦听按钮单击事件。 但 Handles 不支持类型名称.成员名称 形式,因为它必须支持与该形式冲突的实例.事件 形式。 有关详细信息,请参见路由事件概述。
Handles 无法附加针对标记为已处理的事件而调用的处理程序, 而必须使用代码并调用 AddHandler(RoutedEvent, Delegate, Boolean) 的 handledEventsToo 重载。
注意 |
---|
在 XAML 中为相同事件指定事件处理程序时,不要在 Visual Basic 代码中使用 Handles 语法。在这种情况下,将调用事件处理程序两次。 |
WPF 如何实现“Handles”功能
编译Extensible Application Markup Language (XAML) 页时,中间文件会声明对设置了 Name 属性(或声明了 x:Name 指令)的页中每个元素的 Friend WithEvents 引用。 每个命名实例都可能是可以通过 Handles 分配给处理程序的元素。
注意 |
---|
在 Microsoft Visual Studio 中,IntelliSense 可以向您显示元素可用于页中的 Handles 引用的完成状态。但是,这可能需要进行一次编译,以便中间文件可以填充所有 Friends 引用。 |