Order of controls in a form's Control property in C#

后端 未结 5 1424
北海茫月
北海茫月 2021-01-18 19:35

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

相关标签:
5条回答
  • 2021-01-18 19:46

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

    0 讨论(0)
  • 2021-01-18 19:50

    I know this is quite an old question, but...

    You might want to use SetChildIndex. e.g. this.Controls.SetChildIndex(button1, 0);

    0 讨论(0)
  • 2021-01-18 19:52

    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!

    0 讨论(0)
  • 2021-01-18 19:57

    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());
            }
    
    0 讨论(0)
  • 2021-01-18 19:59

    What if in future some other designer removed the controls, added back etc? Checking the designer always is a mess. What would be better is to sort the controls in the container control before you enumerate. I use this extension method (if you have Linq):

    public static List<Control> ToControlsSorted(this Control panel)
    {
        var controls = panel.Controls.OfType<Control>().ToList();
        controls.Sort((c1, c2) => c1.TabIndex.CompareTo(c2.TabIndex));
        return controls;
    }
    

    And you can:

    foreach (FlowLayoutPanel aDaysControl in this.ToControlsSorted())
    {
        MessageBox.Show(aDaysControl.TabIndex.ToString());
    }
    

    (Above is for TabIndex). Would be trivial to sort according to Tag from that.

    0 讨论(0)
提交回复
热议问题