foreach SomePanel.Controls中的控件控件没有获得所有控件

问题描述:

我有一个面板,里面有一堆labeles和文本框。foreach SomePanel.Controls中的控件控件没有获得所有控件

的代码:

foreach (Control ctrl in this.pnlSolutions.Controls) 

似乎只是寻找面板和2个liternals内HTML表格。 但它没有得到HTML表格中的文本框。 有没有简单方式得到全部面板内的控件不管嵌套

的感谢!

+0

您是否在寻找特定的控制功能?你能否提供一些你希望达到的细节。 – Lazarus 2010-05-13 16:00:38

这里是一个懒惰的解决方案:

public IEnumerable<Control> GetAllControls(Control root) { 
    foreach (Control control in root.Controls) { 
    foreach (Control child in GetAllControls(control)) { 
     yield return child; 
    } 
    } 
    yield return root; 
} 

也请记住,某些控件保持项目的内部集合(如ToolStrip的),这将不枚举的。

+0

luvs me懒惰的解决方案:) 谢谢你的工作完美! 我从来没有听说过“屈服”之前:) – aron 2010-05-13 16:30:16

您需要通过控件递归“treewalk”,想象它像遍历文件夹结构。

有一个样品Here

+0

+1,我会这样做的。 – 2010-05-13 16:05:31

据我知道你有自己实现递归,但它不是真的很难。

草图(未经测试):

void AllControls(Control root, List<Control> accumulator) 
{ 
    accumulator.Add(root); 
    foreach(Control ctrl in root.Controls) 
    { 
     AllControls(ctrl, accumulator); 
    } 
} 

的原因是因为这是您的面板直接孩子的唯一控件是表和你提到的文字,这是只有这些是this.pnlSolutions.Controls回报。

文本框标签是表的子控件,使它们成为面板的孙子。

正如@Yoda指出,你需要递归地走控制找到他们。

我确实有问题中提到的问题,所以这可能有助于某人。在重写之前,我试图清除控件集合。

private void clearCollection(Control.ControlCollection target) 
{ 
    foreach (Control Actrl in target) 
    { 
     if (Actrl is Label || Actrl is Button) 
     { 
      target.Remove(Actrl); 
     } 
    } 
} 

通过删除foreach循环内的控件,它必须弄乱内部指针,结果是集合中的控件被遗漏。 我的解决方案是找到所有的控件,然后在一个单独的循环中删除。

private void clearCollection(Control.ControlCollection target) 
    { 
     List<Control> accumulator = new List<Control>(); 

     foreach (Control Actrl in target) 
     { 
      if (Actrl is Label || Actrl is Button) 
      { 
       accumulator.Add(Actrl); // find all controls first. 
      } 
     } 

     for (int i = 0; i < accumulator.Count; i++) 
     { 
      target.Remove(accumulator[i]); 
     } 
    }