如何在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);