Cómo agregar un controlador de eventos mediante código (WPF .NET)

Puede asignar un controlador de eventos a un elemento en Windows Presentation Foundation (WPF) mediante marcado o código subyacente. Aunque es habitual asignar un controlador de eventos en lenguaje XAML, puede que a veces tenga que asignar un controlador de eventos en el código subyacente. Por ejemplo, use código en los siguientes supuestos:

  • Asigna un controlador de eventos a un elemento después de que la página de marcado que contiene los elementos cargue.
  • Agrega un elemento y asigna su controlador de eventos después de que la página de marcado que contendrá los elementos cargue.
  • Define el árbol de elementos para la aplicación por completo en el código.

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).

Sintaxis para la asignación del controlador de eventos

C# admite la asignación de controladores de eventos mediante lo siguiente:

  • El operador +=, que también se usa en el modelo de control de eventos de Common Language Runtime (CLR).
  • El método UIElement.AddHandler .

VB admite la asignación del controlador de eventos mediante lo siguiente:

Ejemplo

En el ejemplo siguiente se usa XAML para definir una clase Button denominada ButtonCreatedByXaml y asignar el método ButtonCreatedByXaml_Click como controlador de eventos Click. Click es un evento enrutado integrado para los botones que derivan de ButtonBase.

<StackPanel Name="StackPanel1">
    <Button
        Name="ButtonCreatedByXaml" 
        Click="ButtonCreatedByXaml_Click"
        Content="Create a new button with an event handler"
        Background="LightGray">
    </Button>
</StackPanel>

En el ejemplo se usa código subyacente para implementar los controladores ButtonCreatedByXaml_Click y ButtonCreatedByCode_Click, y para asignar el controlador ButtonCreatedByCode_Click a los elementos ButtonCreatedByCode y StackPanel1. Los métodos de controlador de eventos solo se pueden implementar en código subyacente.

// 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

Cuando se hace clic en ButtonCreatedByXaml y se ejecuta su controlador de eventos, ButtonCreatedByXaml_Click hace lo siguiente mediante programación:

  1. Agrega un nuevo botón denominado ButtonCreatedByCode al árbol de elementos XAML ya construido.
  2. Especifica las propiedades del nuevo botón, como el nombre, el contenido y el color de fondo.
  3. Asigna el controlador de eventos ButtonCreatedByCode_Click a ButtonCreatedByCode.
  4. Asigna el mismo controlador de eventos ButtonCreatedByCode_Click a StackPanel1.

Cuando se hace clic en ButtonCreatedByCode sucede lo siguiente:

  1. El evento enrutado Click se genera en ButtonCreatedByCode.
  2. Se desencadena el controlador de eventos ButtonCreatedByCode_Click asociado a ButtonCreatedByCode.
  3. El evento enrutado Click recorre el árbol de elementos hasta StackPanel1.
  4. Se desencadena el controlador de eventos ButtonCreatedByCode_Click asociado a StackPanel1.
  5. El evento enrutado Click continúa hacia arriba en el árbol de elementos, lo que podría desencadenar otros controladores de eventos Click asignados a otros elementos recorridos.

El controlador de eventos ButtonCreatedByCode_Click obtiene la siguiente información sobre el evento que lo desencadenó:

  • El objeto emisor, que es el elemento al que está asociado el controlador de eventos. sender será ButtonCreatedByCode la primera vez que se ejecute el controlador, y StackPanel1 la segunda.
  • El objeto RoutedEventArgs.Source, que es el elemento que generó originalmente el evento. En este ejemplo, Source siempre es ButtonCreatedByCode.

Nota

Una diferencia clave entre un evento enrutado y un evento CLR es que un evento enrutado atraviesa el árbol de elementos, buscando controladores, mientras que un evento CLR no atraviesa el árbol de elementos, y los controladores solo se pueden adjuntar al objeto de origen que generó el evento. Como resultado, un evento enrutado sender puede ser cualquier elemento transversal en el árbol de elementos.

Para más información sobre cómo crear y controlar eventos enrutados, consulte Cómo crear un evento enrutado personalizado (WPF .NET) y Cómo: Controlar un evento enrutado.

Vea también