Winforms TableLayoutPanel以编程方式添加行

Ash*_*Ash 81 .net c# runtime tablelayoutpanel winforms

我已经和它斗争了一段时间,并且发现许多其他人也在使用TableLayoutPanel(.net 2.0 Winforms).

问题

我试图采用一个'空白'tablelayoutpanel,它定义了10列,然后在运行时以编程方式添加控件行(即每个单元一个控件).

人们可能认为它应该如此简单

myTableLayoutPanel.Controls.Add(myControl, 0 /* Column Index */, 0 /* Row index */);
Run Code Online (Sandbox Code Playgroud)

但是(对我来说)不添加行.所以也许可以添加一行样式

myTableLayoutPanel.RowStyles.Clear();
myTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 30F));
Run Code Online (Sandbox Code Playgroud)

但这也不起作用.我已经挖掘并发现myTableLayoutPanel.RowCount使用情况从设计时间变为运行时间,因此myTableLayoutPanel.RowCount++;实际上并没有添加另一行,甚至在添加RowStyle条目之前/之后!

我遇到的另一个相关问题是控件将被添加到显示器,但它们都只是在TableLayoutPanel的点0,0处渲染,另外它们甚至不被限制在它们应该是的Cell边界内.显示在内(即使用Dock = DockStyle.Fill它们仍然显得太大/太小).

有人有一个在运行时添加行和控件的工作示例吗?

Bil*_*ver 73

我上周才这样做了.设置GrowStyleTableLayoutPanelAddRowsAddColumns,那么你的代码应工作:

// Adds "myControl" to the first column of each row
myTableLayoutPanel.Controls.Add(myControl1, 0 /* Column Index */, 0 /* Row index */);
myTableLayoutPanel.Controls.Add(myControl2, 0 /* Column Index */, 1 /* Row index */);
myTableLayoutPanel.Controls.Add(myControl3, 0 /* Column Index */, 2 /* Row index */);
Run Code Online (Sandbox Code Playgroud)

以下是一些与您正在执行的操作类似的工作代码:

    private Int32 tlpRowCount = 0;

    private void BindAddress()
    {
        Addlabel(Addresses.Street);
        if (!String.IsNullOrEmpty(Addresses.Street2))
        {
            Addlabel(Addresses.Street2);
        }
        Addlabel(Addresses.CityStateZip);
        if (!String.IsNullOrEmpty(Account.Country))
        {
            Addlabel(Address.Country);
        }
        Addlabel(String.Empty); // Notice the empty label...
    }

    private void Addlabel(String text)
    {            
        label = new Label();
        label.Dock = DockStyle.Fill;
        label.Text = text;
        label.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
        tlpAddress.Controls.Add(label, 1, tlpRowCount);
        tlpRowCount++;
    }
Run Code Online (Sandbox Code Playgroud)

TableLayoutPanel总是给我用一刀切.在上面的示例中,我提交的地址卡可能会增长或缩小,具体取决于具有地址行2或国家/地区的帐户.因为表格布局面板的最后一行或列会拉伸,我会在那里抛出空标签以强制换出一个新的空行,然后一切排好.

这是设计器代码,因此您可以看到我开始的表:

        //
        // tlpAddress
        // 
        this.tlpAddress.AutoSize = true;
        this.tlpAddress.BackColor = System.Drawing.Color.Transparent;
        this.tlpAddress.ColumnCount = 2;
        this.tlpAddress.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 25F));
        this.tlpAddress.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
        this.tlpAddress.Controls.Add(this.pictureBox1, 0, 0);
        this.tlpAddress.Dock = System.Windows.Forms.DockStyle.Fill;
        this.tlpAddress.Location = new System.Drawing.Point(0, 0);
        this.tlpAddress.Name = "tlpAddress";
        this.tlpAddress.Padding = new System.Windows.Forms.Padding(3);
        this.tlpAddress.RowCount = 2;
        this.tlpAddress.RowStyles.Add(new System.Windows.Forms.RowStyle());
        this.tlpAddress.RowStyles.Add(new System.Windows.Forms.RowStyle());
        this.tlpAddress.Size = new System.Drawing.Size(220, 95);
        this.tlpAddress.TabIndex = 0;
Run Code Online (Sandbox Code Playgroud)

  • 完美,简单的例子. (2认同)
  • 感谢空占位符行的想法!解决了我的尺寸问题. (2认同)

