Quiero mostrarles varias cosas con este ejemplo… pero la principal es como agregar eventos a un grupo de controles en tiempo de ejecución en visual basic .net.
Para el ejemplo necesitaremos un formulario con muchos controles textBox’s (no importa como se llamen). Puedes hacer algo parecido a lo que hice yo.

Cada vez que en el diseñador de visual studio le damos doble clic a un control se crea una sub rutina que será la encargada de manejar ese evento. En el caso de un cuadro de texto el evento por defecto es TextChanged y el diseñador de visual studio creará una subrutina llamada TextBox1_TextChanged pero en realidad el nombre no es importante, podríamos cambiarlo y nada pasaría. Lo importante es lo que está al final de la linea: ” Handles TextBox1.TextChanged”. Esto indica que esta rutina “manejará” el evento TextBox1.TextChanged.
Nosotros podemos asignar estos “manejadores” en tiempo de ejecución y, como en el presente ejemplo, podemos hacerlo utilizando la misma función para varios controles.
La sintaxis para gregar un manejador es:
AddHandler Objeto.Evento, AddressOf MiRutina
y para quitar un manejador:
RemoveHandler Objeto.Evento, AddressOf MiRutina
Veramos ahora el ejemplo en cuestion: en este ejemplo lo que aremos es agregar dos eventos a cada control textBox que tengamos en el formulario. Estos eventos serán GotFocus (que ocurre cuando el control toma foco) y lostFocus (que ocurre cuando el control pierde el foco). Cuando el control tiene el foco queremos que cambie su color de fondo, en este caso, a un amarillo. Y cuando lo pierde que regrese a su color normal.
Lo primero que aremos es agregar esas dos rutinas.
Private Sub conFoco(ByVal sender As Object, ByVal e As System.EventArgs)
DirectCast(sender, TextBox).BackColor = Color.Yellow
End Sub
Private Sub sinFoco(ByVal sender As Object, ByVal e As System.EventArgs)
DirectCast(sender, TextBox).BackColor = Color.White
End Sub
Listo, ya tenemos las dos rutinas, pero… nadie las llama aún. Para eso necesitamos agregar a cada control textBox del formulario un manejador que llame a estasd funciones.
En el evento Load del formulario agregamos el siguiente código:
For Each c As Object In Me.Controls
If c.GetType Is GetType(TextBox) Then
AddHandler DirectCast(c, TextBox).GotFocus, AddressOf conFoco
AddHandler DirectCast(c, TextBox).LostFocus, AddressOf sinFoco
End If
Next
Y listo, podemos probar el programa y no necesitamos nada más. Todos los textBox cambiarán su color de fondo al tomar el foco. No importa cuantos sean ni como se llamen.
en la imagen siguiente se ve el formulario en funcionamiento:

