我有一个名为A
的Form
。
A
包含许多不同的控件,包括一个主要的GroupBox
。这个GroupBox
包含许多表格和其他的GroupBox
。我想找到一个在A
表单中具有例如标签索引9的控件,但我不知道哪个GroupBox
包含此控件。
我该如何做?
使用递归...
public static IEnumerable<T> Descendants<T>( this Control control ) where T : class
{
foreach (Control child in control.Controls) {
T childOfT = child as T;
if (childOfT != null) {
yield return (T)childOfT;
}
if (child.HasChildren) {
foreach (T descendant in Descendants<T>(child)) {
yield return descendant;
}
}
}
}
您可以像这样使用上面的函数:
var checkBox = (from c in myForm.Descendants<CheckBox>()
where c.TabIndex == 9
select c).FirstOrDefault();
这将获取表单中TabIndex为9的第一个CheckBox。您可以使用任何标准。
如果您不喜欢LINQ查询语法,以上内容可以重写为:
var checkBox = myForm.Descendants<CheckBox>()
.FirstOrDefault(x=>x.TabIndex==9);
递归搜索您的表单的 Controls 集合。
void FindAndSayHi(Control control)
{
foreach (Control c in control.Controls)
{
Find(c.Controls);
if (c.TabIndex == 9)
{
MessageBox.Show("Hi");
}
}
}
void iterateControls(Control ctrl)
{
foreach(Control c in ctrl.Controls)
{
iterateControls(c);
}
}
public static Control GetControl(Control.ControlCollection controlCollection, Predicate<Control> match)
{
foreach (Control control in controlCollection)
{
if (match(control))
{
return control;
}
if (control.Controls.Count > 0)
{
Control result = GetControl(control.Controls, match);
if (result != null)
{
return result;
}
}
}
return null;
}
...这样使用:
Control control = GetControl(this.Controls, ctl => ctl.TabIndex == 9);
TabIndex
是一个棘手的情况,因为它在每个容器内都从0
开始,所以在同一表单中可能有几个控件具有相同的TabIndex
值。Control control = GetControl(this.Controls, ctl => ctl.Text == "Some text");
我讨厌递归,所以我总是使用堆栈来处理这种事情。这将为当前控件层次结构中每个单选按钮控件的 CheckedChanged
事件分配一个公共事件处理程序:
Stack<Control> controlStack = new Stack<Control>();
foreach (Control c in this.Controls)
{
controlStack.Push(c);
}
Control ctl;
while (controlStack.Count > 0 && (ctl = controlStack.Pop()) != null)
{
if (ctl is RadioButton)
{
(ctl as RadioButton).CheckedChanged += new EventHandler(rb_CheckedChanged);
}
foreach (Control child in ctl.Controls)
{
controlStack.Push(child);
}
}
您可以轻松地使乔希·爱因斯坦的扩展方法按照这种方式工作。