2010-12-19 1 views
7

Ich arbeite an einer Anwendung, die Objekte (im Grunde Windows Forms Steuerelemente) zur Laufzeit aus einer XML-Datei hinzufügen. Die Anwendung muss auf die hinzugefügten Objekte zugreifen.Suchen Sie ein Steuerelement in Windows Forms nach Name

Die Objekte werden in einem Panel oder in einer Groupbox hinzugefügt. Für das Panel und die Groupbox habe ich Panel.Controls ["object_name"], um auf die Objekte zuzugreifen. Dies ist nur hilfreich, wenn das Objekt direkt auf demselben Bedienfeld hinzugefügt wird. In meinem Fall enthält das Hauptfenster [pnlMain, ich habe nur Zugriff auf dieses Feld] möglicherweise ein anderes Feld und dieses Feld [pnlChild] enthält wieder ein groupbox [gbPnlChild] und das groupbox enthält eine Schaltfläche [button1, ich möchte auf diese Schaltfläche zugreifen] . Ich habe folgende Methode dafür:

Die obige Methode ist hilfreich, wenn Eltern bekannt sind. In meinem Szenario ist nur der Name des Objekts bekannt, auf das zugegriffen werden soll [button1] und nicht seine Eltern. Wie kann ich also auf dieses Objekt zugreifen, unabhängig von seinem Elternteil?

Gibt es eine Methode wie GetObject ("objName") oder etwas ähnliches?

Antwort

24

Sie die Controls.Find()-Methode des Formulars wieder einen Verweis abrufen können:

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

Beachten Sie, dass diese wieder ein Array kann die Eigenschaft Name eines Steuer mehrdeutig sein, gibt es keinen Mechanismus, der sicherstellt, dass Ein Steuerelement hat einen eindeutigen Namen. Sie müssen das selbst erzwingen.

+1

Das tun können, wird in .NET Compact Framework nicht funktionieren. –

+0

Ist die Suche nach Groß- und Kleinschreibung wichtig? –

1

Das .NET Compact Framework unterstützt Control.ControlCollection.Find nicht.

Siehe Control.ControlCollection Methods und beachten Sie, dass neben der Find-Methode kein kleines Telefonsymbol angezeigt wird.

In diesem Fall definieren Sie die folgende Methode:

// 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; 
} 

Dann ist es wie folgt verwenden:

// 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(); 

Dies funktioniert, wenn Sie wissen, was Sie sind loking.

+0

Die +1 im Ausdruck haben mich vor einem Fehler gerettet! – shipr

2

Wenn Sie in einer Benutzersteuerung sind und keinen direkten Zugang zum Containerform Sie folgende

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. 
}