Wpf - Crear un evento enrutado

Descripción general

En este documento se explica que es un evento enrutado y como se declaran y usan.

[TOC] Tabla de Contenidos


↑↑↑

1 Crear un evento enrutado

Cuando se diseñan controles puede ser interesante crear un evento enrutado, de forma que se compote como el reto de eventos de los controles ( que, evidentemente, son todos enrutados.)


↑↑↑

1.1 ¿Qué es un evento enrutado?

Copiado de.:

Puede considerar los eventos enrutados desde dos perspectivas: funcional y de implementación. Aquí se presentan ambas definiciones, ya que algunas personas encuentran que una es más útil que la otra.

Definición funcional: un evento enrutado es un tipo de evento que puede invocar controladores o varios agentes de escucha en un árbol de elementos, en lugar de simplemente en el objeto que lo desencadenó.

Definición de implementación: Un evento enrutado es un evento CLR que está respaldado por una instancia de la clase RoutedEvent y que es procesado por el sistema de eventos de Windows Presentation Foundation (WPF).

Una aplicación típica de WPF contiene muchos elementos. Tanto si se crean en código como si se declaran en XAML, estos elementos se relacionan entre sí a través de un árbol de elementos. En función de la definición del evento, la ruta de eventos puede viajar en cualquiera de las dos direcciones, pero generalmente viaja partiendo del elemento de origen y, a continuación, "se propaga" en sentido ascendente por el árbol de elementos hasta que llega a la raíz (normalmente una página o una ventana). Puede que le resulte familiar el concepto de propagación si ha trabajado previamente con el modelo de objetos de DHTML.

Considere el siguiente árbol de elementos simple:

<Border Height="50" Width="300" BorderBrush="Gray" BorderThickness="1">

  <StackPanel Background="LightGray" Orientation="Horizontal" 
              Button.Click="CommonClickHandler">
    <Button Name="YesButton"    Width="Auto" >Yes   </Button>
    <Button Name="NoButton"     Width="Auto" >No    </Button>
    <Button Name="CancelButton" Width="Auto" >Cancel</Button>
  </StackPanel>

</Border>

Este árbol de elementos genera algo parecido a lo siguiente:

Imagen ruta que sigue un evento enrutado

En este árbol de elementos simplificado, el origen de un evento Click es uno de los elementos Button y el elemento Button en el que se hizo clic es el primer elemento que tiene la oportunidad de controlar el evento. Pero si ninguno de los controladores asociados a Button actúa sobre el evento, este se propagará hacia arriba hasta el elemento primario de Button en el árbol de elementos, que es StackPanel. Potencialmente, el evento se propaga hasta Border y, a continuación, continúa hacia la raíz de la página en el árbol de elementos (que no se muestra).

En otras palabras, la ruta de eventos para este evento Click es:

Botón-->StackPanel-->Borde-->...

↑↑↑

1.2 Cómo se implementan los eventos enrutados

Un evento enrutado es un evento de CLR que está respaldado por una instancia de la clase RoutedEvent y registrado en el sistema de eventos de WPF. La instancia de RoutedEvent obtenida del registro normalmente se retiene como un miembro del campo publicstaticreadonly de la clase que registra y, por tanto, es la "propietaria" del evento enrutado. La conexión con el evento de CLR del mismo nombre (que a veces se denomina el evento "contenedor") se logra reemplazando las implementaciones add y remove para el evento de CLR. Lo normal es que add y remove se dejen como un valor predeterminado implícito que usa la sintaxis de eventos específica del lenguaje adecuado para agregar y quitar controladores de ese evento. El mecanismo de conexión y de respaldo de los eventos enrutados es conceptualmente similar al modo en que una propiedad de dependencia es una propiedad de CLR respaldada por la clase DependencyProperty y registrada en el sistema de propiedades de WPF.


↑↑↑

1.3 Ejemplo de implementación

¡¡¡ Atención!!!


↑↑↑

1.3.1 Un evento SelectionChanged

