2010-12-19 19 views
7

Estoy trabajando en una aplicación que agrega objetos (básicamente controles Windows Forms) en tiempo de ejecución desde un archivo XML. La aplicación necesita acceder a los objetos que se han agregado.Buscar un control en Windows Forms por nombre

Los objetos se agregan en un panel o en un cuadro de grupo. Para el panel y groupbox, tengo Panel.Controles ["object_name"] para acceder a los objetos. Esto solo es útil cuando el objeto se agrega directamente en el mismo panel. En mi caso, el panel principal [pnlMain, tengo acceso a este panel solamente] puede contener otro panel y este panel [pnlChild] nuevamente contiene un cuadro de grupo [gbPnlChild] y el cuadro de grupo contiene un botón [button1, quiero acceder a este botón] . Tengo el siguiente método para esto:

Panel childPanel = pnlMain.Controls["pnlChild"]; 
GroupBox childGP = childPanel.Controls["gbPnlChild"]; 
Button buttonToAccess = childGP["button1"]; 

El método anterior es útil cuando se conocen los padres. En mi caso, solo se conoce el nombre del objeto al que se debe acceder [button1] y no sus padres. Entonces, ¿cómo puedo acceder a este objeto por su nombre, independientemente de su padre?

¿Hay un método como GetObject ("objName") o algo similar?

Respuesta

24

Puede utilizar el método de la forma Controls.Find() para recuperar una referencia posterior:

 var matches = this.Controls.Find("button2", true); 

Mira que este devuelve un gama, la propiedad Name de un control puede ser ambiguo, no existe un mecanismo que asegure que un control tiene un nombre único. Tendrás que hacer cumplir eso por ti mismo.

+1

El no va a funcionar en el .NET Compact Framework. –

+0

¿Es una búsqueda sensible a mayúsculas y minúsculas? –

1

.NET Compact Framework no es compatible con Control.ControlCollection.Find.

Consulte Control.ControlCollection Methods y tenga en cuenta que no hay un pequeño icono de teléfono junto al método Find.

En ese caso, defina el siguiente método:

// Return all controls by name 
// that are descendents of a specified control. 

List<T> GetControlByName<T>(
    Control controlToSearch, string nameOfControlsToFind, bool searchDescendants) 
    where T : class 
{ 
    List<T> result; 
    result = new List<T>(); 
    foreach (Control c in controlToSearch.Controls) 
    { 
     if (c.Name == nameOfControlsToFind && c.GetType() == typeof(T)) 
     { 
      result.Add(c as T); 
     } 
     if (searchDescendants) 
     { 
      result.AddRange(GetControlByName<T>(c, nameOfControlsToFind, true)); 
     } 
    } 
    return result; 
} 

luego usarlo como esto:

// find all TextBox controls 
// that have the name txtMyTextBox 
// and that are descendents of the current form (this) 

List<TextBox> targetTextBoxes = 
    GetControlByName<TextBox>(this, "txtMyTextBox", true); 
3
TextBox txtAmnt = (TextBox)this.Controls.Find("txtAmnt" + (i + 1), false).FirstOrDefault(); 

Esto funciona cuando se sabe lo que está buscando el.

+0

¡El +1 en la expresión me salvó de un error! – shipr

2

Si se encuentra en un control de usuario y no tiene acceso directo a la forma de contenedor que puede hacer lo siguiente

var parent = this.FindForm(); // returns the object of the form containing the current usercontrol. 
var findButton = parent.Controls.Find("button1",true).FirstOfDefault(); 
if(findButton!=null) 
{ 
    findButton.Enabled =true; // or whichever property you want to change. 
} 
Cuestiones relacionadas