Código para eventos de controles, asociando y separando dinámicamente con AddHandler y RemoveHandler

Código para eventos de controles, asociando y separando dinámicamente con AddHandler y RemoveHandler

Debido a que AddHandler emplea enlace tardío para conectar un procedimiento con el evento de un objeto, podemos conseguir que un mismo evento de un control, en determinados momentos ejecute un procedimiento manipulador, y en otras ocasiones otro distinto.

Esto es lo que vamos a conseguir con los RadioButton del formulario. Cuando pulsemos el control rbtFecha, el evento Click del control btnMostrar ejecutará un manipulador de evento, y cuando pulsamos el control rbtHora, el botón btnMostrar ejecutará un manipulador distinto.

En primer lugar, debemos asociar los controles RadioButton con su propio evento Click. Esto lo conseguimos mediante AddHandler, en el momento de su creación.

Una vez que pulsemos alguno de los RadioButton, se ejecutará su correspondiente método Click, y en el procedimiento manipulador de ese evento del control de radio, asociaremos al botón btnMostrar un procedimiento para su evento de pulsación. Veamos el Código fuente 468.

Public Class frmDatos '.... Public Sub New()

'.... ' RadioButton: Fecha Me.rbtFecha = New RadioButton() '.... ' asociar este RadioButton a un procedimiento ' de evento con AddHandler AddHandler Me.rbtFecha.Click, AddressOf PulsaFecha

' RadioButton: Hora Me.rbtHora = New RadioButton() '.... ' asociar este RadioButton a un procedimiento ' de evento con AddHandler AddHandler Me.rbtHora.Click, AddressOf PulsaHora '....

End Sub '.... '.... ' este manipulador de evento se producirá cuando ' se pulse el RadioButton rbtFecha Private Sub PulsaFecha(ByVal sender As Object, ByVal e As EventArgs)

' asociamos un nuevo manipulador para el botón btnMostrar AddHandler btnMostrar.Click, AddressOf MuestraFecha

End Sub

' este manipulador de evento se producirá cuando ' se pulse el RadioButton rbtHora Private Sub PulsaHora(ByVal sender As Object, ByVal e As EventArgs)

' asociamos un nuevo manipulador para el botón btnMostrar AddHandler btnMostrar.Click, AddressOf MuestraHora

End Sub

' este manipulador de evento se asociará al control btnMostrar ' cuando se pulse el RadioButton rbtFecha Private Sub MuestraFecha(ByVal sender As Object, ByVal e As EventArgs)

Dim dtFecha As Date dtFecha = DateTime.Today MessageBox.Show("Fecha actual: " & dtFecha.ToString("D"))

End Sub

Programación con Visual Basic .NET © Grupo EIDOS

' este manipulador de evento se asociará al control btnMostrar ' cuando se pulse el RadioButton rbtHora Private Sub MuestraHora(ByVal sender As Object, ByVal e As EventArgs)

Dim dtFecha As Date dtFecha = DateTime.Now MessageBox.Show("Hora actual: " & dtFecha.ToString("T"))

End Sub

End Class

Código fuente 468

Sin embargo, este modo de asignación del procedimiento manipulador, al evento Click del botón btnMostrar, tiene la siguiente pega: cada vez que pulsamos uno de los RadioButton, el manipulador del evento Click antiguo no se elimina, sino que se va apilando a los ya existentes.

Como consecuencia, cuando hayamos pulsado repetidas veces los controles de radio del formulario, se ejecutarán también repetidamente los manipuladores del evento Click de btnMostrar.

El motivo de este comportamiento se debe a que el delegado en el que está basado el evento, contiene lo que se denomina una lista de invocación, y cada vez que usamos AddHandler, se añade el nombre del procedimiento de evento a dicha lista. Si no quitamos de la lista de manipuladores de evento la referencia a un procedimiento, cada vez que se produzca el evento se ejecutarán todos los procedimientos de su lista de invocación. Para quitar un procedimiento de la lista de un evento, emplearemos la instrucción RemoveHandler.

Para que todo funcione ya correctamente, cuando pulsemos los RadioButton, en el código de los eventos de estos controles haremos un pequeño añadido, consistente en quitar al botón btnMostrar, el manipulador de evento que tenía hasta ese momento. Veámoslo en el Código fuente 469.

' este manipulador de evento se producirá cuando ' se pulse el RadioButton rbtFecha Private Sub PulsaFecha(ByVal sender As Object, ByVal e As EventArgs)

' quitamos el manipulador que hubiera para btnMostrar... RemoveHandler btnMostrar.Click, AddressOf MuestraHora

' ...y asociamos un nuevo manipulador para el botón btnMostrar AddHandler btnMostrar.Click, AddressOf MuestraFecha

End Sub

' este manipulador de evento se producirá cuando ' se pulse el RadioButton rbtHora Private Sub PulsaHora(ByVal sender As Object, ByVal e As EventArgs)

' quitamos el manipulador que hubiera para btnMostrar... RemoveHandler btnMostrar.Click, AddressOf MuestraFecha

' ...y asociamos un nuevo manipulador para el botón btnMostrar AddHandler btnMostrar.Click, AddressOf MuestraHora

End Sub

Código fuente 469

© Grupo EIDOS 30. Codificación avanzada de controles y herencia visual

Al ejecutar ahora, cuando pulsemos el control btnMostrar, sólo se ejecutará un único procedimiento manipulador de su evento Click. Esto nos proporciona de nuevo una idea de la potencia que encierra el lenguaje en esta versión de VB.