views:

2238

answers:

3

I am having a peculiar problem with the order in which FlowLayoutPanels are added in to the form's controls property. This is what I tried,

I added 7 FlowLayoutPanels in to a C# window application from left to right in vertical strips. Then I tagged the flow layouts as 1, 2, 3, ... 7 again from left to right. Now in the load handler of the form, I wrote the following snippet,

    foreach (FlowLayoutPanel aDaysControl in this.Controls)
    {
        MessageBox.Show(aDaysControl.Tag.ToString());
    }

I expected messages to appear in the order of 1, 2, ... 7. But I got it in the reverse order (7, 6, ...1). Could some one help me out with the mistake I did ??

Reason behind preserving the order,

I am trying to make a calendar control with each row representing a day. If a month starts from Wednesday, then I need to add a empty label to the first(Monday) and the second(Tuesday) row. So the order matters a bit

+1  A: 

look at the order in which they are added to the form in the yourForm.designer.cs

Mladen Prajdic
Yeah. Thats that problem. They were added in the opposite way. Don't know why. Thanks
A: 

Is it really a problem?

As long as the UI operates correctly (in terms of tab order, for example), I'd recommend that you don't make any assumptions about the order in which they're enumerated.

EDIT: Thanks for explaining your requirement in more detail. I think I'd still recommend against using the order that they're stored in the Controls collection. It's always best to consider these implementation details to be 'opaque'. You have a tag associated with each control, so you can use this to identify the correct control. In order to speed up the processing, you could build a 7-element array that references the controls by ordinal:

FlowLayoutPanel[] panels = new FlowLayoutPanel[7];

foreach(FlowLayoutPanel panel in this.Controls)
{
    panels[(int)panel.Tag] = panel;
}

// Now, you can reference the panels directly by subscript:

panels[2].BackColor = Color.Aquamarine;

Though I'd put some type-checking in to make this code a bit more robust!

Steve Morgan
But the order __does___ matter in my case !!
+1  A: 

if you look at the code generated by the designer Form1.designer.cs it will look something like this:

        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(658, 160);
        this.Controls.Add(this.flowLayoutPanel7);
        this.Controls.Add(this.flowLayoutPanel6);
        this.Controls.Add(this.flowLayoutPanel5);
        this.Controls.Add(this.flowLayoutPanel4);
        this.Controls.Add(this.flowLayoutPanel3);
        this.Controls.Add(this.flowLayoutPanel2);
        this.Controls.Add(this.flowLayoutPanel1);
        this.Name = "Form1";
        this.Text = "Form1";
        this.ResumeLayout(false);

note how it was built up you added panel 1 first then 2 etc. but as the code runs through it will add 7 first then 6.

this code will be in the InitializeComponent() function generated by the designer.

Why do you need them to run in a certain order?

I wouldn't rely on the designer to keep the order you want.. i would sort the controls my self:

        var flowpanelinOrder = from n in this.Controls.Cast<Control>()
                               where n is FlowLayoutPanel
                               orderby int.Parse(n.Tag.ToString())
                               select n;

        /* non linq
        List<Control> flowpanelinOrder = new List<Control>();
        foreach (Control c in this.Controls)
        {
            if (c is FlowLayoutPanel) flowpanelinOrder.Add(c);                
        }
        flowpanelinOrder.Sort();
         * */

        foreach (FlowLayoutPanel aDaysControl in flowpanelinOrder)
        {
            MessageBox.Show(aDaysControl.Tag.ToString());
        }
Hath
I am trying to make a calendar control with each row representing a day. If a month starts from Wednesday, then I need to add a empty label to the first(Monday) and the second(Tuesday) row. So the order matters a bit.
Hmm. I was bit lazy. Learn the lesson now.