Control de eventos en Visual Basic y WPF (WPF .NET)

Si va a codificar en Visual Basic .NET, puede usar la palabra clave Handles específica del lenguaje para adjuntar un controlador de eventos a un objeto. El objeto puede ser una instancia de código subyacente o un elemento en lenguaje XAML. Handles se puede usar para asignar controladores de eventos para eventos de Common Language Runtime (CLR) o eventos enrutados de Windows Presentation Foundation (WPF). Sin embargo, Handles tiene algunas limitaciones de uso cuando se usa para adjuntar controladores de eventos para eventos enrutados.

Importante

La documentación de la guía de escritorio para .NET 7 y .NET 6 está en proceso de elaboración.

Requisitos previos

En el artículo se da por supuesto un conocimiento básico de los eventos enrutados y que ha leído Información general sobre eventos enrutados. Para seguir los ejemplos de este artículo, le ayudará estar familiarizado con el lenguaje XAML y saber cómo escribir aplicaciones de Windows Presentation Foundation (WPF).

Syntax

La sintaxis de una declaración Sub que usa la palabra clave Handles es: Sub <procedure name> Handles <object name>.<event name>. Esa sintaxis designa un procedimiento como el controlador de eventos que se ejecutará cuando se genere un evento especificado por <event name> en un objeto especificado por <object name>. El evento debe ser miembro de la clase del objeto o la clase base del objeto. En el ejemplo siguiente se muestra cómo adjuntar un controlador de eventos a un elemento XAML mediante Handles.

' Click event handler attached to XamlButton using Handles.
Private Sub XamlButton_Click(sender As Object, e As RoutedEventArgs) Handles XamlButton.Click

    ' Handler logic.
    Debug.WriteLine($"Click event handler attached to XamlButton using Handles.")

End Sub

Para usar Handles con un objeto definido en código subyacente, normalmente se declara el objeto mediante la palabra clave WithEvents. Para obtener más información sobre el uso de WithEvents, consulte estos ejemplos. WPF declara automáticamente todos los elementos XAML mediante Friend WithEvents. En el ejemplo siguiente se muestra cómo declarar un objeto definido en código subyacente mediante WithEvents.

' Declare a new button using WithEvents.
Dim WithEvents CodeButton As New Button With {
    .Content = "New button",
    .Background = Brushes.Yellow
}

' Click event handler attached to CodeButton using Handles.
Private Sub CodeButton_Click(sender As Object, e As RoutedEventArgs) Handles CodeButton.Click

    ' Handler logic.
    Debug.WriteLine($"Click event handler attached to CodeButton using Handles.")

End Sub

Para usar el mismo controlador para varios eventos, separe las comas de los eventos <object name>.<event name>. Por ejemplo, Sub Button_Click(sender As Object, e As RoutedEventArgs) Handles Button1.Click, Button2.Click. El orden de los eventos separados por comas es inmaterial.

Puede asignar diferentes controladores para el mismo evento con varias instrucciones Handles. El orden de las instrucciones Handles no determina el orden en que se invocan los controladores cuando se produce el evento.

Sugerencia

Para quitar un controlador que se ha agregado con Handles, llame a RemoveHandler. Por ejemplo, RemoveHandler Button1.Click, AddressOf Button1_Click.

Uso de «Handles» en una aplicación WPF

Para un objeto definido en XAML, la sintaxis del evento Handles<object name>.<event name> requiere que el elemento XAML que representa el objeto tenga una propiedad Name o x:Name. Sin embargo, no se requiere una propiedad de nombre para el elemento raíz de página XAML, para el que se puede usar el nombre Me. En el ejemplo siguiente se muestra cómo adjuntar un controlador de eventos a un elemento XAML mediante Handles.

' Loaded event handler attached to the XAML page root using Handles.
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded

    ' Handler logic.
    Debug.WriteLine($"Loaded event handler attached to Window using Handles.")

End Sub

Cuando se compila una página XAML, todos los elementos XAML con un parámetro Name o x:Name se declaran como Friend WithEvents. Como resultado, se puede usar cualquier elemento XAML con Handles.

Sugerencia

Visual Studio IntelliSense muestra los objetos que se pueden usar con Handles.

Independientemente de si asocia un controlador de eventos mediante Handles, la sintaxis de atributo XAML, la instrucción AddHandler o el método AddHandler, el comportamiento del sistema de eventos es el mismo.

Nota

No use los atributos XAML y Handles para adjuntar el mismo controlador de eventos al mismo evento; de lo contrario, se llamará dos veces al controlador de eventos para cada evento.

Limitaciones

La palabra clave Handles tiene estas limitaciones de uso:

  • Solo puede usar Handles para adjuntar un controlador de eventos a un objeto si el evento es miembro de la clase o la clase base del objeto. Por ejemplo, puede usar Handles para adjuntar un controlador de eventos Click a un botón cuya clase base ButtonBase genera el evento enrutado Click. Sin embargo, una de las características de los eventos enrutados es que atraviesan el árbol de elementos, lo que permite escuchar y controlar un evento Click en un nivel superior al elemento que lo ha generado. Un evento enrutado que un elemento primario escucha y controla se denomina evento adjunto. Handles no se puede usar para eventos adjuntos porque su sintaxis no admite especificar un agente de escucha en el árbol de elementos XAML diferente al elemento que ha generado el evento. Para asignar controladores de eventos a eventos adjuntos, se debe usar la sintaxis de atributo XAML o el método AddHandler. Para obtener más información sobre los eventos adjuntos, consulte Información general sobre eventos adjuntos y Eventos adjuntos en WPF.

  • La sintaxis Handles no admite la invocación del controlador de eventos para los eventos Handled. Para permitir que el controlador de eventos se invoque para eventos Handled, adjunte el controlador de eventos mediante el método AddHandler(RoutedEvent, Delegate, Boolean) y establezca su parámetro handledEventsToo en true.

Vea también