我一直在与此作斗争,并且发现许多其他人也在使用TableLayoutPanel(.net 2.0 Winforms)。
问题
我正在尝试使用一个'空白'tablelayoutpanel,它定义了10列,然后在运行时以编程方式添加控件行(即每个单元格一个控件)。
有人可能认为它应该像
一样简单myTableLayoutPanel.Controls.Add(myControl, 0 /* Column Index */, 0 /* Row index */);
但是(对我来说)不添加行。所以也许可以添加一种行样式
myTableLayoutPanel.RowStyles.Clear();
myTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 30F));
但这也不起作用。我已经挖掘并发现myTableLayoutPanel.RowCount
用法从设计时间到运行时间发生了变化,因此执行myTableLayoutPanel.RowCount++;
实际上并没有添加另一行,甚至在为其添加RowStyle条目之前/之后!
我遇到的另一个相关问题是控件将被添加到显示器中,但它们都只是在TableLayoutPanel的0,0点处渲染,另外它们甚至不被限制在它们所在的Cell范围内应该显示在内(即使用Dock = DockStyle.Fill它们仍然显得太大/太小)。
有人有一个添加行和放大器的工作示例吗?在运行时控制?
答案 0 :(得分:71)
我上周刚刚这样做了。将GrowStyle
上的TableLayoutPanel
设置为AddRows
或AddColumns
,然后您的代码应该有效:
// 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 */);
以下是一些与您正在执行的操作类似的工作代码:
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++;
}
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;
答案 1 :(得分:28)
这是一个奇怪的设计,但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;
}
其他想法
我从未使用DockStyle.Fill
来控制填充网格中的单元格;我通过设置控件的Anchors
属性来完成此操作。
如果您要添加大量控件,请确保在整个过程中调用SuspendLayout
和ResumeLayout
,否则在每个控件出现后整个表单都会重新启动时,事情会变慢加入。
答案 2 :(得分:16)
这是我在两列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;
}
标签控件位于左列,值控件位于右列。控件通常是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;
这一切都很好。您应该知道,使用Controls属性(至少在某些版本的框架中)动态地从TableLayoutPanel处理控件时似乎存在一些问题。如果你需要删除控件,我建议处理整个TableLayoutPanel并创建一个新的。
答案 3 :(得分: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
}
最后,运行代码。
答案 4 :(得分:4)
我只是查看了我的代码。在一个应用程序中,我只是添加控件,但没有指定索引,完成后,我只是遍历行样式并将大小类型设置为AutoSize。所以只是添加它们而不指定索引似乎按预期添加行(假设GrowStyle设置为AddRows)。
在另一个应用程序中,我清除控件并将RowCount属性设置为所需的值。这不会添加RowStyles。然后我添加我的控件,这次指定索引,并添加一个新的RowStyle(RowStyles.Add(new RowStyle(...)
),这也有效。
所以,选择其中一种方法,它们都有效。我记得表布局面板给我带来的麻烦。
答案 5 :(得分:0)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim dt As New DataTable
Dim dc As DataColumn
dc = New DataColumn("Question", System.Type.GetType("System.String"))
dt.Columns.Add(dc)
dc = New DataColumn("Ans1", System.Type.GetType("System.String"))
dt.Columns.Add(dc)
dc = New DataColumn("Ans2", System.Type.GetType("System.String"))
dt.Columns.Add(dc)
dc = New DataColumn("Ans3", System.Type.GetType("System.String"))
dt.Columns.Add(dc)
dc = New DataColumn("Ans4", System.Type.GetType("System.String"))
dt.Columns.Add(dc)
dc = New DataColumn("AnsType", System.Type.GetType("System.String"))
dt.Columns.Add(dc)
Dim Dr As DataRow
Dr = dt.NewRow
Dr("Question") = "What is Your Name"
Dr("Ans1") = "Ravi"
Dr("Ans2") = "Mohan"
Dr("Ans3") = "Sohan"
Dr("Ans4") = "Gopal"
Dr("AnsType") = "Multi"
dt.Rows.Add(Dr)
Dr = dt.NewRow
Dr("Question") = "What is your father Name"
Dr("Ans1") = "Ravi22"
Dr("Ans2") = "Mohan2"
Dr("Ans3") = "Sohan2"
Dr("Ans4") = "Gopal2"
Dr("AnsType") = "Multi"
dt.Rows.Add(Dr)
Panel1.GrowStyle = TableLayoutPanelGrowStyle.AddRows
Panel1.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single
Panel1.BackColor = Color.Azure
Panel1.RowStyles.Insert(0, New RowStyle(SizeType.Absolute, 50))
Dim i As Integer = 0
For Each dri As DataRow In dt.Rows
Dim lab As New Label()
lab.Text = dri("Question")
lab.AutoSize = True
Panel1.Controls.Add(lab, 0, i)
Dim Ans1 As CheckBox
Ans1 = New CheckBox()
Ans1.Text = dri("Ans1")
Panel1.Controls.Add(Ans1, 1, i)
Dim Ans2 As RadioButton
Ans2 = New RadioButton()
Ans2.Text = dri("Ans2")
Panel1.Controls.Add(Ans2, 2, i)
i = i + 1
'Panel1.Controls.Add(Pan)
Next
答案 6 :(得分:0)
这非常适合在TableLayoutPanel中添加行和控件。
在设计页面中定义一个包含3列的空白Tablelayoutpanel
Dim TableLayoutPanel3 As New TableLayoutPanel()
TableLayoutPanel3.Name = "TableLayoutPanel3"
TableLayoutPanel3.Location = New System.Drawing.Point(32, 287)
TableLayoutPanel3.AutoSize = True
TableLayoutPanel3.Size = New System.Drawing.Size(620, 20)
TableLayoutPanel3.ColumnCount = 3
TableLayoutPanel3.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single
TableLayoutPanel3.BackColor = System.Drawing.Color.Transparent
TableLayoutPanel3.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 26.34146!))
TableLayoutPanel3.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 73.65854!))
TableLayoutPanel3.ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 85.0!))
Controls.Add(TableLayoutPanel3)
创建按钮btnAddRow以在每次点击时添加行
Private Sub btnAddRow_Click(sender As System.Object, e As System.EventArgs) Handles btnAddRow.Click
TableLayoutPanel3.GrowStyle = TableLayoutPanelGrowStyle.AddRows
TableLayoutPanel3.RowStyles.Add(New RowStyle(SizeType.Absolute, 20))
TableLayoutPanel3.SuspendLayout()
TableLayoutPanel3.RowCount += 1
Dim tb1 As New TextBox()
Dim tb2 As New TextBox()
Dim tb3 As New TextBox()
TableLayoutPanel3.Controls.Add(tb1 , 0, TableLayoutPanel3.RowCount - 1)
TableLayoutPanel3.Controls.Add(tb2, 1, TableLayoutPanel3.RowCount - 1)
TableLayoutPanel3.Controls.Add(tb3, 2, TableLayoutPanel3.RowCount - 1)
TableLayoutPanel3.ResumeLayout()
tb1.Focus()
End Sub
答案 7 :(得分:0)
我刚遇到一个相关的问题(这就是我发现这个帖子的方式),我动态添加的行和列样式没有生效。我通常将SuspendLayout()/ ResumeLayout()视为优化,但在这种情况下,将代码包装在其中使得行和列的行为正确。