2009-07-17 14 views
74

Ho combattuto per un po 'e ho scoperto che un certo numero di altre persone ha difficoltà con il TableLayoutPanel (.net 2.0 Winforms).Winforms TableLayoutPanel aggiunta di righe a livello di codice

Problemi

Sto tentando di prendere una TableLayoutPanel 'blank', che ha 10 colonne definite, in fase di esecuzione di programmazione aggiungere righe di controlli (cioè un controllo per cella).

Si sarebbe potuto pensare che dovrebbe essere semplice come

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

Ma questo (per me) non aggiunge le righe. Quindi, magari aggiungendo uno stile di riga

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

Ma questo non funziona neanche. Ho scavato e ho scoperto che l'utilizzo di myTableLayoutPanel.RowCount cambia da tempo di progettazione a tempo di esecuzione, quindi fare myTableLayoutPanel.RowCount++; non aggiunge effettivamente un'altra riga, nemmeno prima/dopo aver aggiunto una voce di RowStyle!

Un altro problema correlato che sto riscontrando è che i controlli verranno aggiunti al display, ma tutti vengono semplicemente visualizzati al punto 0,0 del TableLayoutPanel, inoltre non sono nemmeno vincolati per essere all'interno dei limiti della cella che essi dovrebbero essere visualizzati all'interno (cioè con Dock = DockStyle.Fill appaiono ancora troppo grandi/piccoli).

Qualcuno ha un esempio funzionante di aggiunta di controlli di righe & in fase di esecuzione?

+0

Aggiungere un RowStyle effettivamente aumenterà il RowStyles.Count() –

risposta

4

Ho appena esaminato il mio codice. In un'applicazione, aggiungo semplicemente i controlli, ma senza specificare l'indice e, una volta terminato, faccio semplicemente scorrere gli stili di riga e imposta il tipo di dimensione su AutoSize. Quindi, solo aggiungerli senza specificare gli indici sembra aggiungere le righe come previsto (a condizione che GrowStyle sia impostato su AddRows).

In un'altra applicazione, si deselezionano i controlli e si imposta la proprietà RowCount sul valore necessario. Questo non aggiunge RowStyles. Quindi aggiungo i miei controlli, questa volta specificando gli indici, e aggiungo un nuovo RowStyle (RowStyles.Add(new RowStyle(...)) e anche questo funziona.

Quindi, scegli uno di questi metodi, entrambi funzionano. Ricordo i mal di testa causati dal pannello di layout della tabella.

+0

Darò a questi una prova per vedere se si comporta da solo! – Ash

68

L'ho appena fatto la scorsa settimana. Impostare la GrowStyle sul TableLayoutPanel-AddRows o AddColumns, allora il codice dovrebbe funzionare:

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

Ecco alcuni codice di lavoro che sembra simile a quello che si sta facendo:

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

Il TableLayoutPanel mi dà sempre si adatta alle dimensioni Nel mio esempio sopra, sto registrando una scheda di indirizzo che potrebbe aumentare o diminuire a seconda dell'account che ha una linea di indirizzo due, o di un paese. Poiché l'ultima riga o colonna del pannello di layout della tabella si allungherà, lancerò l'etichetta vuota lì per forzare una nuova riga vuota, quindi tutto si allinea bene.

Ecco il codice progettista in modo da poter vedere la tabella comincio con:

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

Perfetto, semplice esempio. – RandomInsano

+2

Grazie per l'idea di una fila vuota di segnaposto! Risolto il mio problema di dimensionamento. – JNadal

16

Ecco il mio codice per l'aggiunta di una nuova riga a una TableLayoutColumn a due colonne:

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

L'etichetta il controllo va nella colonna di sinistra e il controllo del valore va nella colonna di destra. I controlli sono generalmente di tipo Label e la loro proprietà AutoSize è impostata su true.

Io non credo che le questioni troppo, ma per riferimento, ecco il codice progettista che imposta 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; 

Questo tutto funziona bene. È necessario tenere presente che sembra che ci siano alcuni problemi con l'eliminazione dei controlli da un TableLayoutPanel in modo dinamico utilizzando la proprietà Controls (almeno in alcune versioni del framework). Se è necessario rimuovere i controlli, suggerisco di smaltire l'intero TableLayoutPanel e crearne uno nuovo.

+0

Questo è stato molto utile. Ho scoperto che l'attributo DockStyle.Fill era essenziale. Inoltre, è sorprendentemente facile fare errori con il conteggio! Inoltre, nota le dimensioni di colonne e righe impostate con gli stili. Ho scoperto che quando RowStyle era impostato su AutoSize, alcune variazioni involontarie nelle impostazioni di TextAlign (tra Alto, Basso e Basso) facevano sembrare che la tabella stesse generando righe extra in qualche modo strano, ma non era così. La cosa funziona abbastanza bene una volta capita, ma è stato doloroso arrivarci! –

+0

Soluzione corretta –

28

È un disegno strano, ma la proprietà TableLayoutPanel.RowCount non riflette il conteggio della collezione RowStyles, e allo stesso modo per la proprietà ColumnCount e la raccolta ColumnStyles.

Quello che ho trovato ho bisogno nel mio codice è stato quello di aggiornare manualmente RowCount/ColumnCount dopo aver apportato modifiche al RowStyles/ColumnStyles.

Ecco un esempio di codice che ho usato:

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

Altri pensieri

  • Non ho mai usato DockStyle.Fill a fare un controllo di riempire una cellanella griglia; Ho fatto questo impostando la proprietà Anchors del controllo.

  • Se si aggiunge un sacco di controlli, assicuratevi di chiamare SuspendLayout e ResumeLayout tutto il processo, le altre cose verrà eseguito lento come l'intero modulo viene rifatto dopo l'aggiunta di ogni controllo.

+2

Se è utile per chiunque, nel mio caso ho dovuto chiamare * tableLayoutPanel1.ColumnStyles.Clear(); * durante il caricamento del modulo. – 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

La domanda riguarda TableLayoutPanel, questo post riguarda DataTable. Il post è solo codice. Non ha alcun testo che descrive quale potrebbe essere il punto. Neanche i commenti nel codice. Quindi, -1. –

7

creare un pannello di layout tabella con due colonne nel modulo e denominarlo tlpFields.

Quindi, è sufficiente aggiungere un nuovo controllo al pannello di layout della tabella (in questo caso ho aggiunto 5 etichette nella colonna 1 e 5 caselle di testo nella colonna 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 
} 

Infine, eseguire il codice.

+0

come stai accedendo a tlpfields? Ho creato tablelayoutpanel e il suo nome è tabkelayout ma sono unabla per accedere a questo. –

+0

@MuneemHabib vai alle proprietà di tabkelayout e cambia ** Modificatori ** da privato a pubblico – RookieCoder

0

Ciò funziona perfettamente per l'aggiunta di righe e controlli in un TableLayoutPanel.

Definire un TableLayoutPanel in bianco con 3 colonne nella pagina di disegno

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) 

Creare un pulsante btnAddRow per aggiungere righe su ogni clic

 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

Ho appena avuto un problema correlato (che è come mi trovato questo thread), dove i miei stili di riga e colonna aggiunti dinamicamente non stavano avendo effetto. Solitamente considero SuspendLayout()/ResumeLayout() come ottimizzazioni, ma in questo caso, avvolgere il mio codice in esse ha comportato il corretto funzionamento di righe e colonne.

Problemi correlati