Colecciones de controles

02/06/2005 - 11:58 por yego | Informe spam
Hola de nuevo a todos.
Hoy el problema que se me plantea es el siguiente.
Estoy diseñando un formulario base al cual quiero añadir un metodo para
poder recoger los datos de ciertos controles (mis propios controles) de
forma dinamica. La idea que se me ha ocurrido es recorrerme todos los
controles que tenga el formulario e ir comprobando que se tratan de cada uno
de los tipos de mis controles. El caso es que me encuentro con la dificultad
de no poder acceder a la coleccion de controles del formulario y a ninguna
de las propiedades que en todos son distitas.

Alguna solucion mas practica?


Chas gracias.

Preguntas similare

Leer las respuestas

#11 Tristan
03/06/2005 - 12:00 | Informe spam
Hola Juan,
He buscado el tema del que me hablas y no he visto nada en el MSDN
(Macrosustitucion) cuentame algo mas.



MSDN???? Nooo, me refiero al mensaje del hilo siguiente al tuyo en este
mismo foro. El hilo tiene de título Macrosustitución. Ahí he dejado un
ejemplo de como asignar controles a un Array. Puedes usar cualquier colección
para almacenar referencias a tus controles, de forma que no sea necesario
recorrer todos los del formulario.

En un principio no puedo generar una clase base puesto que tengo varios
controles diferentes que heredan de otras clases y estan ya muy avanzados.
Lo que si que he hecho es incluir una interface y la he implementado en cada
clase de los controles (pero como Controls no lo tiene definido, siempre me
da error al compilar).



Pero no acabo de comprender. ¿Todos tus controles derivan de TextBox?. Si es
así, solo tienes que crear la clase base, y sustituir la herencia de tus
clases desde TextBox hacia tu clase base. No hay que cambiar nada, solo la
primera linea del control.

Si por el contrario, tus controles derivan de varios tipos de controles, en
los que no puedes modificar su herencia, en efecto, la solución es usar una
interface.

Lo que si que he hecho es incluir una interface y la he implementado en cada
clase de los controles (pero como Controls no lo tiene definido, siempre me
da error al compilar).



El hecho de que Controls no la tenga definido no afecta a nada. Puesto que
todas tus clases implementan la interface, una vez comprobado que el control
la implementa, solo hay que hacer un casting a esa interface:

Si todas tus clases implementan ITuInterface:

foreach (Control control in this.Controls)
{
ITuInterface tuControl = control as ITuInterface;
if (tuControl != null)
MessageBox.Show(tuControl.StrText);
}

Recuerda que para tratar todos los controles del formulario, debes utilizar
recursividad.

Lo anterior es la forma más eficiente, pero tal vez este se comprenda mejor
de esta otra forma:

foreach (Control control in this.Controls)
{
if (control is ITuInterface)
{
ITuInterface tuControl = (ITuInterface) control;
MessageBox.Show(tuControl.StrText);
}
}

Juan Carlos Badiola Saiz
MVP - C#
Respuesta Responder a este mensaje
#12 Tristan
03/06/2005 - 12:24 | Informe spam
Ahhh, y creo que es importante. Viendo la pregunta que has dejado en otro
hilo, me he dado cuenta de que el ejemplo que te dejé ayer tiene varios
errores. Es el problema de hacer las cosas de cabeza, y de pasar demasiado
tiempo con vb.net :-)

Ayer dije:

De esta forma, para recorrer el form y tratar solo tus controles:

TrataTusTextBox(Me.Controls)

void TrataTusTextBox(controles as CollectionControls)
{
foreach (Control control in controles)
{
TuBaseTextBox base = control as TuBaseTextBox;
if (base != null)
MessageBox.Show(base.StrText);
if (control.Controls.Count > 0)
TrataTusTextBox(control.Controls); // Recursividad
}
}



Lo correcto, sería:

De esta forma, para recorrer el form y tratar solo tus controles:

TrataTusTextBox(this.Controls)

private void TrataControles(Control.ControlCollection controles)
{
foreach (Control control in controles)
{
ITuInterface iControl = control as ITuInterface;
if (iControl != null)
MessageBox.Show(iControl.StrText);
if (control.Controls.Count > 0)
TrataControles(control.Controls);
}
}

Juan Carlos Badiola Saiz
MVP - C#
Respuesta Responder a este mensaje
#13 yego
03/06/2005 - 14:01 | Informe spam
Hola de nuevo Juan,
Con respecto a definirme un control como mi interface, no lo entiendo. Yo he
creado una interface que implementa una variable de solo lectura sease:
public interface IValorReal

{string ValorReal

{ get;}

}

He hecho que todos los controles la hereden y la implementan tal que:
//Implementacion de la interfaz IValorReal
public string ValorReal

{get {return this.strCuenta;}}

Y todo esto unicamente para, a la hora de acceder a los campos fuese
dinamica y estandard y utilizar un unico control. Pero esto siempre me
fallaba. Asi que al final he optado por crearme un control de cada tipo, con
lo cual creo que no haria falta la interface.
¿cual son los conceptos que no estoy teniendo en cuenta?

private string ProcessControl(Control.ControlCollection ctrlProcess)

//protected string ProcessControl_OUT(Control ctrlProcess)

