folibis folibis - 27 days ago 10
C# Question

Set button fill all the width & top of parent in WinForms

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.

Answer

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:

Comments