Search code examples
c#winformstablelayoutpanel

How to dynamically scale control size in a TableLayoutPanel


My goal is to have a grid of buttons which represent my 2d array using a TableLayoutPanel.

Currently I can get the correct amount of columns and rows and it adds the buttons in the right place.

The problem I am having is the scaling of the buttons. I've already tried other solutions but they don't seem to work.

Filling the table

int[,] testArr = new int[,] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };

        tableLayoutPanel_TopView.ColumnCount = testArr.GetLength(0);
        tableLayoutPanel_TopView.RowCount = testArr.GetLength(1);
        tableLayoutPanel_TopView.AutoSize = true;

        for (int y = 0; y < testArr.GetLength(1); y++)
        {
            for (int x = 0; x < testArr.GetLength(0); x++)
            {
                Button btn = new Button
                {
                    Text = x.ToString() + "." + y.ToString(),
                    Dock = DockStyle.Fill,
                };
                tableLayoutPanel_TopView.Controls.Add(btn);
            }
        }

        Single percHeight = ((Single)1 / (Single)tableLayoutPanel_TopView.RowStyles.Count) * 100;
        Single percWidth = ((Single)1 / (Single)tableLayoutPanel_TopView.ColumnStyles.Count) * 100;

        foreach (ColumnStyle style in tableLayoutPanel_TopView.ColumnStyles)
        {
            style.SizeType = SizeType.Percent;
            style.Width = percWidth;
        }

        foreach (RowStyle style in tableLayoutPanel_TopView.RowStyles)
        {
            style.SizeType = SizeType.Percent;
            style.Height = percHeight;
        }

TableLayoutPanel settings

        this.tableLayoutPanel_TopView.ColumnCount = 1;
        this.tableLayoutPanel_TopView.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
        this.tableLayoutPanel_TopView.Dock = System.Windows.Forms.DockStyle.Fill;
        this.tableLayoutPanel_TopView.Location = new System.Drawing.Point(3, 16);
        this.tableLayoutPanel_TopView.Name = "tableLayoutPanel_TopView";
        this.tableLayoutPanel_TopView.RowCount = 1;
        this.tableLayoutPanel_TopView.RowStyles.Add(new System.Windows.Forms.RowStyle());
        this.tableLayoutPanel_TopView.Size = new System.Drawing.Size(638, 463);
        this.tableLayoutPanel_TopView.TabIndex = 0;

However, this gives the following result:

Current table

As you can see, the width and the height of each button only seems to make sense starting from the second column and second row. What can I do so that each button has the same size?


Solution

  • Solution

    I've fixed it by clearing both the ColumnStyles and RowStyles and adding a new style for each row and column. Each style has it's SizeType set to Percent and the width/height is calculated.

    Code

    I have replaced testArr with sortedContainers, a collection the function was made for.

           // above code hasn't changed
            Single percHeight = ((Single)1 / (Single)tableLayoutPanel_TopView.RowStyles.Count) * 100;
            Single percWidth = ((Single)1 / (Single)tableLayoutPanel_TopView.ColumnStyles.Count) * 100;
    
            tableLayoutPanel_TopView.ColumnStyles.Clear();
            tableLayoutPanel_TopView.RowStyles.Clear();
    
            for (int x = 0; x < sortedContainers.Width; x++)
            {
                tableLayoutPanel_TopView.ColumnStyles.Add(new ColumnStyle
                {
                    SizeType = SizeType.Percent,
                    Width = percWidth
                });
            }
    
            for (int y = 0; y < sortedContainers.Length; y++)
            {
                tableLayoutPanel_TopView.RowStyles.Add(new RowStyle
                {
                    SizeType = SizeType.Percent,
                    Height = percHeight
                });
            }