如何在Windows窗体应用程序中迭代控件?

所以这是一个愚蠢的问题。 我已经在我编写的应用程序中的选项对话框中添加了一堆文本框。 它们被命名为textbox1 – textbox12。 有没有办法以编程方式访问名称? 我只想在for循环中迭代它们。 现在我正在单独访问每个人(不寒而栗!)。 我知道这是错误的方式。 什么是正确的方法? 什么是简单的方法?

谢谢

我个人更喜欢以编程方式创建控件,然后将它们放入集合中。 即

IList textBoxes = new List(); … 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); } 

然后,您可以在textBoxes上进行迭代,以编程方式添加它们。 当你有几个不同的文本框组需要这样做时,我发现这个尺度更好。

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

如果它们具有不同的function,那么您可能需要更多检查,而不仅仅是确定它们是正确的类型。 当然,这假设您已导入System.Windows.Forms命名空间。

Controls集合允许您按名称访问项目,因此您可以这样做:

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

这将避免必须枚举集合中的每个控件,虽然它很脆弱,因为它取决于使用的命名约定。

或者,您可以使用OfType查询方法:

 var textboxes = this.Controls.OfType(); 

您可以编写一个更通用地执行此操作的函数。

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

用这种方式:

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

我有一个页面通过转发器向页面添加了可变数量的复选框,我需要对它们执行一些操作。 我最后写了这个通用扩展方法,所以我可以将它用于将来的任何控件。 如果您的复选框位于页面上的其他控件内,这将通过子控件进行挖掘。

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

在页面中,它被使用如下:

 var checkedCheckboxes = _myRepeater.FindChildrenOfType().FindAll(c => c.Checked);