2009-07-17 111 views
74

我一直在爭取一段時間,並發現其他一些人也與TableLayoutPanel(.net 2.0 Winforms)發生衝突。Winforms TableLayoutPanel以編程方式添加行

問題

我試圖採取一個「空白」 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

添加一個RowStyle實際上會增加RowStyles.Count() – 2015-12-18 15:58:43

回答

4

我只是看着我的代碼。在一個應用程序中,我只是添加控件,但沒有指定索引,並且完成後,我只是遍歷行樣式並將大小類型設置爲AutoSize。所以只是在不指定索引的情況下添加它們似乎會按照預期添加行(假設GrowStyle設置爲AddRows)。

在另一個應用程序中,我清除控件並將RowCount屬性設置爲所需的值。這不會添加RowStyles。然後我添加我的控件,這次指定索引,並添加一個新的RowStyle(RowStyles.Add(new RowStyle(...)),這也適用。

因此,選擇這些方法之一,他們都工作。我記得桌面佈局面板給我帶來的麻煩。

+0

我會給這些嘗試看看它是否表現自己! – Ash 2009-07-17 12:27:15

68

我剛剛在上週做了這個。在TableLayoutPanelAddRowsAddColumns,那麼你的代碼應該工作設置GrowStyle

// 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; 
+2

完美,簡單的例子。 – RandomInsano 2010-05-31 16:25:08

+2

感謝您的空佔位符行的想法!解決了我的尺寸問題。 – JNadal 2012-11-09 18:34:36

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並創建一個新的控件。

+0

這非常有幫助。我發現DockStyle.Fill屬性是必不可少的。而且,在計數過程中出錯也是非常容易的!另請注意,使用樣式設置的列和行大小。我發現當RowStyle設置爲AutoSize時,TextAlign設置(Top,Middle和Bottom中的一些無意的變化)表明該表以某種奇怪的方式生成額外的行,但事實並非如此。一旦你發現了這件事情,這件事情會非常好,但是到達那裏真是痛苦! – 2011-07-12 14:30:54

+0

正確的解決方案 – 2014-02-14 22:37:03

28

這是一個奇怪的設計,但TableLayoutPanel.RowCount屬性並不反映RowStyles集合的計數,對於ColumnCount屬性和ColumnStyles集合也是如此。

我發現我需要的代碼是在對RowStyles/ColumnStyles進行更改後手動更新RowCount/ColumnCount

下面是我使用的代碼示例:

/// <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屬性來完成此操作。

  • 如果你加入了大量的控件,請確保您撥打SuspendLayoutResumeLayout周圍的過程中,添加的每個控制後,整個形式重新鋪設否則事情會運行緩慢。

+2

如果它對任何人都有用,在我的情況下,我不得不在窗體加載時調用* tableLayoutPanel1.ColumnStyles.Clear(); *。 – John 2016-08-25 12:06:03

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

最後,運行代碼。

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 
0

我只是有一個相關的問題(這是我如何發現此線程),其中我動態添加的行和列樣式不起作用。我通常將SuspendLayout()/ ResumeLayout()視爲優化,但在這種情況下,將代碼封裝在它們中使行和列行爲正確。