#Region " Evento SelectionChanged "

    '---------------------------------------------------------------
    ' Crea un evento personalizado
    ' primero se registra como RoutedEventID
    ' la estrategia de enrutado es [ RoutingStrategy.Bubble]
    '---------------------------------------------------------------
    Public Shared ReadOnly SelectionChangedEvent As RoutedEvent =
                           EventManager.RegisterRoutedEvent(
                                        "SelectionChanged", 
                                        RoutingStrategy.Bubble, 
                                        GetType(SelectionChangedEventArgs), 
                                        GetType(UC_OpcionCambioNombre))

    ' Provide CLR accessors for the event
    Public Custom Event SelectionChanged As RoutedEventHandler
       AddHandler(ByVal value As RoutedEventHandler)
           Me.AddHandler(SelectionChangedEvent, value)
       End AddHandler

       RemoveHandler(ByVal value As RoutedEventHandler)
           Me.RemoveHandler(SelectionChangedEvent, value)
       End RemoveHandler

       RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs)
           Me.RaiseEvent(e)
       End RaiseEvent
    End Event


    ''' <summary>
    ''' Dispara el evento SelectionChanged
    ''' </summary>
    Protected Sub RaiseLocalSelectionChangedRoutedEvent()
        Dim newEventArgs As New RoutedEventArgs(UC_OpcionCambioNombre.SelectionChangedEvent)
        MyBase.RaiseEvent(newEventArgs)
    End Sub


    ''' <summary>
    ''' Dispara el evento SelectionChanged con mas información
    ''' </summary>
    Protected Sub OnSelectionChanged()

        '------------------------------------------
        ' Aquí se incluyen los elementos que antes estaban seleccionados y ahora no
        Dim elementosSeleccionadosViejos As New List(Of ComboOpcionElegidaE)
        elementosSeleccionadosViejos.Add(_OpcionComboElegidaVieja)

        ' Aquí se incluyen los elementos que ahora están seleccionados 
        Dim elementosSeleccionadosNuevos As New List(Of ComboOpcionElegidaE)
        elementosSeleccionadosNuevos.Add(_OpcionComboElegidaNueva)

        ' el evento [SelectionChangedEventArgs] que trasportará esa información
        Dim localSelectionChangedEventArgs As New SelectionChangedEventArgs(SelectionChangedEvent, elementosSeleccionadosViejos, elementosSeleccionadosNuevos)

        ' disparar el evento [SelectionChanged] con toda la información 
        MyBase.RaiseEvent(localSelectionChangedEventArgs)
    End Sub

#End Region

1.3.1.1 Código XAML,

Se incluye en control personalizado en la ventana, y después del tamaño y demás características se declarar el evento [SelectionChanged ] y la función que lo tratara

<local:UC_OpcionCambioNombre x:Name="UC_OpcionCambioNombre" 
                             HorizontalAlignment="Left"
                             VerticalAlignment="Top" 
                             Margin="20,10,0,0"   
                             Width="177" Height="78" 
                             SelectionChanged="UC_OpcionCambioNombre_SelectionChanged"  />

1.3.1.2 La función que trata el evento

La forma de usar (interceptor este evento por el objeto contenedor es la siguiente:

Private Sub UC_OpcionCambioNombre_SelectionChanged(sender As Object, e As RoutedEventArgs)

    '---------------------------------------------------
    ' marcar que me ocupo aquí de tratar el evento 
    ' y que no tiene que seguir 'subiendo' por el árbol de elementos
    e.Handled = True

    '---------------------------------------------------
    ' Opción Uno de tratar el evento
    ' recuperar el control que disparo el evento
    ' recuperar la propiedad que me interesa y tratarla
    Dim auxSender As UC_OpcionCambioNombre
    auxSender = CType(sender, UC_OpcionCambioNombre)
    Dim op As ComboOpcionElegidaE = auxSender.OpcionElegida
    textBoxOpcionElegida.Text = CType(op, String)


    '---------------------------------------------------
    ' Opción Dos de tratar el evento
    ' recuperar la información a través de [SelectionChangedEventArgs]
    ' recuperando las opciones de seleccionadas y las nuevas seleccionadas
    Dim evento As System.Windows.Controls.SelectionChangedEventArgs = CType(e, SelectionChangedEventArgs)
    Me.textBoxAntes.Text = evento.AddedItems.Item(0).ToString
    Me.textBoxDespues.Text = evento.RemovedItems.Item(0).ToString

End Sub

↑↑↑

1.4 Otro ejemplo de evento enrutado

1.4.1 Un evento textChanged

#Region " Evento TextChanged "

    Public Shared ReadOnly TextChangedEvent As RoutedEvent =
                                              EventManager.RegisterRoutedEvent("TextChanged", 
                                                                               RoutingStrategy.Bubble, 
                                                                               GetType(TextChangedEventArgs), 
                                                                               GetType(UC_OpcionCambioNombre))

            Public Custom Event TextChanged As RoutedEventHandler
            AddHandler(ByVal value As RoutedEventHandler)
            Me.AddHandler(TextChangedEvent, value)
            End AddHandler

            RemoveHandler(ByVal value As RoutedEventHandler)
            Me.RemoveHandler(TextChangedEvent, value)
            End RemoveHandler

            RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs)
            Me.RaiseEvent(e)
            End RaiseEvent
            End Event


            'Este método dispara el evento enrutado TextChanged
            Protected Sub RaiseLocalTextChangedRoutedEvent()
                Dim newEventArgs As New RoutedEventArgs(UC_OpcionCambioNombre.TextChangedEvent, Me)
                MyBase.RaiseEvent(newEventArgs)
            End Sub

#End Region

1.4 Bibliografía


↑↑↑

A.2.Enlaces

[Para saber mas]
[Grupo de documentos]
[Documento Index]
[Documento Start]
[Imprimir el Documento]
© 1997 - - La Güeb de Joaquín
Joaquín Medina Serrano
Ésta página es española

Codificación
Fecha de creación
Última actualización
[HTML5 Desarrollado usando CSS3]