繁体   English   中英

我可以在C#winforms中使用foreach循环评估两组项目吗?

[英]Can I evaluate two groups of items with a foreach loop in C# winforms?

我有一个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循环吗?

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);
}

最终解决方案

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>();

BTW我认为最好在这里使用简单的非通用ArrayList

ArrayList allControls = new ArrayList();
allControls.AddRange(tb_Invoices.Controls);
allControls.AddRange(tb_Statements.Controls);

我喜欢做的是:

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

foreach (T item in list)
{
    .....
}

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

private void LoopAllControls(Control YourObject)
   foreach(Control c in YourObject.Controls)
   {
      if(C.Controls.Count > 0)
        LoopAllControls(c.Controls);
      //your code
   }

你可以这样做:

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);

如果你不能使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM