2

I want to create a form with columns of buttons. The buttons should fit all the width of form. Also I want to push it to top of form as possible. It should look like this:

|----------------------------------|
|           Form caption           |
|----------------------------------|
||--------------------------------||
||Button0                         ||
||--------------------------------||
||--------------------------------||
||Button1                         ||
||--------------------------------||
||--------------------------------||
||Button2                         ||
||--------------------------------||
|                                  |
|                                  |
|           free space             |
|                                  |
|----------------------------------|

Usually I work with C++/Qt and it's rich of layouts. As I understand c# is not so good in that. I've found that TableLayoutPanel with 1 column can do that. The only thing I want is to push all the buttons to top. So I've created the following code:

// panelButton was created by VS with following params:
this.panelButton = new System.Windows.Forms.TableLayoutPanel();
this.panelButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.panelButton.Name = "panelButton";
this.panelButton.RowCount = 1;


for(int i = 0;i < 3;i ++)
{
    Button button = new Button();
    button.Dock = DockStyle.Fill;
    button.Height = 40;
    button.Text = "Button" + i;
    button.Click += new EventHandler(delegate(object o, EventArgs args) {});
    panelButton.Controls.Add(button, 0, i);
}

But the layout I get is wrong - button0 and button1 are 40px height as expected but button2 fills all the space when I expect it will be 40px.

ADDED: I've found a workaround. I add

panelButton.Controls.Add(new Control(), 0, rowIndex);

after the loop and so thet works as expected.

folibis
  • 12,048
  • 6
  • 54
  • 97
  • Set `button.Dock` to `System.Windows.Forms.DockStyle.Top` – Reza Aghaei Nov 06 '16 at 11:15
  • By the way, layout is not related to `C#` it's the job of UI frameworks like `Windows Forms` and `WPF` which both work well. – Reza Aghaei Nov 06 '16 at 11:18
  • @RezaAghaei, than also doesn't work. All the buttons are 40px height but the layout 's height doesn't grow. If height of all buttons > height of panel it add scrollbars – folibis Nov 06 '16 at 11:18
  • If you want panel grows instead of showing scrollbars, set its AutoSize to true. – Reza Aghaei Nov 06 '16 at 11:22
  • Ok, the trick with `AutoSize = true` + `panelButton.Dock = DockStyle.Top` works as expected. Thanks! Can you add your comment as answer? – folibis Nov 06 '16 at 11:24
  • The only thing that not good is that it doesn't add scrollbars – folibis Nov 06 '16 at 11:26
  • See the answer, it describes about autoscroll and autosize. – Reza Aghaei Nov 06 '16 at 11:30
  • To see an example about when `TableLayoutPanel` is useful take a look at this post: [Dynamic button creation & placing them in a predefined order using c#](https://stackoverflow.com/questions/33968993) – Reza Aghaei Nov 06 '16 at 11:45
  • To see a `FlowLayoutPanel` example take a look at this post: [Multi-Row Autosize Scrollable FlowLayoutPanel](https://stackoverflow.com/questions/32564463) – Reza Aghaei Nov 06 '16 at 11:48

1 Answers1

3

You don't need to use TableLayoutPanel for such task. It's enough to use a Panel and add buttons to it. For each button you need to set its Dock to Top.

If you want the panel grows instead of showing scrolls, you can set the panel AutoSize=true and AutoScroll=false.

If you want scrollbars, just set it's AutoSize=false and AutoScroll=true.

Example 1

An auto sized form containing a panel which has a list of buttons:(Screenshot)

public Form1()
{
    InitializeComponent();
    this.Controls.Clear();
    this.AutoSize = true;
    this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
    var panel = new Panel();
    panel.Dock = DockStyle.Fill;
    panel.AutoScroll = false;
    panel.AutoSize = true;
    panel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
    this.Controls.Add(panel);
    for (int i = 0; i < 20; i++)
    {
        var buttun = new Button();
        buttun.Text = string.Format("Button {0}", i + 1);
        buttun.Dock = DockStyle.Top;
        panel.Controls.Add(buttun);
    }
}

Example 2

A form containing an auto-scroll panel which has a list of buttons:(Screenshot)

public Form1()
{
    InitializeComponent();
    this.Controls.Clear();
    this.AutoSize = false;
    var panel = new Panel();
    panel.Dock = DockStyle.Fill;
    panel.AutoScroll = true;
    this.Controls.Add(panel);
    for (int i = 0; i < 20; i++)
    {
        var buttun = new Button();
        buttun.Text = string.Format("Button {0}", i + 1);
        buttun.Dock = DockStyle.Top;
        panel.Controls.Add(buttun);
    }
}

Note: Layout is not related to C# it's the job of UI frameworks like Windows Forms. To learn more about layout in windows forms take a look at these documents:

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398