How to: Obtener controles de un formulario con generics

Nota: Es una pregunta recurrente en los foros de MSDN y como he tenido que contestarla en varias ocasiones, me he decidido a hacer este post para en futuras preguntas, poder referenciarlo como respuesta en lugar de contestar una y otra vez (no es que cueste demasiado pero con la edad uno se vuelve más vago :-P).

Pregunta: Cómo recorrer todos los TextBox de un formulario (incluidos los contenedores de controles) y vaciar su contenido.

Respuesta: Mediante el uso de generics, esto es tan sencillo como crear un método extensor de la clase Control, que devuelva una colección de los controles de un tipo determinado. Posteriormente, usamos esta colección para realizar alguna acción sobre cada uno de los elementos devueltos.

Método extensor:

   1: public static List<T> GetControls<T>(this Control container) where T : Control
   2: {
   3:   List<T> controls = new List<T>();
   4:   foreach (Control c in container.Controls)
   5:   {
   6:     if (c is T)
   7:       controls.Add((T)c);
   8:     controls.AddRange(GetControls<T>(c));
   9:   }
  10:   return controls;
  11: }

Básicamente recorre la colección de controles del tipo suministrado en tiempo de compilación, llamándose además recursivamente para cada control contenedor que contiene.

Cómo se usa:

   1: this.GetControls<TextBox>().ForEach(p => p.Text = string.Empty);

Se llama al método extensor para el formulario (si, un formulario hereda de ContainerControl, que a su vez hereda de ScrollableControl, y éste de Control). Dicho de otro modo, un objeto Form va a implementar también el método GetControls. En tiempo de compilación se especifica el tipo de la colección de objetos a buscar y retornar (*), y posteriormente se aplica una acción sobre cada uno de los elementos devueltos mediante el método ForEach.

(*) Evidentemente si deseamos devolver todos los botones del formulario basta sustituir TextBox por Button en el ejemplo anterior.

Por otro lado, si deseamos devolver sólo los controles contenidos dentro de un contenedor específico, por ejemplo un GroupBox, Panel o TabControl, basta con llamar al método extensor para el ese control determinado:

   1: this.GroupBox1.GetControls<TextBox>().ForEach(p => p.Text = "hola");
   2: this.Panel1.GetControls<TextBox>().ForEach(p => p.Text = string.Empty);

Para terminar, en el caso anterior sólo vaciamos el contenido del control, es decir realizamos una sola acción sobre el control. En el caso que deseemos realizar varias acciones para un control, basta con llamar a un método que reciba un parámetro del tipo deseado y realice las acciones oportunas:

   1: this.GetControls<TextBox>().ForEach(p => ApplyFormat(p));
   2:  
   3: private void ApplyFormat(TextBox text)
   4: {
   5:     text.BackColor = Color.LightGray;
   6:     text.ForeColor = Color.Red;
   7:     text.Text = "hello";
   8:     text.TextAlign = HorizontalAlignment.Center;
   9: }

O bien, utilizar un ‘Action Delegate’ para tener el código ‘inline’, ambas opciones son equivalentes.

   1: this.GetControls<TextBox>().ForEach(p => {
   2:                 p.BackColor = Color.LightGray;
   3:                 p.ForeColor = Color.Red;
   4:                 p.Text = "hello";
   5:                 p.TextAlign = HorizontalAlignment.Center;
   6:             });

Saludos y nos leemos!

Published 5/11/2010 15:34 por Lluis Franco
Archivado en: ,,,
Comparte este post:

Comentarios

# re: How to: Obtener controles de un formulario con generics

Saturday, November 06, 2010 10:21 PM por José Miguel Torres

Ahí está ese C#!! LINQ + lambdas + generics es lo más bonito que nos podia pasar!! Muy bueno ;-))

# re: How to: Obtener controles de un formulario con generics

Sunday, November 07, 2010 3:33 PM por Lluis Franco

Asias neng! Aprecio más el cumplido por venir de quien viene ;-)

# re: How to: Obtener controles de un formulario con generics

Sunday, November 07, 2010 8:27 PM por Renontio

Es lo que tiene geeks, por un lado lees articulos de algunos "fustrados" con el entorno de .NET y en cambio hay otros que demuestran su potencial.

Hay que tener libertad para elegir lo que te gusta.. y si criticas, es que demuestras tu ignorancia.

Gracias por este articulo aclaratorio y seductor.

# re: How to: Obtener controles de un formulario con generics

Monday, November 08, 2010 8:23 AM por Javier Torrecilla

Muy bueno Lluis, la verdad es que es una pregunta muy demandada en los foros jejeje!

# How to: Obtener controles de un formulario con generics II (Linq al rescate).

Monday, November 08, 2010 11:28 AM por Burbujas en .NET

Ayer Lluis escribía este gran post: How to: Obtener controles de un formulario con generics . Como bien

# re: How to: Obtener controles de un formulario con generics

Monday, November 08, 2010 11:59 AM por Lluis Franco

Gracias chavales!

De eso se trata, no? Ya hay demasiados posts en geeks sobre novedades, anuncios... en fin, todas esas cosas que pueden encontrarse por otros canales de comunicación. Prefiero postear poco, pero que al menos sea de utilidad, aunque sea a costa de menos visitas :-)