He estado luchando con esta por un tiempo, y han encontrado que un número de otras personas luchan con la TableLayoutPanel (.net 2.0 Winforms) así.

Problema

Estoy tratando de tomar un ‘blanco’ tablelayoutpanel, que tiene 10 columnas definidas, entonces en tiempo de ejecución agregar filas mediante programación de los controles (es decir, un control por cada celda).

Uno podría haber pensado que debería ser tan simple como

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

Pero que (para mí) no agregar las filas. Así que tal vez la adición de una fila de estilo

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

Pero que no funciona bien. He cavado alrededor y encontró que la myTableLayoutPanel.RowCount uso de los cambios de tiempo de diseño para el tiempo de ejecución, por lo tanto haciendo myTableLayoutPanel.RowCount++; en realidad no agregar otra fila, ni siquiera antes de/después de la adición de un RowStyle entrada para ella!

Otro problema relacionado con el que me estoy encontrando es que los controles se añadirá a la pantalla, pero todos ellos simplemente llegar al punto 0,0 de la TableLayoutPanel, además de que no está aún limitado a estar dentro de la Celda de los límites que se supone que se mostrará dentro (es decir, con Dock = DockStyle.Llenar aún aparecen de manera demasiado grande/pequeño).

¿ Alguien tiene un ejemplo de trabajo de la adición de filas & controles en tiempo de ejecución?

  • La adición de un RowStyle aumente la RowStyles.Count()
InformationsquelleAutor Ash | 2009-07-17

8 Comentarios

  1. 72

    Lo hice de esta última semana. Establecer el GrowStyle en el TableLayoutPanel a AddRows o AddColumns, a continuación, el código debería funcionar:

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

    Aquí es algunas código de trabajo que parece similar a lo que están haciendo:

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

    La TableLayoutPanel siempre me da encaja con el tamaño. En mi ejemplo anterior, estoy presentación de una tarjeta de dirección que puede crecer o decrecer en función de la cuenta que tenga una dirección de línea de dos, o de un país. Debido a que la última fila o columna de la tabla de diseño de panel de estiramiento, voy a tirar la etiqueta vacía en la haya para forzar una nueva fila vacía, entonces todo se alinea perfectamente.

    Aquí está el código del diseñador así que usted puede ver la tabla empiezo 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;
    • Perfecto, sencillo ejemplo.
    • Gracias por la idea para un marcador de posición vacío de la fila! Solucionado mis problemas de tamaño.
  2. 28

    Es un raro diseño, pero el TableLayoutPanel.RowCount propiedad no refleja el recuento de los RowStyles de la colección, y de manera similar para el ColumnCount de la propiedad y el ColumnStyles colección.

    Lo que he encontrado yo necesitaba en mi código para actualizar manualmente RowCount/ColumnCount después de hacer cambios a RowStyles/ColumnStyles.

    He aquí un ejemplo de código que he utilizado:

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

    Otros pensamientos

    • Nunca he usado DockStyle.Fill para hacer un control de llenar un celular en la Cuadrícula; yo lo he hecho esta configuración a través de la Anchors propiedad del control.

    • Si vas a agregar una gran cantidad de controles, asegúrese de llamar SuspendLayout y ResumeLayout de todo el proceso, de lo contrario las cosas se ejecutará lento como el formulario en su totalidad es relaid después de cada control se agrega.

    • Si es útil para alguien, en mi caso tuve que llamar a tableLayoutPanel1.ColumnStyles.Clear(); cuando el formulario se carga.
  3. 16

    Aquí está mi código para añadir una nueva fila a una de dos columnas 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;
    }

    El control de etiqueta que va en la columna de la izquierda y el valor de control de la va en la columna de la derecha. Los controles son generalmente de tipo de Etiqueta, y que tiene su propiedad AutoSize true.

    Yo no creo que importe demasiado, pero sólo para referencia, aquí está el código del diseñador que establece 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;

    Todo esto funciona bien. Usted debe ser consciente de que parece que hay algunos problemas con la eliminación de los controles de TableLayoutPanel de forma dinámica utilizando los Controles de la propiedad (al menos en algunas versiones del framework). Si usted necesita para eliminar controles, sugiero que desechar toda la TableLayoutPanel y la creación de una nueva.

    • Esto fue muy útil. He encontrado que la DockStyle.Llenar el atributo esencial. También, es sorprendentemente fácil cometer errores con el conteo! También, tenga en cuenta la columna y la fila de los tamaños de conjunto con los estilos. He encontrado que cuando la RowStyle se establece en Automático, algunos no intencional de las variaciones en el TextAlign configuración (entre la parte Superior, Media e Inferior), hacían parecer que la mesa era generar más filas de alguna extraña manera, pero ese no fue el caso. La cosa funciona bastante bien una vez que averiguar, pero fue doloroso llegar allí!
    • Solución correcta
  4. 7

    Crear una tabla de diseño de panel con dos columnas en su forma y nombre que tlpFields.

    Luego, simplemente agregar nuevo control al diseño de la mesa panel (en este caso he añadido 5 etiquetas en la columna 1 y 5 cuadros de texto en la columna-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
    }

    Finalmente, ejecutar el código.

    • cómo se accede a tlpfields? He creado tablelayoutpanel y su nombre es tabkelayout pero estoy unabla para acceder a esta.
    • ir a tabkelayout propiedades y cambiar el Modificadores de la privada a la pública
  5. 4

    Sólo miré en mi código. En una aplicación, acabo de añadir los controles, pero sin especificar el índice, y cuando se hace, acabo de bucle a través de la fila de estilos y establecer el tipo de tamaño de tamaño Automático. Tan sólo la adición de ellos sin especificar los índices parece añadir las filas como la intención de la GrowStyle se establece en AddRows).

    En otra aplicación, puedo borrar los controles y establecer el número de filas de la propiedad con el valor necesario. Esto no agregar el RowStyles. A continuación, añado mi controles, esta vez especificando los índices, y añadir un nuevo RowStyle (RowStyles.Add(new RowStyle(...)) y esto también funciona.

    Así, elija uno de estos métodos, ambos trabajan. Recuerdo los dolores de cabeza de la mesa panel de diseño me causó.

    • Voy a dar a estas personas una oportunidad para ver si se comporta en sí misma!
  6. 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
    • La pregunta es acerca de TableLayoutPanel, este post es sobre el objeto DataTable. El post es de código único. No tiene ningún texto descriptivo de lo que el punto de que podría ser. No hay comentarios en el código. Así, -1.
  7. 0

    Esto funciona perfectamente para agregar filas y los controles en un TableLayoutPanel.

    Definir un espacio en blanco Tablelayoutpanel con 3 columnas en el diseño de la página

        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)

    Crear un botón btnAddRow para agregar filas en cada 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
  8. 0

    Yo sólo tenía un problema relacionado (que es como he encontrado este hilo), donde mi dinámicamente añadido de fila y de columna estilos no estaban teniendo efecto. Me suele considerar SuspendLayout()/ResumeLayout() como optimizaciones, pero en este caso, envolviendo mi código en ellos las filas y columnas se comportan correctamente.

Dejar respuesta

Please enter your comment!
Please enter your name here