用于循环访问 Windows 窗体中的所有控件及其相关控件的常规递归方法
本文关键字:控件 递归方法 常规 访问 循环 Windows 窗体 用于 | 更新日期: 2023-09-27 17:55:36
是否有任何通用的递归方法可以在Windows窗体中迭代所有控件(包括toolstrip及其项,bindingnavigator及其项,...)?(其中一些不是从 Control 类继承的)或者至少迭代 toolstrip 及其项、绑定导航器及其项?
你会在这里遇到障碍,因为ToolStrip
使用Items
而不是Controls
,并且ToolStripItem
不会从Control
继承。ToolStripItem
和Control
都继承自Component
,所以充其量你可以得到一个IEnumerable<Component>
。
您可以使用以下扩展方法完成此操作:
public static class ComponentExtensions
{
public static IEnumerable<Component> GetAllComponents(this Component component)
{
IEnumerable<Component> components;
if (component is ToolStrip) components = ((ToolStrip)component).Items.Cast<Component>();
else if (component is Control) components = ((Control)component).Controls.Cast<Component>();
else components = Enumerable.Empty<Component>(); // figure out what you want to do here
return components.Concat(components.SelectMany(x => x.GetAllComponents()));
}
}
在 Windows 窗体上,您可以在foreach
循环中处理所有这些组件:
foreach (Component component in this.GetAllComponents())
{
// Do something with component...
}
不幸的是,您将进行大量手动类型检查和转换。
这是我在这种情况下通常做的:
首先定义一个接受 Control 作为参数的委托:
public delegate void DoSomethingWithControl(Control c);
然后实现一个方法,该方法将此委托作为第一个参数,并实现递归执行它的控件作为第二个参数。此方法首先执行委托,然后循环控件的 Controls 集合以递归调用自身。这有效,因为控件是在控件中定义的,并为简单控件返回一个空集合,例如:
public void RecursivelyDoOnControls(DoSomethingWithControl aDel, Control aCtrl)
{
aDel(aCtrl);
foreach (Control c in aCtrl.Controls)
{
RecursivelyDoOnControls(aDel, c);
}
}
现在,您可以将要为每个控件执行的代码放在方法中,并通过委托在 Form 上调用它:
private void DoStg(Control c)
{
// whatever you want
}
RecursivelyDoOnControls(new DoSomethingWithControl(DoStg), yourForm);
编辑:
由于您也在处理 ToolStripItems,因此您可以定义委托来处理泛型对象,然后编写递归方法的不同重载。 即像这样:
public delegate void DoSomethingWithObject(Object o);
public void RecursivelyDo(DoSomethingWithObject aDel, Control aCtrl)
{
aDel(aCtrl);
foreach (Control c in aCtrl.Controls)
{
RecursivelyDoOnControls(aDel, c);
}
}
public void RecursivelyDo(DoSomethingWithObject aDel, ToolStrip anItem)
{
aDel(anItem);
foreach (ToolstripItem c in anItem.Items)
{
RecursivelyDo(aDel, c);
}
}
public void RecursivelyDo(DoSomethingWithObject aDel, ToolStripDropDownButton anItem)
{
aDel(anItem);
foreach (ToolStripItem c in anItem.DropDownItems)
{
RecursivelyDo(aDel, c);
}
}
//and so on