TableLayoutPanel sizing

无人久伴 提交于 2019-11-30 02:37:50

问题


I may not be using the right control for what I want. I'm filling a table with controls and I want each column to automatically size to the controls contained within it. For example, a column of textboxes will be wider than a column of checkboxes. I don't want to fiddle with measuring if I can help it, due to the complexities of different OS, different DPI, different fonts, etc. The table can expand horizontally to fit the controls, with a scrollbar. How is this possible with a TableLayoutPanel - or some other control?

Thanks.

Edited to add code:

    private void UpdateLocations()
    {
        tableLayoutPanel1.RowCount = CurrentSchedule.location.Length + 1;
        tableLayoutPanel1.ColumnCount = 7;
        int row = 1;
        int timeWidth = TextRenderer.MeasureText("00:00:00x", tableLayoutPanel1.Font).Width;

        Label lab = new Label();
        lab.Text = "Location";
        tableLayoutPanel1.Controls.Add(lab, 0, 0);

        lab = new Label();
        lab.Text = "Arrive";
        tableLayoutPanel1.Controls.Add(lab, 1, 0);

        lab = new Label();
        lab.Text = "Depart";
        tableLayoutPanel1.Controls.Add(lab, 2, 0);

        lab = new Label();
        lab.Text = "Pass?";
        tableLayoutPanel1.Controls.Add(lab, 3, 0);

        lab = new Label();
        lab.Text = "Path";
        tableLayoutPanel1.Controls.Add(lab, 4, 0);

        lab = new Label();
        lab.Text = "Plat";
        tableLayoutPanel1.Controls.Add(lab, 5, 0);

        lab = new Label();
        lab.Text = "Line";
        tableLayoutPanel1.Controls.Add(lab, 6, 0);

        foreach (location loc in CurrentSchedule.location)
        {
            TextBox tb = new TextBox();
            tb.Text = loc.locationID;
            tableLayoutPanel1.Controls.Add(tb, 0, row);

            tb = new TextBox();
            tb.Text = loc.arrivalTime;
            tb.Width = timeWidth;
            tableLayoutPanel1.Controls.Add(tb, 1, row);

            tb = new TextBox();
            tb.Text = loc.departureTime;
            tb.Width = timeWidth;
            tableLayoutPanel1.Controls.Add(tb, 2, row);

            CheckBox cb = new CheckBox();
            cb.Checked = loc.passingTime;
            tableLayoutPanel1.Controls.Add(cb, 3, row);

            tb = new TextBox();
            tb.Text = loc.pathCode;
            tableLayoutPanel1.Controls.Add(tb, 4, row);

            tb = new TextBox();
            tb.Text = loc.platformCode;
            tableLayoutPanel1.Controls.Add(tb, 5, row);

            tb = new TextBox();
            tb.Text = loc.lineCode;
            tableLayoutPanel1.Controls.Add(tb, 6, row);

            row++;
        }
        /*for (int idx = 0; idx < tableLayoutPanel1.RowCount; idx++)
        {
            tableLayoutPanel1.RowStyles[idx].SizeType = SizeType.AutoSize;
        }
        for (int idx = 0; idx < tableLayoutPanel1.ColumnCount; idx++)
        {
            tableLayoutPanel1.ColumnStyles[idx].SizeType = SizeType.AutoSize;
        }*/
    }

(Yes it needs heavy refactoring - I'm just trying to get it to work first)

The commented out bits cause out of bounds exceptions, even though logically (to me) it shouldn't. The range appears limited to whatever I set at design time, not at runtime.


回答1:


Sorry, but what's wrong with having the columns set to Autosize? That's what TableLayoutPanel does, size columns to the fit the controls within it. Expanding the table and having a scrollbar would require you to set the tables Autosize property to true, then sit the TableLayoutPanel within another panel that has scrollbars enabled. But the column sizing should work out of the box if unless I'm misunderstanding your requirements.

Just to make sure, you are going to the columns property and setting each column's SizeType to AutoSize right? Not just the AutoSize property of the table itself?

is this what you want?

-Post code:

Thanks for the code. I'd suggest that you use designer to do a lot of this. At least to set up the columns, set them to autosize, and add the heading labels.

You also might want to check out the Datagrid control and bind that to your location list.

To get this method working though:

1) the reason your columns look the same size is because the heading labels you're using aren't autosizing. They're all x pixels wide and that's stretching the columns. Do this:

Label lab = new Label();
lab.AutoSize = true;
lab.Text = "Location";
tableLayoutPanel1.Controls.Add(lab, 0, 0);

You'll also need to set the AutoSize property to true on the CheckBox control and any other labels you add as content.

2) Setting the RowCount and ColumnCount won't affect the RowStyles or ColumnStyles collection. You've got 7 Columns but only 2 ColumnStyles. Try:

tableLayoutPanel1.ColumnStyles.Clear();
for (int i = 0; i < tableLayoutPanel1.ColumnCount; i++)
{
   tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
}

tableLayoutPanel1.RowStyles.Clear();
for (int i = 0; i < tableLayoutPanel1.RowCount; i++)
{
   tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
}

Only other thing to look out for is that some controls will be misaligned in the rows (labels appear too high for example). To fix that set the Margin property, normally to 3,6,3,0 to align them with textboxes and checkboxes etc.




回答2:


You'll need to handle the ControlAdded event, then resize the column if the new control's width is greater than the column's width...

You say you don't want to fiddle with measuring, but if you're resizing, you kind of have to. Fonts and such shouldn't come into it if you're careful about the TextAlign of your checkboxes etc...




回答3:


You could use multiple splitContainers one inside another's panel. But don't use many nested panels, you might get resize/redraw issues like this.

You can find many examples if you want to use SplitContainer.



来源:https://stackoverflow.com/questions/7269649/tablelayoutpanel-sizing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!