开发者

foreach (Control ctrl in Frm.Controls) in which order it takes controls

I am having 开发者_StackOverflowa peculiar problem with the order in which TextBox controls are added in to the form's Controls property.

Currently, I have the function:

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

But it's iterating through the textboxes randomly, even though I have set their tab indices.

So I develop the same form again and create the textboxes sequentially. But still, when I pass the form to this function, it's iterating through the textboxes randomly.

I want to know if there is any property of the controls that would allow me to manage their flow.


You can do its easily. Please use following syntax and which sort controls as per your tabindex in your form

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


It's much easier to sort controls manually than manage their order in Controls collection. Example (sorts by 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;
    }


Is it really iterating over the controls "randomly"? (Implying that it is non-deterministic and the order is likely to change each time.) Or is it iterating over the controls in the same order each time, but not the order you expect? I suspect it's the latter, given that the C# language specification explicitly states the ordering of foreach (see first answer).

The tab order certainly won't affect the ordering of the controls. That's just for UI purposes. The actual order of the controls as array elements in the backing store is more likely controlled by the order in which they were created when building the form.

Can you elaborate more on that last part where you develop the form again "and take the text box sequentially"?


The controls are placed in order of the Z-order of the controls in the same parent container (top-most to bottom-most). To test try placing controls on a form and get the order. Apply "Send to Back" or "Bring to Front" for a few controls (at design time or runtime). The order of the foreach will change with the topmost control first and downwards.

The generated Designer code adds the controls based on the z-order. Lowest control first (top most control last). Hence it seems like it is based on the order in which it is added to the container.

I'm not sure if the implementation of BringToFront() and SendToBack() internally removes and adds controls in the required order. To me it makes sense to have it based on the z-order. And like mentioned above, we can always use our own ordering if required.


You can drop the controls into the form in the designer visually, and then open up the Form.Designer.cs source file and locate where the designer has typed in the code to add the controls to the Controls collection (i.e. the Controls.Add lines) and re-order those lines in the *.Designer.cs by hand. Once you've done that, the designer should leave your changes alone. I noticed that the designer writes them in reverse order. Your foreach should find them in the order that you arranged them.


i had this problem and i changed the order control name on Designer.cs ,

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


See the Document Outline of the Form in view -> Other Windows -> Document Outline. And then change the hierarchy of the controls as you need. the foreach looks there

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