C# 通过C递归通知子控件#

C# 通过C递归通知子控件#,c#,winforms,controls,C#,Winforms,Controls,我有一个窗体MainForm,它是一个包含许多子控件的Windows窗体。我想在MainForm上调用一个函数,通知它的所有子函数。Windows窗体是否提供了执行此操作的方法?我玩了更新、刷新和失效,但没有成功。没有。你必须推出你自己的 另一方面,WPF有“路由事件”,正是这样,甚至更多 foreach (Control ctrl in this.Controls) { // call whatever you want on ctrl } 如果希望访问窗体上的所有控件,以及窗体上每

我有一个窗体
MainForm
,它是一个包含许多子控件的Windows窗体。我想在
MainForm
上调用一个函数,通知它的所有子函数。Windows窗体是否提供了执行此操作的方法?我玩了更新、刷新和失效,但没有成功。

没有。你必须推出你自己的

另一方面,WPF有“路由事件”,正是这样,甚至更多

foreach (Control ctrl in this.Controls)
{
    // call whatever you want on ctrl
}
如果希望访问窗体上的所有控件,以及窗体上每个控件上的所有控件(等等,递归),请使用如下函数:

public void DoSomething(Control.ControlCollection controls)
{
    foreach (Control ctrl in controls)
    {
        // do something to ctrl
        MessageBox.Show(ctrl.Name);
        // recurse through all child controls
        DoSomething(ctrl.Controls);
    }
}
DoSomething(this.Controls);
。。。您可以通过最初传入表单的控件集合来调用它,如下所示:

public void DoSomething(Control.ControlCollection controls)
{
    foreach (Control ctrl in controls)
    {
        // do something to ctrl
        MessageBox.Show(ctrl.Name);
        // recurse through all child controls
        DoSomething(ctrl.Controls);
    }
}
DoSomething(this.Controls);

您需要一个递归方法来实现这一点(如下所示),因为控件可以有子控件

void NotifyChildren( control parent )
{
    if ( parent == null ) return;
    parent.notify();
    foreach( control child in parent.children )
    {
        NotifyChildren( child );
    }
}

MusiGenesis的答案是优雅的,(在一个好的方面是典型的),漂亮和干净

但为了提供一种替代方法,使用lambda表达式和一个“操作”来实现不同类型的递归:

Action<Control> traverse = null;

//in a function:
traverse = (ctrl) =>
    {
         ctrl.Enabled = false; //or whatever action you're performing
         traverse = (ctrl2) => ctrl.Controls.GetEnumerator();
    };

//kick off the recursion:
traverse(rootControl);
动作遍历=null;
//在函数中:
遍历=(ctrl)=>
{
ctrl.Enabled=false;//或您正在执行的任何操作
遍历=(ctrl2)=>ctrl.Controls.GetEnumerator();
};
//开始递归:
导线(根控制);

notify是什么意思?正如问题的标题所说,这是WinForms中的C#控件没有“children”集合。也没有控件类。我将在像“ICanDoSomething”这样的接口中实现DoSomething,并在foreach中复制该接口。因此,您只需为每个控件添加此接口。