Bev*_*van 29

这是一个奇怪的设计,但该TableLayoutPanel.RowCount属性不反映RowStyles集合的数量,并且类似于ColumnCount属性和ColumnStyles集合.

我在代码中发现我需要的是在对RowCount/ ColumnCount进行更改后手动更新RowStyles/ ColumnStyles.

这是我用过的代码示例:

    /// <summary>
    /// Add a new row to our grid.
    /// </summary>
    /// The row should autosize to match whatever is placed within.
    /// <returns>Index of new row.</returns>
    public int AddAutoSizeRow()
    {
        Panel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
        Panel.RowCount = Panel.RowStyles.Count;
        mCurrentRow = Panel.RowCount - 1;
        return mCurrentRow;
    }
Run Code Online (Sandbox Code Playgroud)

其他想法

  • 我从来没有习惯DockStyle.Fill过控制填充网格中的单元格; 我通过设置Anchors控件的属性来完成此操作.

  • 如果你要添加很多控件,请确保调用SuspendLayoutResumeLayout围绕整个过程,否则在添加每个控件后整个表单都会重新启动时,事情会变慢.

  • 如果它对任何人都有用,在我的情况下,我必须在加载表单时调用*tableLayoutPanel1.ColumnStyles.Clear();*. (2认同)

Cor*_*rty 17

这是我的代码,用于向两列TableLayoutColumn添加新行:

private void AddRow(Control label, Control value)
{
    int rowIndex = AddTableRow();
    detailTable.Controls.Add(label, LabelColumnIndex, rowIndex);
    if (value != null)
    {
        detailTable.Controls.Add(value, ValueColumnIndex, rowIndex);
    }
}

private int AddTableRow()
{
    int index = detailTable.RowCount++;
    RowStyle style = new RowStyle(SizeType.AutoSize);
    detailTable.RowStyles.Add(style);
    return index;
}
Run Code Online (Sandbox Code Playgroud)

标签控件位于左列,值控件位于右列.控件通常是Label类型,其AutoSize属性设置为true.

我认为这不重要,但作为参考,这里是设置detailTable的设计器代码:

this.detailTable.ColumnCount = 2;
this.detailTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.detailTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.detailTable.Dock = System.Windows.Forms.DockStyle.Fill;
this.detailTable.Location = new System.Drawing.Point(0, 0);
this.detailTable.Name = "detailTable";
this.detailTable.RowCount = 1;
this.detailTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.detailTable.Size = new System.Drawing.Size(266, 436);
this.detailTable.TabIndex = 0;
Run Code Online (Sandbox Code Playgroud)

这一切都很好.您应该知道,使用Controls属性(至少在某些版本的框架中)动态地从TableLayoutPanel处理控件时似乎存在一些问题.如果你需要删除控件,我建议处理整个TableLayoutPanel并创建一个新的.


小智 7

在表单中创建一个包含两列的表格布局面板并命名tlpFields.

然后,只需将新控件添加到表格布局面板(在这种情况下,我在第1列中添加了5个标签,在第2列中添加了5个文本框).

tlpFields.RowStyles.Clear();  //first you must clear rowStyles

for (int ii = 0; ii < 5; ii++)
{
    Label l1= new Label();
    TextBox t1 = new TextBox();

    l1.Text = "field : ";

    tlpFields.Controls.Add(l1, 0, ii);  // add label in column0
    tlpFields.Controls.Add(t1, 1, ii);  // add textbox in column1

    tlpFields.RowStyles.Add(new RowStyle(SizeType.Absolute,30)); // 30 is the rows space
}
Run Code Online (Sandbox Code Playgroud)

最后,运行代码.


Ore*_*ost 4

我刚刚查看了我的代码。在一个应用程序中,我只是添加控件,但没有指定索引,完成后,我只是循环遍历行样式并将大小类型设置为 AutoSize。因此,仅添加它们而不指定索引似乎会按预期添加行(假设 GrowStyle 设置为 AddRows)。

在另一个应用程序中,我清除控件并将 RowCount 属性设置为所需的值。这不会添加行样式。然后我添加控件,这次指定索引,并添加一个新的 RowStyle ( RowStyles.Add(new RowStyle(...)),这也有效。

因此,选择其中一种方法,它们都有效。我记得表格布局面板让我头疼。