2009-07-17 37 views
74

Tôi đã chiến đấu với điều này một thời gian, và đã tìm thấy rằng một số người khác đấu tranh với TableLayoutPanel (net 2.0 Winforms).Winforms TableLayoutPanel thêm hàng lập trình

Vấn đề

Tôi đang cố gắng để có một TableLayoutPanel 'trống', trong đó có 10 cột được xác định, sau đó khi chạy theo chương trình thêm hàng của các điều khiển (ví dụ: một điều khiển mỗi tế bào).

Người ta có thể có thể nghĩ rằng nó nên càng đơn giản càng

myTableLayoutPanel.Controls.Add(myControl, 0 /* Column Index */, 0 /* Row index */); 

Nhưng đó (cho tôi) không thêm các hàng. Vì vậy, có thể thêm vào một phong cách hàng

myTableLayoutPanel.RowStyles.Clear(); 
myTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 30F)); 

Nhưng điều đó cũng không có tác dụng. Tôi đã đào xung quanh và phát hiện ra rằng những thay đổi sử dụng myTableLayoutPanel.RowCount từ thời gian thiết kế để chạy thời gian, do đó làm myTableLayoutPanel.RowCount++; không thực sự thêm một hàng khác, thậm chí không trước/sau khi thêm một mục RowStyle cho nó!

Một vấn đề liên quan khác mà tôi đang gặp phải là các điều khiển sẽ được thêm vào màn hình, nhưng tất cả chúng chỉ được hiển thị tại điểm 0,0 của TableLayoutPanel, ngoài ra chúng còn không bị ràng buộc trong phạm vi ô mà chúng được cho là sẽ được hiển thị bên trong (nghĩa là với Dock = DockStyle.Fill chúng vẫn xuất hiện quá lớn/nhỏ).

Có ai đó có ví dụ hoạt động về việc thêm hàng & kiểm soát vào thời gian chạy không?

+0

Thêm một RowStyle sẽ thực sự tăng RowStyles.Count() –

Trả lời

4

Tôi vừa xem mã của mình. Trong một ứng dụng, tôi chỉ cần thêm các điều khiển, nhưng không chỉ định chỉ mục, và khi thực hiện xong, tôi chỉ lặp qua các kiểu hàng và thiết lập kiểu kích thước thành AutoSize. Vì vậy, chỉ cần thêm chúng mà không chỉ định các chỉ mục có vẻ như thêm các hàng như dự định (miễn là GrowStyle được đặt thành AddRows).

Trong ứng dụng khác, tôi xóa các điều khiển và đặt thuộc tính RowCount thành giá trị cần thiết. Điều này không thêm RowStyles. Sau đó, tôi thêm điều khiển của tôi, thời gian này xác định các chỉ số, và thêm một RowStyle mới (RowStyles.Add(new RowStyle(...)) và điều này cũng hoạt động.

Vì vậy, hãy chọn một trong các phương pháp này, cả hai đều hoạt động. Tôi nhớ những đau đầu bảng bố trí bảng gây ra cho tôi.

+0

Tôi sẽ cung cấp cho những người này một thử để xem nếu nó hoạt động chính nó! – Ash

68

Tôi vừa làm điều này tuần trước. Đặt GrowStyle trên TableLayoutPanel-AddRows hoặc AddColumns, sau đó mã của bạn nên làm việc:

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

Dưới đây là một số mã làm việc mà dường như giống với những gì bạn đang làm:

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

Các TableLayoutPanel luôn mang lại cho tôi phù hợp với kích thước. Trong ví dụ trên, tôi đang gửi một thẻ địa chỉ có thể tăng hoặc thu nhỏ tùy thuộc vào tài khoản có dòng địa chỉ hai hoặc quốc gia. Bởi vì hàng cuối cùng, hoặc cột, của bảng bố trí bảng sẽ kéo dài, tôi ném nhãn trống trong đó để buộc một hàng trống mới, sau đó tất cả mọi thứ dòng lên độc đáo.

Đây là mã thiết kế để bạn có thể xem bảng tôi bắt đầu với:

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

Ví dụ đơn giản, hoàn hảo. – RandomInsano

+2

Cảm ơn ý tưởng về hàng giữ chỗ trống! Giải quyết các vấn đề về kích thước của tôi. – JNadal

16

Dưới đây là mã của tôi cho thêm một hàng mới vào một hai cột 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; 
} 

Nhãn kiểm soát đi vào cột bên trái và điều khiển giá trị đi vào cột bên phải. Các điều khiển nói chung là loại Label và có thuộc tính AutoSize được đặt thành true.

