jueves, 7 de mayo de 2009

Recorrido de todos los controles en un Form C# y VB.NET

Hace un tiempo trabajé en un proyecto en el cual quería "formatear" a los controles de un formulario, para poder ofrecer al usuario un "skin" o un tema a la aplicación, por ejemplo, que todos los controles 'label' de un formulario se colorearan de color azul, para eso lo tenía que hacer dinámicamente, ya que tenía varios formularios en la misma aplicación, y algunos cargados de distintos tipos de controles.

El recorrido de controles, se puede hacer de 2 maneras:

1. Recorriendo de manera Iterativa los controles de un control. En esta forma, sólo podemos recorrer los controles hijos de un control padre, por ejemplo, si tenemos un Form, y queremos aplicar este recorrido, entonces unicamente se recorrerá todos los controles que estén directamente agregados en el formulario y no dentro de otro control, es decir, si tenemos 3 controles dentro del Form: 1 Label, 1 GroupBox y 1 Button, pero el Label se encuentra dentro del Group Box, al hacer este recorrido, no afectará al Label, sino solo al Button y al GroupBox.


Suponiendo que tenemos este formulario, en este tipo de recorrido, cuando queramos recorrer todos los controles que tenemos en el Form1, solo recorreremos a GroupBox1 y a Button1.








2. Recorriendo de manera Recursiva TODOS los controles de un control. En esta forma se podrán recorrer todos y cada uno de los controles que esten dentro de un control padre, aún cuando algunos controles estén dentro de otro y éste a su vez de otro (esto se conoce como controles anidados), mientras formen parte del mismo control padre que establecemos, se hará dicho recorrido. Ésta es la mejor manera de hacerlo, cuando se trate de recorrer de manera DINÁMICA, es decir, cuando no se conoce ni dónde, ni cuántos controles vamos a recorrer. Cuando conozcamos su ubicación, o su tamaño, y sabemos que NO VA A CAMBIAR en el transcurso de vida de nuestra aplicación, entonces no conviene hacer un recorrido Recursivo de todos, sino almacenarlos en una colección y ahí hacer el recorrido, este tipo de recorrido es sobre una colección de elementos, en la cual conocemos su tamaño (esto lo explicaré mas adelante).

Código:

1. Recorriendo de manera Iterativa
  • C#
//Recorremos con un ciclo for each cada control que hay en la coleccion Controls de un objeto llamado 'control'

foreach(Control contHijo in control.Controls){


//Aqui va la lógica de lo queramos hacer, en mi ejemplo, voy a pintar de color azul el fondo de todos los controles

contHijo.BackColor = Color.Blue;

}

  • VB.NET
'Recorremos con un ciclo for each cada control que hay en la coleccion Controls de un objeto llamado 'control'
For Each contHijo As Control In control.Controls


'Aqui va la lógica de lo queramos hacer, en mi ejemplo, voy a pintar de color azul el fondo de todos los controles
contHijo.BackColor = Color.Blue

Next




2. Recorriendo de manera Recursiva

  • C#
public void RecControles(Control control) {
//Recorremos con un ciclo for each cada control que hay en la colección Controls
foreach(Control contHijo in control.Controls){
//Preguntamos si el control tiene uno o mas controles dentro del mismo con la propiedad 'HasChildren'
//Si el control tiene 1 o más controles, entonces llamamos al procedimiento de forma recursiva, para que siga recorriendo los demás controles
if (contHijo.HasChildren) this.RecControles(contHijo);
//Aqui va la lógica de lo queramos hacer, en mi ejemplo, voy a pintar de color azul el fondo de todos los controles
contHijo.BackColor = Color.Blue;
}
}

  • VB.NET
Public Sub RecControles(ByVal control As Control)

'Recorremos con un ciclo for each cada control que hay en la colección Controls
For Each contHijo As Control In control.Controls

'Preguntamos si el control tiene uno o mas controles dentro de l mismo con la propiedad 'HasChildren'
'Si el control tiene 1 o más controles, entonces llamamos al procedimiento de forma recursiva, para que siga
'recorriendo los demás controles
If contHijo.HasChildren Then Me.RecControles(contHijo)

'Aqui va la lógica de lo queramos hacer, en mi ejemplo, voy a pintar de color azul el fondo de todos los controles
contHijo.BackColor = Color.Blue

Next
End Sub

Como se dan cuenta, en el recorrido de forma recursiva, se debe hacer uso de un procedimiento que haga el recorrido (de ahí su nombre, una función [o procedimiento] que se llama a sí misma, mientras que de manera iterativa lo puedes utilizar en tu código de función o procedimiento sin necesidad de declarar otra función alterna.

Ahora bien, esto lo hace de maravilla, y está bien hacerlo cuando NO conozcamos el tamaño ni la ubicación de los controles, ya que como ven, el recorrido pasa por TODOS los controles de un cierto control, pero... y qué pasa si sólo necesito los controles 'Button' que se encuentran en un formulario que, de antemano, sé que no voy a agregar otros controles, pues entonces lo que conviene es que realices una colección de esos botones y hagas el recorrido UNICAMENTE en esos controles. La colección la puedes hacer en un Array, en un objeto Collection, etc.

4 comentarios:

  1. gracias por tu tiempo de explicación

    ResponderEliminar
  2. muy bien explicado...
    no sabes de la que me salvaste
    Graciasss

    ResponderEliminar
  3. deberias de visitar la pagina de facebook:

    http://www.facebook.com/dotnetguerrero

    http://www.facebook.com/pages/DotNet-Guerrero/296843610339870

    ahi mas informacion de este tipo y de eventos presenciales gratuitos :)

    ResponderEliminar
  4. muchas gracias!!! me sirvio de mucho

    ResponderEliminar