{ string strCola="";

SAGLabel NEWctrlSAGLabel;

SAGCuadroTexto NEWctrlSAGCuadroTexto;

SAGCuadroImporte NEWctrlSAGCuadroImporte;

SAGCuadroFecha NEWctrlSAGCuadroFecha;

SAGCodCta NEWctrlSAGCodCta;

foreach(Control ctrl in ctrlProcess.Controls){

if (ctrl is SAGLabel){

NEWctrlSAGLabel = (SAGLabel)(ctrl);

strCola+=NEWctrlSAGLabel.ValorReal;}

if (ctrl is SAGCuadroTexto){

NEWctrlSAGCuadroTexto = (SAGCuadroTexto)(ctrl);

strCola+=NEWctrlSAGCuadroTexto.ValorReal;}

if (ctrl is SAGCuadroImporte){

NEWctrlSAGCuadroImporte= (SAGCuadroImporte)(ctrl);

strCola+=NEWctrlSAGCuadroImporte.ValorReal; }

if (ctrl is SAGCuadroFecha){

NEWctrlSAGCuadroFecha = (SAGCuadroFecha)(ctrl);

strCola+=NEWctrlSAGCuadroFecha.ValorReal;}

if (ctrl is SAGCodCta){

NEWctrlSAGCodCta = (SAGCodCta)(ctrl);

strCola+=NEWctrlSAGCodCta.ValorReal;}

if(ctrl.HasChildren==true) strCola+=ProcessControl_OUT(ctrl);

}

return strCola;

}





"Tristan" escribió en el mensaje
news:
Ahhh, y creo que es importante. Viendo la pregunta que has dejado en otro
hilo, me he dado cuenta de que el ejemplo que te dejé ayer tiene varios
errores. Es el problema de hacer las cosas de cabeza, y de pasar demasiado
tiempo con vb.net :-)

Ayer dije:

> De esta forma, para recorrer el form y tratar solo tus controles:
>
> TrataTusTextBox(Me.Controls)
>
> void TrataTusTextBox(controles as CollectionControls)
> {
> foreach (Control control in controles)
> {
> TuBaseTextBox base = control as TuBaseTextBox;
> if (base != null)
> MessageBox.Show(base.StrText);
> if (control.Controls.Count > 0)
> TrataTusTextBox(control.Controls); // Recursividad
> }
> }

Lo correcto, sería:

De esta forma, para recorrer el form y tratar solo tus controles:

TrataTusTextBox(this.Controls)

private void TrataControles(Control.ControlCollection controles)
{
foreach (Control control in controles)
{
ITuInterface iControl = control as ITuInterface;
if (iControl != null)
MessageBox.Show(iControl.StrText);
if (control.Controls.Count > 0)
TrataControles(control.Controls);
}
}

Juan Carlos Badiola Saiz
MVP - C#
Respuesta Responder a este mensaje
#14 Tristan
03/06/2005 - 16:25 | Informe spam
Con respecto a definirme un control como mi interface, no lo entiendo. Yo
he
creado una interface que implementa una variable de solo lectura sease:
public interface IValorReal

{string ValorReal

{ get;}

}



Vamos a ver, si me entero. No se puede exponer una variable en una
interface. Se pueden exponer métodos, propiedades y eventos. Las variables
de hecho no se deben exponer al exterior.

Por lo demás, no solo se puede hacer casting a clases, también se puede
hacer casting a interfaces. Si tus clases implementan la interface
IValorReal, puedes utilizar ((tuObjeto) IValorReal).ValorReal. Por supuesto,
siempre que ValorReal sea una propiedad.

¿Se comprende hasta aquí?

Si comprendes esto, fíjate bien en el ejemplo que dejé antes para recorrer
los controles. En él, recorro todos los controles del formulario,
comprobando que cumplen la interface, y visualizando la propiedad de la
interface.

Juan Carlos Badiola
MVP - C#
Respuesta Responder a este mensaje
#15 Guillermo guille
03/06/2005 - 20:05 | Informe spam
esa coleccion <System.Windows.Forms.Controls> no soporta la propiedad ahora
comun de los controles. Se que se puede resolver diciendo que solo me
recorra los de ese tipo, pero eso no es lo que quiero.



A ver, si lo que quieres es acceder a una propiedad que solo existe en tus
propios controles, ¡de alguna forma tendrás que saber que el control examinado
es de "los tuyos"!
Y no te estoy diciendo que recorras solo "tus" controles, sino todos los
controles y después hacer la "criba" para solamente examinar los que
"realmente" te interesa examinar.

Algo parecido a lo que te ha contestado Víctor, pero en lugar de un TextBox,
pues lo haces con el tipo de tu control...

Lo mismo es que no me entero de lo que quieres hacer... en fin... cosas de la
edad... je, je, je.


Nos vemos.
Guillermo
Microsoft VB MVP desde 1997
Te invito a mi sitio dedicado al VB y más...
http://www.elguille.info/
http://www.mundoprogramacion.com/
(puede que el correo usado sea anti-spam)


"yego" wrote in message
news:
Muchas gracias Super Guille.
Estoy tipando en tiempo de ejecucion pero me da un error al compilar. porque
esa coleccion <System.Windows.Forms.Controls> no soporta la propiedad ahora
comun de los controles. Se que se puede resolver diciendo que solo me
recorra los de ese tipo, pero eso no es lo que quiero.
Respecto a la recursividad del metodo, hasta que no solucione lo anterior no
lo podre probar.

Te agradezco un monton tus consejos.


Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida