TableLayoutPanel 大小调整

13

我可能没有使用正确的控件来实现我的需求。我正在用控件填充一个表格,并希望每一列根据其中包含的控件自动调整大小。例如,文本框列将比复选框列宽。我不想通过测量来解决问题,因为涉及到不同操作系统、不同DPI、不同字体等复杂性。表格可以水平扩展以适应控件,并带有滚动条。如何在TableLayoutPanel或其他控件中实现这一点?

谢谢。

编辑以添加代码:

    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;
        }*/
    }

(是的,它需要进行大量的重构 - 我只是试图先让它能正常工作)

尽管在逻辑上(对我来说)不应该出现数组越界异常,但被注释掉的部分确实会导致此问题。范围似乎被限制为设计时设置的内容,而非运行时。


你有多少列? - CharithJ
如果一个特定的列只有复选框,为什么需要调整大小? - CharithJ
列不需要动态调整大小,而是在添加控件时设置为特定的大小。目前我正在使用自动大小,这意味着所有列的宽度都相同。 - GeoffM
3个回答

21

抱歉,将列设置为AutoSize有什么问题吗?这就是TableLayoutPanel所做的,将列大小调整为适合其中控件的大小。如果要扩展表格并具有滚动条,则需要将表的AutoSize属性设置为true,然后将TableLayoutPanel放置在启用滚动条的另一个面板中。但是,如果我没有误解您的要求,列的大小调整应该可以正常工作。

只是为了确认,您要转到列属性,并将每个列的SizeType设置为AutoSize,对吧?而不仅仅是表本身的AutoSize属性?

enter image description here

这符合您的要求吗?

-发帖代码:

感谢您的代码。我建议您使用设计器完成大部分工作,至少设置列,将它们设置为自动调整大小,并添加标题标签。

您还可以查看DataGrid控件并将其绑定到您的位置列表。

要使此方法起作用:

1)您的列看起来相同大小的原因是您使用的标题标签不是自动调整大小的。它们都是x像素宽,这会拉伸列。请按照以下步骤操作:

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

你还需要在CheckBox控件上设置AutoSize属性为true,并对添加的任何其他标签设置AutoSize属性为true。

2) 设置RowCount和ColumnCount不会影响RowStyles或ColumnStyles集合。你有7个列,但只有2个ColumnStyles。尝试:

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

需要注意的另一个问题是,在某些行中,某些控件可能不对齐(例如,标签显示过高)。要解决这个问题,请设置Margin属性,通常为3,6,3,0,以使它们与文本框和复选框等控件对齐。


是的,那就是我想要的。但是根据我读到的有关它如何计算宽度的内容(“GetPreferredWidth”),它不应该这样做……也许我没有以正确的组合设置属性。然而,我在设置行和列方面遇到了问题-请参见我上面编辑过的代码。 - GeoffM
哎呀!标题标签的宽度,你发现了!其他部分的答案也很有道理。谢谢。 - GeoffM

0

你需要处理ControlAdded事件,如果新控件的宽度大于列的宽度,则调整列的大小...

你说你不想去测量,但是如果你要调整大小,你必须这样做。如果你对复选框等的TextAlign小心谨慎,字体等就不应该成为问题...


我有点希望能够获得类似于HTML表格功能的自动调整列(和行)大小的功能。我担心在Windows Vista上工作时,发现Win7的边框比预期厚2px(或者主题或其他参数)。如果仅仅使用控件的宽度和高度足够可靠,那么我将使用它。 - GeoffM
控件的宽度应该足够可靠。话虽如此,我曾经看到其他开发者创建的窗体应用在Windows 7和XP上显示不同,所以我不能保证这种方法一定有效 :-) - andyhasit

0

您可以在另一个面板中使用多个SplitContainers。但是不要使用太多嵌套的面板,否则可能会出现调整大小/重绘问题,例如this

如果您想使用SplitContainer,可以找到许多示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接