foreach(在Frm.Controls中控制ctrl)按顺序控制

时间:2010-12-24 11:21:40

标签: c# winforms controls

我对TextBox控件添加到表单的Controls属性的顺序有一个特殊的问题。

目前,我有这个功能:

 public static bool IsValidate(System.Windows.Forms.Form Frm)
 {
     foreach (Control ctrl in Frm.Controls)                  
         if (ctrl is TextBox)
         //  if (((TextBox)ctrl).AccessibleDescription == "Valid" && ((TextBox)ctrl).Text == string.Empty)
         if (((TextBox)ctrl).AccessibleDescription == "Valid" &&  ((TextBox)ctrl).Text.Trim()== "")
         {
             MessageBox.Show(((TextBox)ctrl).AccessibleName + " Can't be Blank", Program.companyName, MessageBoxButtons.OK, MessageBoxIcon.Stop);                         
             ((TextBox)ctrl).Focus();
              return false;
         }
         return true;
}

但它正在随机迭代文本框,即使我已设置了标签索引。

所以我再次开发相同的表单并按顺序创建文本框。但是,当我将表单传递给此函数时,它会随机迭代文本框。

我想知道控件的任何属性是否允许我管理它们的流程。

7 个答案:

答案 0 :(得分:15)

你可以轻松地做到。 请根据表单中的tabindex使用以下语法和排序控件

foreach (Control control in this.Controls.Cast<Control>()
                                         .OrderBy(c => c.TabIndex))
{
}

答案 1 :(得分:4)

手动排序控件比在Controls集合中管理订单要容易得多。示例(按TabOrder排序):

    private static int CompareTabIndex(TextBox c1, TextBox c2)
    {
        return c1.TabIndex.CompareTo(c2.TabIndex);
    }

    public static bool IsValid(Form form)
    {
        List<TextBox> textBoxes = new List<TextBox>();
        foreach(Control ctl in form.Controls)
        {
            TextBox textBox = ctl as TextBox;
            if(textBox != null) textBoxes.Add(textBox);
        }
        textBoxes.Sort(new Comparison<TextBox>(CompareTabIndex));
        foreach(TextBox textBox in textBoxes)
        {
            if(textBox.AccessibleDescription == "Valid" && textBox.Text.Trim() == "")
            {
                MessageBox.Show(textBox.AccessibleName + " Can't be Blank",
                    Program.companyName, MessageBoxButtons.OK, MessageBoxIcon.Stop);
                textBox.Focus();
                return false;
            }
        }
        return true;
    }

答案 2 :(得分:3)

它是否真的在“随机”迭代控件? (暗示它是非确定性的,并且每次都可能改变顺序。)或者每次都以相同的顺序迭代控件,但不是您期望的顺序?鉴于C#语言规范explicitly states the ordering of foreach(参见第一个答案),我怀疑它是后者。

Tab键顺序当然不会影响控件的顺序。这只是用于UI目的。作为后备存储中的数组元素的控件的实际顺序更可能由构建表单时创建它们的顺序控制。

您是否可以详细说明再次开发表单的最后一部分“并按顺序取出文本框”?

答案 3 :(得分:2)

控件按照同一父容器中控件的Z顺序排列(从最顶部到最底部)。要测试尝试在窗体上放置控件并获取订单。对于一些控件(在设计时或运行时)应用“Send to Back”或“Bring to Front”。 foreach的顺序将随着最顶层控件的变化而向前和向下变化。

生成的Designer代码根据z顺序添加控件。首先是最低控制(最高控制最后)。因此,它似乎是基于它被添加到容器的顺序。

我不确定BringToFront()和SendToBack()的实现是否在内部删除并按所需顺序添加控件。对我而言,根据z顺序进行它是有意义的。如上所述,如果需要,我们可以随时使用自己的订单。

答案 4 :(得分:1)

我遇到了这个问题,我更改了Designer.cs上的订单控制名称,

this.groupBox3.Controls.Add(this.txtPrice);
this.groupBox3.Controls.Add(this.txtDate);

答案 5 :(得分:0)

您可以直观地将控件放入设计器中的表单中,然后打开Form.Designer.cs源文件并找到设计器在代码中键入的位置,以将控件添加到Controls集合(即控件) 。添加行)并手动重新排序* .Designer.cs中的这些行。完成后,设计师应该单独留下您的更改。我注意到设计师以相反的顺序编写它们。你的foreach应该按照你安排它们的顺序找到它们。

答案 6 :(得分:-1)

请参阅视图中的表单的文档大纲 - &gt;其他Windows - &gt;文件大纲。 然后根据需要更改控件的层次结构。 foreach看起来在那里