如何在整个控件链中找到类型的控件?
How to find a control of type in the entire controls chain?
我想在我的表单中找到实现特定接口的所有控件(比方说 ITestInterface
)。我试过这个:
this.Controls.OfType<ITestInterface>();
但它只有一层深(尽管 MSDN - @dasblinkenlight 中写的是什么),所以例如,如果我在表单中有一个面板,在里面有一个 ITestInterface
控件面板,它不会找到它。
怎么做?
编辑: 正如@HansPassant 在评论中所写,我可以硬编码我的面板名称,但是,我需要一个通用的解决方案,而不是特定的特定解决方案表格.
您必须使用递归并单步执行控件的 Controls
属性:
private IEnumerable<T> GetAllOfType<T>(Control rootControl)
{
return rootControl.Controls.OfType<T>().
Concat(rootControl.Controls.OfType<Control>().SelectMany(GetAllOfType<T>));
}
您可以这样使用:
var allOfTestInterface = GetAllOfType<ITestInterface(this);
它获取根控件直接包含的所有具有该接口的控件(通过您的 OfType<>()
调用),然后再次为包含的 所有 控件调用该方法通过该控件,从而在所有容器中递归。 SelectMany
将这个嵌套列表展平为一个列表。
我想在我的表单中找到实现特定接口的所有控件(比方说 ITestInterface
)。我试过这个:
this.Controls.OfType<ITestInterface>();
但它只有一层深(尽管 MSDN - @dasblinkenlight 中写的是什么),所以例如,如果我在表单中有一个面板,在里面有一个 ITestInterface
控件面板,它不会找到它。
怎么做?
编辑: 正如@HansPassant 在评论中所写,我可以硬编码我的面板名称,但是,我需要一个通用的解决方案,而不是特定的特定解决方案表格.
您必须使用递归并单步执行控件的 Controls
属性:
private IEnumerable<T> GetAllOfType<T>(Control rootControl)
{
return rootControl.Controls.OfType<T>().
Concat(rootControl.Controls.OfType<Control>().SelectMany(GetAllOfType<T>));
}
您可以这样使用:
var allOfTestInterface = GetAllOfType<ITestInterface(this);
它获取根控件直接包含的所有具有该接口的控件(通过您的 OfType<>()
调用),然后再次为包含的 所有 控件调用该方法通过该控件,从而在所有容器中递归。 SelectMany
将这个嵌套列表展平为一个列表。