Creo que vale la pena explicar un poco el último código.
El For each recorre todos los
Información Bitacoras.com…
Valora en Bitacoras.com: Quiero mostrarles varias cosas con este ejemplo? pero la principal es como agregar eventos a un grupo de controles en tiempo de ejecución en visual basic .net. Para el ejemplo necesitaremos un formulario con muchos controles ….
¡Gracias! Codigo limpio, sencillo y funcional. Eres un fenomeno. Yo usaba los arrays de controles en VB6 para estas cosas (como las echo de menos…), pero con este truquillo queda elegantemente solucionado.
Gracias por este excelente aporte, Yo he desarrollado en VB6 hace 8 años y no habia encontrado la manera de hacer en .Net lo que hacia en VB6 con los Array de Controles, como escribir un solo Evento para todos los TexBox de un Formulario e identificar cada uno por en Index. Con tu aporte supero esta gan dificultad. GRACIAS
Hola, muy buena la explicacion. El addHandler me parece una herramienta interesante; pero tengo una duda al respecto. Yo lo utilizo en asp.net y funciona muy bien, le agrego eventos a los links que genero dinamicamente; pero solo funciona si el addHandler esta en el Load. ¿Hay alguna forma de que funcione no estando en el Load?
Gracias por todo
súper bueno este código ahorra muchas lineas, y tiempo.
Se puede hacer algo similar pero para validar el KeyPress con solo números, etc, pero de alguna forma identificando cada textbox para sabe a quien aplicarle el formato o cual debe ser de solo números, texto etc. espero haberme hecho entender.
Yo creo que si combinás lo aprendido en este artículo mas los dos de lo siguientes link lo podés hacer.
http://www.solovb.net/index.php/2009/01/25/textbox-solo-numeros-validacion/
http://www.solovb.net/index.php/2009/02/23/textbox-solo-letras-validacion/
Suerte.
yo tengo una funcion algo parecida a las que mencionas aqui pero cuando trato de agregarselas en el evento keypress no se me dice que no tiene la misma firma
Hola, me gusta tu pagina y admiro tu dedicacion en los post. Actualmente estoy estudiando en la universidad y ayuda bastante.
Saludos!
Hola excelente codigo, lo estoy aplicando pero para otro control y con otro evento, y sucede que cuando cuando le digo:
AddHandler miObjeto.evento, AddressOf miRutina
me dice que el metodo “mirutina” no tiene la misma firma que el delegado.
En tu ejemplo tu no le envias parametros en el delegado y te funciona, que puede estar pasando en mi caso ?
De antemano gracias por tu ayuda..
Es cierto, no le envío parámetros porque no hay que enviarle nada (se los enviará el control que dispare el evento), pero si hay que definirlos en el procedimiento que llamará. Por ejemplo: Private Sub MiRutina(ByVal sender As Object, ByVal e As System.EventArgs).
Suerte
Hola, este es un buen ejemplo de utilizacion de AddHandler con controles ya añadidos al formulario.
Es por eso que quiero aportar mi granito de arena añadiendo un código para agregar eventos a controles creados en tiempo de ejecución.
Un saludo.
————————————————
Private Sub PulsadoDobleClick(ByVal sender As Object, ByVal e As System.EventArgs)
MsgBox(“Has pulsado Doble Click”)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim MiCajaDeTexto As New TextBox()
MiCajaDeTexto.Name = “CajaDeTexto”
Me.Controls.Add(MiCajaDeTexto)
AddHandler Me.Controls(MiCajaDeTexto.Name).DoubleClick, AddressOf Me.PulsadoDobleClick
End Sub
Gracias por tu ayuda, Me sacaste de apuros. Vengo de VB6 y es muy diferente, leí por ahi que Microsoft pretende incluir de nuevo los arrays de controles en sus nuevas versiones de VB.NET de la misma forma que se manejaban en VB6. Eso nos facilitaria la vida a los que venimos del viejo VB6.
Excelente, yo tan solo agregaría un comentario sobre la posibilidad de asignar una función que tenga parámetros.
Excelente rutina, de gran ayuda para los que aun migramos de vb6 a .net, Gracias
‘** Uso la propiedad readonly para editar los textbox en un determinado Groupbox **’
Ejemplo en mi proyecto:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
‘ Busca en un GroupBox los textbox
For Each c As Control In Me.grpDatosPasajero.Controls
If c.GetType Is GetType(TextBox) Then
AddHandler DirectCast(c, TextBox).Enter, AddressOf conFoco
AddHandler DirectCast(c, TextBox).Leave, AddressOf sinFoco
End If
Next
End Sub
‘ Rutinas
Private Sub conFoco(ByVal sender As Object, ByVal e As System.EventArgs)
If Not DirectCast(sender,TextBox).ReadOnly Then
DirectCast(sender, TextBox).BackColor = Color.PaleGoldenrod
End If
End Sub
Private Sub sinFoco(ByVal sender As Object, ByVal e As System.EventArgs)
If Not DirectCast(sender,TextBox).ReadOnly Then
DirectCast(sender, TextBox).BackColor = Color.White
End If
End Sub
wav
Exelentes codigos amigos tengo que admitirlo jejej. en hora buena garacias . saludos a todos
Comparto este codigo que relize con la ayuda de sus notas, esto me ayudara acrear todos lo botones que necesite y mandar llamar una funcion con condiciones ligadas a el boton presionado, claro a partir de un solo evento
Public Class Form1
Dim lbls() As Button
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim loc As Integer = 25
For m As Integer = 0 To 4
ReDim Preserve lbls(m)
lbls(m) = New Button
With lbls(m)
.Text = (“Boton ” & m)
.Location = New Point(0, loc)
.Size() = New System.Drawing.Size(75, 23)
End With
lbls(m).Name = m
Me.Controls.Add(lbls(m))
AddHandler Me.Controls(lbls(m).Name).Click, AddressOf Me.Click
loc += 25
Next
End Sub
Private Sub Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim j As Button = sender
MsgBox(“Presionaste el Boton ” & j.Name)
End Sub
End Class
espero y les sirva de algo
Quiero crear un tabpage y dentro de este un datagridview en tiempo de ejecucion, y q tambien agregue estos controles en tiempo de diseno, si alguien sabe como hacerlo, agradezco su ayuda.
Quiero crear un tabpage y dentro de este un datagridview en tiempo de ejecución, y que tambien agregue estos controles a la pantalla de diseño en visual basic.net, si alguien sabe como hacerlo, agradezco su ayuda.
Holas! a todos! lo que pasa es que aca le dan propiedad a todos los textbox con:
For Each c As Object In Me.Controls
pero si kiero dar excepciones a algunos controles como los hago…por ejemplo con un boton kiero llenar mi formulario con unos txtbox para notas de alumnos pero ya hay otros txtbox como por ejemplo codigo, nombre y apellidos luego kiero promediar las notas utlizo
Dim Suma(n) As Double
Dim c As Control
For Each c In Me.Controls
If TypeOf c Is TextBox Then
Suma(Val(c.Tag)) += Val(c.Text)
End If
Next
For Each c In Me.Controls
Dim i As Integer
If TypeOf c Is Label Then
If c.Tag >= 0 Then
If Val(c.Tag) = i Then
c.Text = Suma(i) / Val(txtnn.Text)
i += 1
End If
End If
End If
pero me toma todos los txtbox y el promedio sale mal
pepelepu, intenta exluir asi :
…
For Each c In Me.Controls
select case c.Name
‘ Controles a excluir
case “nameControl1″, “nameControl2″, “nameControl3″
loop
case else
‘ Controles que quiero controlar
Suma(Val(c.Tag)) += Val(c.Text)
end select
next
Saludos, muy interesante código.
Tengo una consulta para ustedes, he elaborado un menustrip que lee los elementos desde una base de datos, no que no logro aun es asignar un handler o procedimiento de evento a cada control o elemento del menustrip recuperando los nombres del procedimiento de la bbdd tambien, alguna sugenrencia? yo utilice como base el ejemplo que pueden encontrar en el siguient url: http://www.dotnethelp.co.uk/es/vb/108413/menu_strip_vbnet
gracias por las sugerencias
Me estaba volviendo loco al no poder disparar los eventos hasta que entre aquí y leí
“En el evento Load del formulario agregamos el siguiente código:”
Solo me faltaba eso, a veces me pierdo en cosas obvias, gracias xD
Acabo de empezar con los eventos y manejadores y creo que es algo complejo(para mi), pero que bueno que haya gente que aporte su conocimiento para nosotros los que principiamos… se te agradece Eliseo y a todos los que han incluido su granito de arena.
Saludos!!
soy nuevo en esto y Me parece interesante y muy bueno tu ejemplo, como podria hacerlo publico y poderlo llamar desde cualquier formulario… gracias
oye una consulta no se si me puedes ayudar.
tengo que hacer un programa que controle a un juego con las teclas de movimiento y me gustaria saber como asignarle las teclas a los botones que puse; arriba abajo,izquierda,derecha y cuando presione la tecla el boton haga la simulacion de presionado.
Estimado, una consulta, como le puedo pasar parametros a la funcion que le indico en el addessOf, la funcion tiene un parametro (ej. IDBOTON), y para cada boton que voy creando debo buscar en BD información con el IDBOTON.
Muchas gracias por tu ayuda.
esto lo aprendí hace no mucho (1 dia) jejeje aunque pareciera tarea complicada es realmente sencillo, incluso llame la caracteristica de intervalo desde una SQLCE saludos!
Hola, muy interesante, quisiera que pudieran decirme como aplicar ese codigo para agregar eventos en tiempo de ejecución, en C#.
Gracias, tambien es para agregar el evento Click a los picturebox que he creado en tiempo de ejecución.
Gracias
Muy sencillo pero muy práctico. Muchas gracias
Hola, excelente. Tengo una pregunta, este código funciona para los controles que están directamente colocados en el formulario. Pero como hacer para que funcione para los contenedores sin necesidad de colocar en el Load del formulario un código para cada contenedor?
puedes crear una funcion recursiva para que si el control tiene controles se vuelva a llamar.
A continuación te dejo un ejemplo y quiero aclararte que no lo he probado por falta de tiempo, pero como quería contestarte aqui te lo dejo.
Usalo como base para crear tu función. Suerte.
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
recorrerContenedores(Me)
End Sub
Sub recorrerContenedores(ByVal c As Control)
If c.Controls.Count > 0 Then
recorrerContenedores(c)
Else
‘agregar Handles
End If
End Sub
Hola Estimado, queria saber si te falto una parte del documento porque al final, mientras estaba leyendo parece que ibas a explicar un poco el código y queda algo asi:
Creo que vale la pena explicar un poco el último código.
El For each recorre todos los …
Falta algo? lo podrias completar si es asi? Gracias y te felicito por el aporte que haces a la comunidad VB
hola estubo buenaso eso pero tengo un problema si te das cuenta tu proyecto funciona al cargar el form….bueno es mi problema yo no lo quiero asi yo kiero que al presionar mi boton agregar recien se empieze a funcionar lo del lost y got focus por cada textbox..porfa ayudame en eso sip reponde cuanto antes gracias…
saludosss….
No necesariamente el addHandler debe estar en el Load… puedes ponerlo donde tu quieras. Ademas de esto puedes usar (si lo necesitas) la instrucción RemoveHandler para la asociación del evento al control.
Wooow! Este ejemplo me ha sido de muchísima ayuda, te lo agradezco, de verdad. Mas claro creo que no se puede ^^ Saludos!!