6

我有一个 winforms TabControl,我试图循环浏览每个选项卡中包含的所有控件。有没有办法andforeach循环中添加或者不能评估多个项目?例如,这是我想做的:

foreach (Control c in tb_Invoices.Controls and tb_Statements.Controls)
{
    //do something
}

或者

foreach (Control c in tb_Invoices.Controls, tb_Statements.Controls)
{
    //do something
}

这可能吗,如果没有,下一个最好的事情是什么?我需要使用for循环吗?

4

6 回答 6

4
foreach(TabPage page in yourTabControl.TabPages){
   foreach(Control c in page.Controls){
      LoopThroughControls(c);
   }  
}

private void LoopThroughControls(Control parent){
   foreach(Control c in parent.Controls)
      LoopThroughControls(c);
}
于 2013-08-07T13:57:21.480 回答
3

最终解决方案:

var allControls = from TabPage p in tabControl.TabPages
                  from Control c in p.Controls
                  select c;

原始答案 - 使用Concat

var allControls = tb_Invoices.Controls.Cast<Control>()
                             .Concat(tb_Statements.Controls.Cast<Control>();

顺便说一句,我认为最好在ArrayList这里使用简单的非泛型

ArrayList allControls = new ArrayList();
allControls.AddRange(tb_Invoices.Controls);
allControls.AddRange(tb_Statements.Controls);
于 2013-08-07T13:55:41.700 回答
0

我喜欢做的是:

var list = new List<T>();
list.AddRange(list1);
list.AddRange(list2);
list.AddRange(list3);
list.AddRange(list4);

foreach (T item in list)
{
    .....
}
于 2013-08-07T13:54:42.443 回答
0

你可以这样做:

public static void ForAllChildren(Action<Control> action, 
    params Control[] parents)
{
    foreach(var p in parents)
        foreach(Control c in p.Controls)
            action(c);
}

像这样调用:

ForAllChildren(x => Foo(x), tb_Invoices, tb_Statements);

尽管在这种情况下您可以只使用嵌套的,但您可能会在操作调用的性能上受到一点影响foreach

foreach (var p in new Control[] { tb_Invoices, tb_Statements })
    foreach (Control c in p.Controls)
        Foo(c);

同样,遍历任何非泛型中所有项目的通用解决方案IEnumerable可能是(尽管有点像使用大锤敲钉子):

public static void ForEachAll<T>(Action<T> action, 
    params System.Collections.IEnumerable[] collections)
{
    foreach(var collection in collections)
        foreach(var item in collection.Cast<T>())
            action(item);
}

像这样调用:

ForEachAll<Control>(x => Foo(x), tb_Invoices.Controls, tb_Statements.Controls);
于 2013-08-07T14:07:30.127 回答
0

您可以通过递归编写它来使用一个 foreach 循环。这将确保遍历表单中所有类型的所有控件。

private void LoopAllControls(Control YourObject)
   foreach(Control c in YourObject.Controls)
   {
      if(C.Controls.Count > 0)
        LoopAllControls(c.Controls);
      //your code
   }
于 2013-08-07T13:56:54.923 回答
0

如果您无法使用 LINQ(例如卡在 .NET2 中),我建议您使用以下方法:

public static IEnumerable<T> Concat<T>(params IEnumerable<T>[] args)
{
    foreach (IEnumerable<T> collection in args)
    {
        foreach (T item in collection)
        {
            yield return item;
        }
    }
}

现在你有了一个通用函数,你可以将它与任何可枚举的东西一起使用。您的循环可能如下所示:

foreach (Control c in Concat(tb_Invoices.Controls, tb_Statements.Controls))
{
    //do something
}

简单、便宜且富有表现力!

编辑:如果您的集合没有实现,IEnumerable<T>但只有IEnumerable,您可以添加一个接受后者的重载。一切都保持不变,除了嵌套循环中的T更改object

于 2013-08-08T08:28:26.177 回答