我面临着获取表单中所有元素的任务,包括菜单和状态栏以及其他具有Text. 由于每个控件都有一个Controls属性(和窗体,分别),我可以使用以下代码来获取窗体的所有控件及其子控件:
public static IEnumerable<Control> GetControls(Control control)
{
foreach (Control childControl in control.Controls)
{
foreach (Control grandChild in GetControls(childControl))
{
yield return grandChild;
}
yield return childControl;
}
}
问题是菜单没有 Controls 属性,您必须使用Items属性来访问子元素。目前,我没有找到其他任何东西,如何检查类型。是否有可能以某种方式统一访问所有表单元素,包括子元素?
该属性
Items包含ToolStripItem类型的元素,而不是Control类型的元素。它们不是相互继承的,因此无法将 ToolStripItem 添加到控件序列中。这些类的共同直接祖先是Component,它没有
Text. 他们实现的接口也没有这个属性。因此,您的任务并没有在额头上解决。您写道,除了类型检查之外,您没有发现任何其他东西。是的,无论如何都必须检查类型。您可以在您的方法中执行此操作并在那里执行必要的操作。
但是,如果您只想在方法内部找到所有必要的对象,并在外部对它们执行操作,那么我可以提供以下代码:
在这里,我们得到了一个 type 序列
Component,尽管它可以取得同样的成功object——无论如何,我们必须进一步检查它们的类型。您可以使用以下方法避免手动类型检查
dynamic:这或多或少是有效的代码,但仍然存在许多问题。例如,
ToolStrip它可能包含一个没有属性但有属性的ToolStripDropDownButton。我强烈怀疑您也想浏览它们。ItemsDropDownItems所有这些都表明你正在从错误的角度解决一些问题。
一般来说,我会制作两个(或更多,考虑到
DropDowns)方法,其中一个会返回Control,另一个ToolStripItem,第三个 -ToolStripDropDownItem。当您使用表单设计器添加 MenuStrip 元素时,IDE 会将适当类型的私有字段添加到您的表单类(可以在 FormName.Designer.cs 中查看)。如果你想从另一个表单中获取这个元素,你可以尝试使用反射:
或遍历所有 Control 的字段,并使用 MenuStrip 类型获取所有内容