I have a flowlayout as follows:
I need to center all the controls on the form (In other words, let's say the form's width is 200. btnOpt1 to btnOpt4 should have their Left starting at 100 minus half of the button width, not 0.)
You can do it two ways but with some limitation of each one.
Using Anchor property
Using the layout control with help of Docking and Anchor properties.
Method 1: Anchor Property
Controls are anchored by default to the top left of the form which
means when the form size will be changed, their distance from the top
left side of the form will remain constant. If you change the control
anchor to bottom left, then the control will keep the same distance
from the bottom and left sides of the form when the form if resized.
Turning off the anchor in a direction will keep the control centred in
that direction when resizing.
Example :
public TestForm12()
{
InitializeComponent();
Button btn = new Button();
btn.Width = this.Width - 10;
btn.Height = 20;
btn.Left = (this.ClientSize.Width - btn.Width) / 2;
btn.Top = (this.ClientSize.Height - btn.Height) / 2;
btn.Text = "click me";
this.Controls.Add(btn);
btn.Anchor = AnchorStyles.None;
}
2. Using the layout control
Add TableLayout Control, Set it’s Dock property to Fill.
Add 1 Row with Size Type style Percent 100%
Add 3 Columns Column1(Size Type – Percent(100%)), Column2(Size Type – Absolute(200px)), Column3(Size Type – Percent(100%)).
Now Add Panel Control to Column2 and Set it’s Dock property to Fill
Add Buttons to this control and set their Size as you want and Set Their Anchor Property to AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top
Example - Designer.cs code snippet of the form.
private void InitializeComponent()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.panel1 = new System.Windows.Forms.Panel();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.tableLayoutPanel1.SuspendLayout();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 3;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 200F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.Controls.Add(this.panel1, 1, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 1;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(284, 262);
this.tableLayoutPanel1.TabIndex = 0;
//
// panel1
//
this.panel1.Controls.Add(this.button2);
this.panel1.Controls.Add(this.button1);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(45, 3);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(194, 256);
this.panel1.TabIndex = 0;
//
// button1
//
this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.button1.Location = new System.Drawing.Point(3, 9);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(188, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
//
// button2
//
this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.button2.Location = new System.Drawing.Point(3, 38);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(188, 23);
this.button2.TabIndex = 0;
this.button2.Text = "button1";
this.button2.UseVisualStyleBackColor = true;
//
// TestForm11
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 262);
this.Controls.Add(this.tableLayoutPanel1);
this.Name = "TestForm11";
this.Text = "TestForm11";
this.tableLayoutPanel1.ResumeLayout(false);
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button1;
Hope this help..
I'd go with TableLayoutPanel instead:
Put TableLayoutPanel on your form
Set dock style Fill to panel
Leave only one column inside panel
Create row for every button (and put buttons to table cells)
Set row size type Autosize
Set dock style Fill to every button, except last one
Set dock style Top to last button
BTW in your solution you should iterate over flowLayoutPanel controls instead of form controls. Also consider subtracting horizontal margin and padding from width:
foreach (Control control in flowLayoutPanel.Controls)
{
control.Size = new Size(flowLayoutPanel.Width - control.Margin.Horizontal,
control.Height);
}
But I advise you to use TableLayoutPanel instead.
I solved this by changing the margin values. I am adding my content to a panel though.
C#:
int horizontalMargin = (int)(0.5 * (this.containingPanelOrForm.Width - this.button.Width));
this.btnOptX.Margin = new Padding(horizontalMargin, 0, horizontalMargin, 0);
Or you can use Grid layout instead.
I´m not good in C# but you can also add a panel in flowlayoutpanel with the same width of flowlayoutpanel. Then you can add in the Panel created in running time the button you want and set the dock to left or right. As you wish. Let me show a example in VB.net and C# (used online converts)
VB.net
Dim btn As New Button
btn.Text = "Example"
btn.Name = "Button"
btn.Size = New Size(60,10)
Dim panel As New Panel
panel.Size = New Size(FlowLayoutPanel1.Width, 10) 'size of the flowlayoutpanel + height of button
btn.Dock = DockStyle.Right
FlowLayoutPanel1.Controls.Add(panel)
panel.controls.add(btn)
C#
Button btn = new Button();
btn.Text = "Example";
btn.Name = "Button";
btn.Size = new Size(60, 10);
Panel panel = new Panel();
panel.Size = new Size(FlowLayoutPanel1.Width, 10);
//size of the flowlayoutpanel + height of button
btn.Dock = DockStyle.Right;
FlowLayoutPanel1.Controls.Add(panel);
panel.controls.#add(btn);
Create empty Label with Name = lblEmpty and AutoSize = False. Put this control first in controls list in FlowLayoutPanel1, then add code below.
Example: Assuming three existing labels in FlowLayoutPanel1, the result should be lblEmpty, LabelExisting1, and LabelExisting2, in that order.
Dim MarginLabelEmpty As Integer = ((FlowLayoutPanel1.Width - (LabelExisting1.Width + LabelExisting2.Width)) / 2)
lblEmpty.Width = MarginLabelEmpty
I solved my problem by creating this code.
in your case with Button Controls, create 4 new labels with .Text=""(empty) and put each one at the beginning of each button, naming labels as follows: lblEmpty1, lblEmpty2, lblEmpty3, lblEmpty4.
Then Add the following code:
Dim MarginLeftbtnOptAll As Integer = ((FlowLayoutPanel1.Width - btnOpt1.Width) / 2)
lblEmpty1.AutoSize = False
lblEmpty1.Width = MarginLeftbtnOptAll
lblEmpty2.AutoSize = False
lblEmpty2.Width = MarginLeftbtnOptAll
lblEmpty3.AutoSize = False
lblEmpty3.Width = MarginLeftbtnOptAll
lblEmpty4.AutoSize = False
lblEmpty4.Width = MarginLeftbtnOptAll
This center button, increasing the width of the empty label according to the width of the FlowLayoutPanel1
Throwing the buttons directly to the form or a panel (not FlowLayoutPanel), and setting Anchor = Top (only Top) for all of them, they won't be centered but will always move proportional to the form's (or container's) sides when resizing.
Private Sub FlowLayoutPanel1_SizeChanged(sender As Object, e As EventArgs)` Handles FlowLayoutPanel1.SizeChanged
Dim TotalWidth As Integer = FlowLayoutPanel1.Controls.Count * button.Width
Dim LeftPadding As Integer = (FlowLayoutPanel1.Width - TotalWidth) / 2
Dim GapPadding As Integer = FlowLayoutPanel1.Controls.Count * 5
If TotalWidth <= FlowLayoutPanel1.Width Then
FlowLayoutPanel1.Padding = New Padding(LeftPadding - GapPadding, 0, 0, 0)
End If
End Sub
Related
I have a simple System.Windows.Forms.Label in a System.Windows.Forms.Form.
I want to dynamically resize the label to fit text loaded runtime, while keeping it Anchored to the right and bottom of its parent form.
According to the MSDN Documentation:
It is “always true” that the Location Property remains constant (i.e., that the top left position of the Control will never change).
It is “always true” that the Anchor property is respected when AutoSize is true (i.e., that the Location Property—the top-left corner—will be modified so that the Anchored Sides maintain their initial distance from the edges of their parent controls).
From my reading of this, I would expect that the second truth overrides the first when Anchor is anything but AnchorStyles.None.
However, this doesn't seem to bear out in practice.
Consider the following:
// From ExampleForm.Designer.cs
this.label = new System.Drawing.Label();
this.label.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.label.AutoSize = true;
this.label.Location = new System.Drawing.Point(600, 400);
this.label.Size = new System.Drawing.Size(170, 20);
this.label.Text = "[Populated at Runtime]";
this.label.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
// ...
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.label);
// ...
// Sometime after Form Initialization, this is called
void PopulateLabel() {
var oldRight = label.Right;
label.Text = "Hey here's some new text. It's pretty long so the control will have to resize";
// Without this next line, the Right Anchor distance is not maintained.
// label.Left -= (label.Right - oldRight);
System.Diagnostics.Debug.Assert(label.Anchor.HasFlag(AnchorStyles.Right) && label.Right == oldRight, "The label didn't stay anchored to the right");
}
Obviously I can work around this by tracking the distance manually, as above.
I just wonder if there isn't some way this is “supposed” to work that I'm doing wrong.
The one observation I have to offer is this: it works if the label is not anchored to the bottom.
Do I need to call Suspend/Resume/PerformLayout on the Label? on the Form?
Are the docs wrong?
Am I being foolishly naïve or completely misunderstanding something?
Do I need some sort of intermediary Control for this to work and the docs assume I know this?
To address some possible complications that show up in similar questions (or that I dreamt up):
rightToLeft is false,
Dock is DockStyle.None,
the label's Parent is the form itself, not an intermediary panel or other control.
the Margin seems irrelevant
Anchoring to the Top or Bottom seems irrelevant to Right not working.
System.Windows.Form.Button works as expected. I haven't tested other controls.
Try using a TableLayout, it tends to obey the Control layout properties better. E.g:
public class MyForm : Form {
Label label = new Label() { BackColor = Color.Blue, ForeColor = Color.White };
public MyForm() {
TableLayoutPanel panel = new TableLayoutPanel() { BackColor = Color.Green };
panel.ColumnCount = 1;
panel.RowCount = 1;
panel.Controls.Add(label, 0, 0);
panel.Dock = DockStyle.Bottom;
panel.AutoSize = true;
panel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
panel.Controls.Add(label);
//this.label.Anchor = AnchorStyles.Right | AnchorStyles.Top;// | AnchorStyles.Bottom; // ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
//this.label.Dock = DockStyle.Fill;
this.label.Dock = DockStyle.Right;
this.label.AutoSize = true;
this.label.Margin = Padding.Empty;
//this.label.Location = new System.Drawing.Point(600, 400);
//this.label.Size = new System.Drawing.Size(170, 20);
this.label.Text = "[Populated at Runtime]";
//this.label.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
// ...
//this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
//this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
//this.Controls.Add(this.label);
this.Controls.Add(panel);
// ...
Button btn = new Button { Text = "Change text" };
btn.Click += delegate {
PopulateLabel();
};
Controls.Add(btn);
}
// Sometime after Form Initialization, this is called
void PopulateLabel() {
var oldRight = label.Right;
label.Text = "Hey here's some new text. It's pretty long so the control will have to resize";
// Without this next line, the Right Anchor distance is not maintained.
// label.Left -= (label.Right - oldRight);
//System.Diagnostics.Debug.Assert(label.Anchor.HasFlag(AnchorStyles.Right) && label.Right == oldRight, "The label didn't stay anchored to the right");
}
}
I have form in WinForms that looks like
this
I want the user to be able to resize the form. Buttons would stay the same size and datagridviews would grow when he does this.
Right now, datagridviews are colliding with buttons and It looks pretty ugly.
I want datagridviews to grow, but not collide with buttons.
I've tried many different combinations of code and It doesn't work like I wanted.
I want buttons to be between datagridviews.
Designer:
//
// dataGridView1
//
this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Location = new System.Drawing.Point(13, 60);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.RowTemplate.Height = 24;
this.dataGridView1.Size = new System.Drawing.Size(291, 326);
this.dataGridView1.TabIndex = 0;
//
// dataGridView2
//
this.dataGridView2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dataGridView2.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView2.Location = new System.Drawing.Point(566, 60);
this.dataGridView2.Name = "dataGridView2";
this.dataGridView2.RowTemplate.Height = 24;
this.dataGridView2.Size = new System.Drawing.Size(284, 326);
this.dataGridView2.TabIndex = 1;
//
// button1
//
this.button1.Anchor = System.Windows.Forms.AnchorStyles.None;
this.button1.Location = new System.Drawing.Point(375, 93);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(121, 83);
this.button1.TabIndex = 2;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
//
// button2
//
this.button2.Anchor = System.Windows.Forms.AnchorStyles.None;
this.button2.Location = new System.Drawing.Point(375, 187);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(121, 83);
this.button2.TabIndex = 3;
this.button2.Text = "button2";
this.button2.UseVisualStyleBackColor = true;
//
// button3
//
this.button3.Anchor = System.Windows.Forms.AnchorStyles.None;
this.button3.Location = new System.Drawing.Point(375, 281);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(121, 83);
this.button3.TabIndex = 4;
this.button3.Text = "button3";
this.button3.UseVisualStyleBackColor = true;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(862, 398);
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.dataGridView2);
this.Controls.Add(this.dataGridView1);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).EndInit();
this.ResumeLayout(false);
Try a TableLayoutPanel. You can define 3 columns, the first one set to 50%, the second one to the width of your buttons (or set to AutoSize, initially set it to an absolute or percentage value, then place your buttons. One placed go back and change to autosize otherwise the column will shrink to nothing if there's nothing in the column) and the third to 50%. Then you'll need at least 3 rows, 1 row per button.
Put your first DataGridView in Cell 0,0 (Col 0, Row 0) and set RowSpan to 3. Put your second DataGridView in Cell 2,0 (Col 2, Row 0) and, again, set RowSpan to 3. Then in the middle column (col 1) put your 3 buttons, one in each row. You can remove anchoring at that point so the buttons float in the middle of the column. Set your datagridviews to DockStyle.Fill and you shouldn't have any issues with the DataGridRow overlapping the buttons.
Here's a couple of screenshots.
Use the Anchor Property to your Datagridview and buttons.
I have a problem with a FlowLayoutPanel and I don't know how to solve it.
I'm placing two FlowLayoutPanels inside another; the second inner flp has 3 buttons inside.
The properties from FlowLayoutPanel child are:
FlowDirection = LeftToRight;
AutoSize = true;
AutoSizeMode = GrowAndShrink;
WrapContents = true;
Now I set for each button the FlowBreak property to true, however the behavior I see is not the one I want, I want the FlowLayoutPanel to shrink to the width of the buttons,
Changing FlowDirection to UpToDown is not an option.
Anyone know why the AutoSize is not working?
this is the code.
//
//FlowLayoutPanel1
//
this.FlowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.FlowLayoutPanel1.Controls.Add(this.FlowLayoutPanel3);
this.FlowLayoutPanel1.Location = new System.Drawing.Point(84, 77);
this.FlowLayoutPanel1.MinimumSize = new System.Drawing.Size(10, 10);
this.FlowLayoutPanel1.Name = "FlowLayoutPanel1";
this.FlowLayoutPanel1.Size = new System.Drawing.Size(308, 265);
this.FlowLayoutPanel1.TabIndex = 0;
//
//FlowLayoutPanel3
//
this.FlowLayoutPanel3.AutoSize = true;
this.FlowLayoutPanel3.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.FlowLayoutPanel3.Controls.Add(this.Button1);
this.FlowLayoutPanel3.Controls.Add(this.Button2);
this.FlowLayoutPanel3.Controls.Add(this.Button3);
this.FlowLayoutPanel3.Location = new System.Drawing.Point(127, 3);
this.FlowLayoutPanel3.MinimumSize = new System.Drawing.Size(10, 10);
this.FlowLayoutPanel3.Name = "FlowLayoutPanel3";
this.FlowLayoutPanel3.Size = new System.Drawing.Size(162, 87);
this.FlowLayoutPanel3.TabIndex = 1;
//
//Button1
//
this.FlowLayoutPanel3.SetFlowBreak(this.Button1, true);
this.Button1.Location = new System.Drawing.Point(3, 3);
this.Button1.Name = "Button1";
this.Button1.Size = new System.Drawing.Size(75, 23);
this.Button1.TabIndex = 0;
this.Button1.Text = "Button1";
this.Button1.UseVisualStyleBackColor = true;
//
//Button2
//
this.FlowLayoutPanel3.SetFlowBreak(this.Button2, true);
this.Button2.Location = new System.Drawing.Point(3, 32);
this.Button2.Name = "Button2";
this.Button2.Size = new System.Drawing.Size(75, 23);
this.Button2.TabIndex = 1;
this.Button2.Text = "Button2";
this.Button2.UseVisualStyleBackColor = true;
//
//Button3
//
this.Button3.Location = new System.Drawing.Point(3, 61);
this.Button3.Name = "Button3";
this.Button3.Size = new System.Drawing.Size(75, 23);
this.Button3.TabIndex = 2;
this.Button3.Text = "Button3";
this.Button3.UseVisualStyleBackColor = true;
It is a bug, it's been around for a very long time. The issue is that the layout engine for FlowLayoutPanel calculates the width of the first row wrong, including the width of the 2nd control, even though it got wrapped to the second row.
The workaround is silly but effective, add a dummy Panel with a Width of 0 after the 1st control. If you are doing this with the designer then drop it first and drag it in the right place, to the right of the 1st control. Then set its Margin to (0, 0, 0, 0) and Size to (0, 0) in the Properties window.
I don't believe the FlowLayoutPanel was designed to do what you're trying to do.
A TableLayoutPanel would probably be better suited. Add a TableLayoutPanel with a single column, and add each button to a row.
Edit: I found a hackish work around. After the first button, create a Panel with the size of 0,0 and the margin of 0,0. Make sure that FlowBreak is set to false.
Edit: You only need to create one panel, after the first button, not one for each.
Not a solution, but a workaround. It looks like you are trying to simulate behavior of TableLayoutPanel by using flow breaks in FlowLayoutPanel. Did you try using TableLayoutPanel instead? According to your screenshots in the comments, it should work perfectly for your needs.
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.
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();
I have a winform app in which I have a panel control.
I want to be able to scroll inside the panel and place controls vertically more then the current height of the control and then have a scroll which will help me to see all the controls, how can I achieve that?
This is the designer code as well, in case someone wants to take a look at the code:
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// panel1
//
this.panel1.AutoScroll = true;
this.panel1.BackColor = System.Drawing.SystemColors.ControlLightLight;
this.panel1.Location = new System.Drawing.Point(12, 12);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(267, 365);
this.panel1.TabIndex = 0;
//
// Form2
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(456, 410);
this.Controls.Add(this.panel1);
this.Name = "Form2";
this.Text = "Form2";
this.ResumeLayout(false);
}
Since you have AutoScroll = true, you shouldn't have to do anything. Any control that you place in the panel that is below the visible boundary will automatically create the appropriate scroll distance in the panel.
If you want to manually override that, set AutoScroll = false and set the size of the canvas yourself using the AutoScrollMinSize property, example:
panel1.AutoScrollMinSize = new Size(0, 1200);
You might want to consider anchoring the panel to the four sides of the form as well, or dock-fill, since it looks like a resizable form. Again, the panel will handle the scrollbar size for you.
Try this out for loading other forms in panels of MDIForm. It works perfectly.
myForm.TopLevel = false;
myForm.AutoScroll = true;
main_panel.Controls.Clear();
main_panel.Controls.Add(myForm);
main_panel.AutoScrollMinSize = new Size(0, myForm.Height);
myForm.Show();