Principales respuestas
¿Cómo invocar un evento de un control interno de un UserControl?

Pregunta
-
Buenas...
Recientemente aprendí a trabajar con controles compuestos y he estado creando algunos. Ahora, necesito saber cómo accedo a los eventos predeterminados de los controles internos. Por ejemplo, tengo un UserControl con tres Buttons; uno de ellos es para cerrar el formulario. En su caso, sencillamente debo escribir la línea Me.ParentForm.Close() dentro del evento Click del botón, en el código del UserControl, pues será una constante en cada formulario. Ahora bien, los otros dos botones son para guardar datos en una tabla, pero dependiendo del formulario, la tabla será distinta. Así pues, necesito manipular el evento Click de esos otros botones en cada formulario, y ajustar su código según la tabla destino. Pues bien, eso es justo lo que no sé hacer.
Intente con algo así:
Private Sub Buttons_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserControl1.Button1.Click
Pero eso no es admisible. Noté que puedo usar el evento Click solo para el control compuesto como tal, pero no para sus controles internos, aunque declaré Public los botones.
Así pues, necesito su orientación. ¿Cómo puedo invocar esos eventos?
Siempre hay algo que aprender...
Respuestas
-
Para ello, tienes que declarar un evento Public a nivel de la clase UserControl, y desencadenarlo en el evento Click de cada uno de los controles Button existentes en el control de usuario:
Public Class MyUserControl
' Declaramos el evento
Public Event ButtonClick As EventHandlerPrivate Sub Button1_Click( _
ByVal sender As Object, _
ByVal e As EventArgs) Handles Button1.Click' Desencadenamos el evento
RaiseEvent ButtonClick(sender, e)End Sub
Private Sub Button2_Click( _
ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button2.Click' Desencadenamos el evento
RaiseEvent ButtonClick(sender, e)End Sub
End Class
Ahora, en el formulario donde hayas insertado tu control de usuario, tendrías que detectar el evento «ButtonClick» que pertenece al propio control de usuario:
Public Class Form1
Private Sub MyUserControl1_ButtonClick( _
ByVal sender As Object, ByVal e As System.EventArgs) _
Handles MyUserControl1.ButtonClick' Referenciamos el control Button que ha desencadenado
' el evento.
'
Dim btn As Button = DirectCast(sender, Button)' Obtenemos el valor de su propiedad Name
'
MessageBox.Show(btn.Name)
End Sub
End Class
Enrique Martínez [MS MVP - VB]- Propuesto como respuesta Enrique M. MontejoModerator domingo, 31 de octubre de 2010 8:04
- Marcado como respuesta Jeison Friedman domingo, 31 de octubre de 2010 20:20
Todas las respuestas
-
Para ello, tienes que declarar un evento Public a nivel de la clase UserControl, y desencadenarlo en el evento Click de cada uno de los controles Button existentes en el control de usuario:
Public Class MyUserControl
' Declaramos el evento
Public Event ButtonClick As EventHandlerPrivate Sub Button1_Click( _
ByVal sender As Object, _
ByVal e As EventArgs) Handles Button1.Click' Desencadenamos el evento
RaiseEvent ButtonClick(sender, e)End Sub
Private Sub Button2_Click( _
ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button2.Click' Desencadenamos el evento
RaiseEvent ButtonClick(sender, e)End Sub
End Class
Ahora, en el formulario donde hayas insertado tu control de usuario, tendrías que detectar el evento «ButtonClick» que pertenece al propio control de usuario:
Public Class Form1
Private Sub MyUserControl1_ButtonClick( _
ByVal sender As Object, ByVal e As System.EventArgs) _
Handles MyUserControl1.ButtonClick' Referenciamos el control Button que ha desencadenado
' el evento.
'
Dim btn As Button = DirectCast(sender, Button)' Obtenemos el valor de su propiedad Name
'
MessageBox.Show(btn.Name)
End Sub
End Class
Enrique Martínez [MS MVP - VB]- Propuesto como respuesta Enrique M. MontejoModerator domingo, 31 de octubre de 2010 8:04
- Marcado como respuesta Jeison Friedman domingo, 31 de octubre de 2010 20:20
-
Muuuuuchas gracias otra vez Sr. Enrique! Ud sí que es un maestro! Y qué bueno que sea tan solidario. Es justo lo que necesitaba saber. Con todo, le hice algunos cambios para sintetizar el código, y queda funcionando igual.
Public Event ButtonClick As EventHandler Private Sub RecordButtons_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles _ butCancelar.Click, butAceptar.Click, butEliminar.Click If sender Is butCancelar Or sender Is butAceptar Then Me.ParentForm.Close() RaiseEvent ButtonClick(sender, e) End Sub
En este caso, asocié todos los botones al mismo evento. Total, lo que me interesa es que devuelvan su ID (sender) en el evento ButtonClick, y así lo hacen.
Y en el ParentForm:
Private Sub RecordButtons_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UserControl1.ButtonClick Select Case sender.name Case "butAceptar" 'Código aquí Case "butEliminar" 'Código aquí End Select End Sub
Y listo.
Gracias otra vez Enrique! :D
Siempre hay algo que aprender... -
"Jason Friedman" escribió:
> Y en el ParentForm:
>
> Private Sub RecordButtons_Click(ByVal sender As System.Object,
> ByVal e As System.EventArgs) Handles UserControl1.ButtonClick
> Select Case sender.name
> Case "butAceptar"
> 'Código aquí
> Case "butEliminar"
> 'Código aquí
> End Select
> End Sub
>
> Y listo.¡Ay, ay, ay! ¡Que se ve que no tienes activada la instrucción Option Strict!
Si estás comenzando a utilizar Visual Basic .NET, hazme caso y acostúmbrate a hacer las conversiones entre tipos de datos de manera explícita. Esto se consigue activando la instrucción Option Strict, en el módulo o a nivel del proyecto completo. Al final te alegrarás de haberlo hecho.
Fíjate que el parámetro «sender» del procedimiento está definido con el tipo de dato «Object», que es el tipo genérico de dato de donde heredan, directamente o indirectamente, todos los tipos de datos de .NET. Éste tipo de dato o clase, no tiene ninguna propiedad llamada «Name», pero a tí te funciona porque al tener desactivada la instrucción Option Strict, se convierte implícitamente la clase Object en una clase String mediante un enlace en tiempo de ejecución, enlaces éstos que pueden ser catastróficos si no se sabe muy bien lo que se está haciendo.
Para no complicarse uno la vida y arriesgarse a obtener resultados no esperados, o peor aún, a excepciones de error de difícil depuración, hay que convertir explícitamente los datos utilizando los operadores de conversión DirectCast, CType o TryCast.
Por ejemplo, si tu sabes que al evento RecordButtons_Click solo lo va a llamar el evento Click de un control Button, lo que tienes que hacer es convertir el parámetro Object en un tipo de dato Button, porque ese parámetro Object, mantiene la referencia del objeto Button que ha desencadenado el evento. Y esto se consigue de la siguiente manera:
' Referenciamos el control Button que ha desencadenado
' el evento.
'
Dim btn As Button = DirectCast(sender, Button)Ahora ya tienes un objeto de la propia clase Button, y ésta clase sí dispone de una propiedad llamada Name, que si lo deseas, podrás utilizarla en la instrucción Select Case:
Select Case btn.Name
Case "butAceptar"
'Código aquí
Case "butEliminar"
'Código aquí
End SelectA lo mejor crees que es una tontería. Me da igual que lo creas, pero la experiencia me indica que es la manera correcta de trabajar.
Fíjate si es importante la instrucción Option Strict, que si todo el mundo la utilizara, o al menos, una gran mayoría de usuarios, no habría tantas preguntas en el foro donde nos encontramos. :-)
Enrique Martínez [MS MVP - VB]- Propuesto como respuesta Enrique M. MontejoModerator lunes, 1 de noviembre de 2010 8:14
-
No claro! Si de algo estoy consciente es de su amplia experiencia en este ramo, por lo que sus sugerencias me son de mucha importancia.
Eso de Option Strict no lo había visto, y no sabía que se activaba o desactivaba. Supongo que yo lo tengo desactivado. De todos modos, me parece bien su sugerencia, y tendré que corregir muchas líneas de código que tengo sin tomar en cuenta ese detalle.
Gracias de nuevo!
Siempre hay algo que aprender... -