跨越多个 ControlCollection 的 foreach 循环

4
我在 Windows Form 中有一个选项卡控件,我想要遍历两个不同选项卡中的每个元素。当文件被打开时,我希望所有元素都被启用,当文件被关闭时,所有元素都被禁用。
然而,由于这些控件不是数组或列表,而是一个 ControlsCollection,我不知道如何实现这一点。我之前问过关于 foreach 语句的问题,并学了一些关于 lambda 的知识,但我不知道如何在这里应用它。
以下是我的代码:
List<Control.ControlCollection> panels = new List<Control.ControlCollection>();
panels.Add(superTabControlPanel1.Controls);
panels.Add(superTabControlPanel2.Controls);
foreach(Control.ControlCollection ctrlc in panels){
    foreach (Control ctrl in ctrlc) { 

    }
}

这是否可以使用一个foreach语句完成,或者某种更简单的方式?
4个回答

4

我会使用Linq,具体如下:

foreach (var ctrl in panels.SelectMany (x => x.Cast<Control> ())) {
     // Work with the control.
}

关键是要在IEnumerable上使用Cast扩展方法,使其能够与SelectMany一起使用。

1

你知道吗,如果你禁用父控件,那么所有嵌套的控件也会被禁用?只需要禁用这两个选项卡面板就可以禁用所有子控件。启用面板可以恢复效果。

我知道这不是你问题的答案,但这是一个更好的解决方案。


1
为什么没有人告诉我?该死,这样会容易得多。 - mowwwalker
有时候过于专注于复杂的解决方案会阻碍我们发现简单的方法。 - Scott Rippey
这也有一个很好的功能:如果子控件应该被禁用,即使父控件重新启用,它仍将保持禁用状态。 - Scott Rippey

0

我会像这样做:

List<Control> controls = new List<Control>();
controls.AddRange(superTabControlPanel1.Controls.GetControls());
controls.AddRange(superTabControlPanel2.Controls.GetControls());
foreach(Control ctrl in controls){
    //Do something
}

我目前手头没有VS,并不确定GetControls()是否存在。但是您可以使用一般的想法:不要使用面板集合,而是使用控件集合,并在一个循环中迭代控件。


0

我可能会将这两个集合联合起来,避免使用通用的List<T>

var controls = superTabControlPanel1.Controls.Union(superTabControlPanel2.Controls);

foreach (var control in controls) {
  //...
}

或者您可以将多个集合链接在一起。

var controls = 
  (superTabControlPanel1.Controls)
  .Union
  (superTabControlPanel2.Controls)
  .Union
  (superTabControlPanel3.Controls);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接