【问题标题】:How do I set the order a foreach loop loops through a panel of controls?如何设置 foreach 循环通过控件面板循环的顺序?
【发布时间】:2015-07-15 14:53:40
【问题描述】:

我有一个通过控制面板的 foreach 循环:

foreach(MyControl control in MyPanel.Controls)

并将每个选中的复选框控件的名称添加到列表中:

if (control.Checked == true)
{
  MyList.Add(control.Name)
}

但它似乎按照将它们添加到列表中的顺序在面板周围跳跃。如何设置它在面板中运行的顺序,以便它以指定的顺序将检查到的控件的名称添加到 MyList?

【问题讨论】:

  • 它是按照ControlsCollection中每个控件的顺序添加的。你要哪个订单?
  • 我希望能够编辑它添加它们的顺序...如何将其从添加控制 QQQ 然后控制 RRR 更改为添加控制 RRR 然后控制 QQQ
  • 唯一的方法是删除它们并按照您想要的顺序将它们重新添加到设计器中。更简单的选择是将控件复制到数组并按某些内容排序,例如选项卡索引或Tag 属性。

标签: c# winforms


【解决方案1】:

将集合转换为IEnumerable<Control> 并使用OrderBy

foreach(MyControl control in MyPanel.Controls.Cast<Control>.OrderBy(c => c.Name))
{
    if (control.Checked == true)
    {
        MyList.Add(control.Name)
    }
}

或者在添加所有名称后对列表进行排序,因为您只是将名称存储在列表中:

MyList.Sort();

【讨论】:

    【解决方案2】:

    您可以使用 Linq 创建您的列表

    var MyList = MyPanel.Controls.Cast<Control>.OrderBy(c => c.Name).Where(c=>c.Checked).ToList();
    

    【讨论】:

    • 我开始喜欢这个答案,然后我突然意识到 Checked 属性仅对 CheckBox 对象有效,因此转换为 Control 将不起作用。此外,您应该在排序之前进行过滤。请参阅下面的答案。
    【解决方案3】:

    试试这个:

    var MyList = MyPanel.Controls.OfType<CheckBox>()
                  .Where(c => c.Checked)
                  .OrderBy(c => c.Name)
                  .ToList();
    

    如您所见,我使用OfType 而不是Cast,因为如果不能转换为CheckBox,Cast 会抛出,而OfType 只会返回可以转换为所需类型的对象。

    干杯

    【讨论】:

      【解决方案4】:

      MyPanel.Controls 返回一个 ControlCollection。 ControlCollection 实现了 IList 接口,因此您可以使用 LINQ 对其进行排序。

      【讨论】:

      • 从技术上讲,您可以使用 LINQ 来查询列表并将排序的结果存储在单独的列表中,它实际上不会对源 IList 进行排序。
      猜你喜欢
      • 1970-01-01
      • 2016-08-10
      • 2011-07-04
      • 2013-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      相关资源
      最近更新 更多