22

I have a flowlayout as follows:

enter image description here

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.)

Antonio
  • 19,451
  • 13
  • 99
  • 197
David
  • 15,652
  • 26
  • 115
  • 156
  • `FLowLayout` is not designed for that. – SLaks May 15 '12 at 11:43
  • @SLaks can you recommend an alternative? – David May 15 '12 at 11:44
  • do you know that what are you trying to implement?? your first point contradicts second point regarding layout.. on which condition you will put them back according to your first condition??... rather than using flowlayout panel, put the control in panel and then use the anchor property or dock property as per your requirment.. – Niranjan Singh May 15 '12 at 11:53
  • @NiranjanKala Either one or the other was fine with regards to implementation. But I removed the second one just to keep you happy and keep the question relevant. – David May 15 '12 at 11:59
  • This is another of those cases where WPF wins. – Kendall Frey May 15 '12 at 15:18

8 Answers8

32

You can do it two ways but with some limitation of each one.

  1. Using Anchor property
  2. 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

  1. Add TableLayout Control, Set it’s Dock property to Fill.
  2. Add 1 Row with Size Type style Percent 100%
  3. Add 3 Columns Column1(Size Type – Percent(100%)), Column2(Size Type – Absolute(200px)), Column3(Size Type – Percent(100%)).
  4. Now Add Panel Control to Column2 and Set it’s Dock property to Fill
  5. 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..

Niranjan Singh
  • 18,017
  • 2
  • 42
  • 75
  • For me it was enough to put the AnchorStyle to `None` (no need to set left or anything else), I wonder if I am missing anything. – Antonio Sep 21 '15 at 09:25
  • 1
    if you are using that control in Table layout panel then it may work.. In case 2 it may be correctly work if you set AnchorStype to `None`. – Niranjan Singh Sep 22 '15 at 05:15
11

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.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
2

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);
0

Or you can use Grid layout instead.

sloth
  • 99,095
  • 21
  • 171
  • 219
Nickon
  • 9,652
  • 12
  • 64
  • 119
0

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);
0

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

Toto
  • 1
  • 1
0

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.

Ivan Ferrer Villa
  • 2,129
  • 1
  • 26
  • 23
-1
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
Martin Brisiak
  • 3,872
  • 12
  • 37
  • 51
Naveen
  • 1