2009-09-23 7 views
1

SO c'est une question stupide. J'ai ajouté un tas de zones de texte à une boîte de dialogue d'options dans une application que j'ai écrite. Ils sont nommés textbox1 - textbox12. Existe-t-il un moyen d'accéder aux noms par programme? Je voudrais juste les parcourir dans une boucle for. En ce moment j'accède à chacun individuellement (frémit!). Je sais que c'est la mauvaise façon. Quelle est la bonne façon? quel est le moyen facile?Comment faire pour contrôler des contrôles dans une application de formulaire Windows?

Merci

Répondre

2

Personnellement, je préfère créer les contrôles et les programatically mettre dans une collection. c'est-à-dire

IList<TextBox> textBoxes = new List<TextBox>(); 

… 

    for (int i = 0; i < 12; i += 1) 
    { 
     TextBox textBox = new TextBox(); 
     textBox.Position = new Point(FormMargin, FormMargin + (i * (textBox.Height + TextBoxPadding))); 
     this.Controls.Add(textBox); 
     this.textBoxes.Add(textBox); 
    } 

Vous pouvez alors juste parcourir les textBoxes pour les ajouter par programme. Je trouve ces échelles meilleures quand vous avez plusieurs groupes différents de boîtes de texte avec lesquelles vous devez faire cela.

+0

Je savais que c'était comme ça que je devais le faire. C'est ce que j'aurais dû faire depuis le début. MERCI!!!! –

8
foreach (Control c in this.Controls) 
{ 
    if (c is TextBox) 
    { 
     // your logic here 
    } 
} 

Si elles ont des fonctionnalités différentes, alors vous pouvez avoir besoin de contrôles que de déterminer qu'ils sont le bon type. Et bien sûr, cela suppose que vous avez importé l'espace de noms System.Windows.Forms.

+0

+1 Vous basculez. Plus simple que je ne l'imaginais même. WOOT, –

+2

Content de vous aider. Je suis sûr qu'il y a une façon vraiment cool de le faire, mais je ne suis pas encore un pro de LINQ. J'aimerais voir quelqu'un d'autre contribuer un si c'est faisable ... –

2

Vous pouvez écrire une fonction qui le fait de manière plus générique.

IEnumerable<T> GetChildren<T>(Control owner) 
{ 
    foreach (Control c in owner.Controls) 
    { 
     if (c is T) 
     { 
      yield return c as T; 
     } 
    } 
} 

Utilisez cette façon:

foreach (TextBox tb in GetChildren<TextBox>(optionsControl)) 
{ 
    System.Diagnostics.Trace.WriteLine(tb.Name); 
} 
7

La collection Controls vous permet d'accéder à des éléments par nom, vous pouvez le faire:

var textboxes = Enumerable.Range(1, 12).Select(i => String.Format("textbox{0}", i)).Select(name => (TextBox)this.Controls[name]); 

qui évitera d'avoir à énumérer tous les contrôle dans la collection, mais est fragile car cela dépend de la convention de nommage utilisée.

Sinon, vous pouvez simplement utiliser la méthode de requête OfType:

var textboxes = this.Controls.OfType<TextBox>(); 
+0

+1 pour 'var textboxes = this.Controls.OfType ();' ... C'était exactement ce dont je parlais de me chercher. :) –

+0

Génial. +1 pour la méthode OfType –

+0

Hrm ... Je pense que je dois changer mon code pour utiliser OfType! – Sterno

2

j'avais une page qui a ajouté un nombre variable de cases à cocher à une page via un répéteur, et je devais effectuer certaines opérations sur eux. J'ai fini par écrire cette méthode d'extension générique afin que je puisse l'utiliser pour tous les contrôles dans le futur. Cela permettrait aussi de creuser à travers les sous-contrôles, au cas où votre case à cocher serait dans un autre contrôle sur la page.

public static List<TChildType> FindChildrenOfType<TChildType>(this Control currentControl) 
    where TChildType : Control 
{ 
    var childList = new List<TChildType>(); 
    foreach (Control childControl in currentControl.Controls) 
    { 
     if (childControl is TChildType) 
     { 
      childList.Add((TChildType)childControl); 
     } 

     childList.AddRange(childControl.FindChildrenOfType<TChildType>()); 

    } 
    return childList; 
} 

Dans la page, comme celui-ci se sont habitués:

var checkedCheckboxes = _myRepeater.FindChildrenOfType<CheckBox>().FindAll(c => c.Checked); 
+0

Basé sur quelques exemples ci-dessus, ce serait encore mieux de remplacer ma boucle interne avec Control.OfType(), mais je ne veux pas changer cet exemple jusqu'à ce que j'ai une chance de le tester. – Sterno

+0

Cela semble être la seule réponse qui retourne également les contrôles imbriqués (contrôles à l'intérieur d'un autre contrôle comme un TabControl) par l'utilisation d'une récursivité. –

Questions connexes