When is Panel.Size updated after adding controls when Panel.AutoSize = true?

10,971

What I beleive is happening is that the Size of the Panel will be determined when you do PerformLayout on its Parent. You can make it work like you are wanting by moving the panel's parent SuspendLayout / ResumeLayout code into the Loop.

int yPos = 0;
foreach (String entry in entries)
{
    this.SuspendLayout();
    Panel panel = new Panel();
    panel.SuspendLayout();
    panel.AutoSize = true;
    panel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly;
    panel.BackColor = System.Drawing.SystemColors.Window; // Allows to see that the panel is resized for dispay
    panel.Location = new System.Drawing.Point(0, yPos);
    panel.Size = new System.Drawing.Size(this.Width, 0);
    this.Controls.Add(panel);

    Label label = new Label();
    label.AutoSize = true;
    label.Location = new System.Drawing.Point(0, 0);
    label.MaximumSize = new System.Drawing.Size(panel.Width, 0);
    label.Text = entry;
    panel.Controls.Add(label);
    panel.ResumeLayout(true);
    this.ResumeLayout(true);
    yPos += panel.Height; // When breaking here, panel.Height is worth 0
    //yPos += label.Height; // This works perfectly, label.Height was updated according to the text content when breaking at that point
}
this.PerformLayout();
Share:
10,971
Antoine Henry
Author by

Antoine Henry

Game Designer at Ubisoft Paris Studio

Updated on June 11, 2022

Comments

  • Antoine Henry
    Antoine Henry almost 2 years

    I'm creating a GUI in C# using WinForms.
    I'm trying to position programaticaly created panels one below the other. As the content of these panel can vary depending on their content, I'm using Panel.AutoSize to let WinForms perform the correct resizing.

    The problem is: if I'm using Panel.Height (or Panel.Size.Height) right after populating the Panel, the value returned is always my default value. The resizing do occur, as I can see when launching the app, but I just don't know when.

    Here's a simplified version of what I'm doing:

    this.SuspendLayout();
    
    int yPos = 0;
    foreach (String entry in entries)
    {
        Panel panel = new Panel();
        panel.SuspendLayout();
        panel.AutoSize = true;
        panel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly;
        panel.BackColor = System.Drawing.SystemColors.Window; // Allows to see that the panel is resized for dispay
        panel.Location = new System.Drawing.Point(0, yPos);
        panel.Size = new System.Drawing.Size(this.Width, 0);
        this.Controls.Add(panel);
    
        Label label = new Label();
        label.AutoSize = true;
        label.Location = new System.Drawing.Point(0, 0);
        label.MaximumSize = new System.Drawing.Size(panel.Width, 0);
        label.Text = entry;
        panel.Controls.Add(label);
    
        panel.ResumeLayout(false);
        panel.PerformLayout();
    
        yPos += panel.Height; // When breaking here, panel.Height is worth 0
        yPos += label.Height; // This works perfectly, label.Height was updated according to the text content when breaking at that point
    }
    
    this.ResumeLayout(false);
    this.PerformLayout();
    

    So the real question is: How can I get the updated Panel.Size after adding controls to it, to get its proper height value?

    Note: I know I can use the TextBox height, but I find it inelegant and impractical, as in my actual code there are more controls in the Panel and I need to use that panel height a few lines below.

  • Antoine Henry
    Antoine Henry over 11 years
    It works, thanks a lot for the answer. So the actual resizing occurs when the layout of the parent container is computed.
  • Mark Hall
    Mark Hall over 11 years
    @AntoineHenry Yes That is what appears to be happening.