Tôi không nghĩ rằng nó quan trọng quá nhiều, nhưng để tham khảo, đây là mã thiết kế mà thiết lập 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; 

này tất cả hoạt động tốt. Bạn nên lưu ý rằng dường như có một số vấn đề với việc xử lý các điều khiển từ một TableLayoutPanel động bằng cách sử dụng thuộc tính Controls (ít nhất là trong một số phiên bản của khung công tác). Nếu bạn cần phải loại bỏ các điều khiển, tôi đề nghị xử lý toàn bộ TableLayoutPanel và tạo một bảng mới.

+0

Điều này rất hữu ích. Tôi thấy rằng thuộc tính DockStyle.Fill là cần thiết. Ngoài ra, nó là đáng ngạc nhiên dễ dàng để làm cho những sai lầm với đếm! Ngoài ra, hãy lưu ý kích thước cột và hàng được đặt với kiểu. Tôi thấy rằng khi RowStyle được đặt thành AutoSize, một số biến thể không chủ định trong cài đặt TextAlign (trong Top, Middle và Bottom) làm cho nó xuất hiện rằng bảng đã tạo ra các hàng phụ theo cách lạ, nhưng đó không phải là trường hợp. Điều này hoạt động khá tốt một khi bạn tìm ra nó, nhưng thật là đau đớn khi đến đó! –

+0

Giải pháp đúng –

28

Đây là thiết kế lạ, nhưng thuộc tính TableLayoutPanel.RowCount không phản ánh số lượng bộ sưu tập RowStyles và tương tự cho thuộc tính ColumnCount và bộ sưu tập ColumnStyles.

Tôi đã tìm thấy thông tin cần thiết trong mã của mình là cập nhật thủ công RowCount/ColumnCount sau khi thực hiện thay đổi cho RowStyles/ColumnStyles.

Dưới đây là một ví dụ về mã tôi đã sử dụng:

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

suy nghĩ khác

  • Tôi chưa bao giờ sử dụng DockStyle.Fill để thực hiện một kiểm soát điền vào một tế bào trong lưới; Tôi đã thực hiện điều này bằng cách đặt thuộc tính Anchors của điều khiển.

  • Nếu bạn đang thêm nhiều điều khiển, hãy đảm bảo bạn gọi SuspendLayoutResumeLayout xung quanh quy trình, những thứ khác sẽ chạy chậm vì toàn bộ biểu mẫu được trả sau mỗi lần kiểm soát được thêm vào.

+2

Nếu nó hữu ích cho bất kỳ ai, trong trường hợp của tôi, tôi phải gọi * tableLayoutPanel1.ColumnStyles.Clear(); * khi biểu mẫu đang tải. – John

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 
+0

Câu hỏi đặt ra là về TableLayoutPanel, bài đăng này là về DataTable. Bài đăng chỉ là mã. Nó không có bất kỳ văn bản nào mô tả điểm có thể là gì. Không có bình luận nào trong mã. Vì vậy, -1. –

7

Tạo một bảng điều khiển bố trí bảng với hai cột trong hình thức và tên của bạn nó tlpFields.

Sau đó, chỉ cần thêm điều khiển mới vào bảng bố cục bảng (trong trường hợp này tôi đã thêm 5 nhãn trong cột-1 và 5 hộp văn bản trong cột-2).

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 
} 

Cuối cùng, hãy chạy mã.

+0

cách bạn truy cập tlpfields? Tôi đã tạo tablelayoutpanel và tên của nó là tabkelayout nhưng tôi unabla để truy cập này. –

+0

@MuneemHabib chuyển đến thuộc tính tabkelayout và thay đổi ** Modifiers ** từ riêng tư thành công khai – RookieCoder

0

Điều này hoạt động hoàn hảo để thêm hàng và điều khiển trong TableLayoutPanel.

Xác định một TableLayoutPanel trống với 3 cột trong trang thiết kế

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) 

Tạo một nút btnAddRow để thêm hàng trên mỗi nhấp chuột

 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

Tôi chỉ có một vấn đề có liên quan (trong đó là cách tôi tìm thấy chủ đề này), nơi các kiểu hàng và cột được thêm động của tôi không có hiệu lực. Tôi thường xem xét SuspendLayout()/ResumeLayout() làm tối ưu hóa, nhưng trong trường hợp này, gói mã của tôi vào chúng làm cho các hàng và cột hoạt động chính xác.

Các vấn đề liên quan