Вопрос по winforms, c#, .net, tablelayoutpanel, runtime – Winforms TableLayoutPanel добавление строк программно

77

Я некоторое время боролся с этим и обнаружил, что ряд других людей также борются с TableLayoutPanel (.net 2.0 Winforms).

Problem

Я пытаюсь взять «бланк» 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 для нее!

Другая связанная проблема, с которой я сталкиваюсь, заключается в том, что элементы управления будут добавлены на дисплей, но все они просто отображаются в точке 0,0 TableLayoutPanel, кроме того, они даже не ограничены тем, что находятся в пределах ячеек, которые должны быть отображается внутри (то есть с Dock = DockStyle.Fill они все еще кажутся слишком большими / маленькими).

Есть ли у кого-нибудь рабочий пример добавления строк & amp; контролирует во время выполнения?

Добавление RowStyle фактически увеличит RowStyles.Count () Weapon X

Ваш Ответ

8   ответов
0

У меня просто была связанная проблема (именно так я нашел этот поток), когда мои динамически добавленные стили строк и столбцов не работали. Обычно я рассматриваю SuspendLayout () / ResumeLayout () как оптимизацию, но в этом случае оборачивая мой код в них, строки и столбцы ведут себя правильно.

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;

Это все работает просто отлично. Вы должны знать, что существуют некоторые проблемы с удалением элементов управления из TableLayoutPanel динамически с использованием свойства Controls (по крайней мере, в некоторых версиях платформы). Если вам нужно удалить элементы управления, я предлагаю удалить всю TableLayoutPanel и создать новую.

Правильное решение
Это было очень полезно. Я обнаружил, что атрибут DockStyle.Fill был необходим. Также удивительно легко ошибиться со счетом! Также обратите внимание на размеры столбцов и строк, установленные стилями. Я обнаружил, что когда RowStyle был установлен на AutoSize, некоторые непреднамеренные изменения в настройках TextAlign (среди верхних, средних и нижних) создавали впечатление, что таблица генерирует дополнительные строки каким-то странным образом, но это не так. Эта штука работает довольно хорошо, как только вы это понимаете, но это было больно!
7

Создайте панель макета таблицы с двумя столбцами в форме и назовите ееtlpFields.

Затем просто добавьте новый элемент управления на панель макета таблицы (в этом случае я добавил 5 меток в столбец-1 и 5 текстовых полей в столбец-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
}

Наконец, запустите код.

@MuneemHabib перейдите к свойствам tabkelayout и изменитеModifiers от частного к общественному
как вы получаете доступ к tlpfields? Я создал tablelayoutpanel и его имя tabkelayout, но я не могу получить к нему доступ.
4

Я только что посмотрел в свой код. В одном приложении я просто добавляю элементы управления, но без указания индекса, а когда все готово, я просто перебираю стили строк и устанавливаю тип размера AutoSize. Таким образом, простое добавление их без указания индексов, по-видимому, добавляет строки по назначению (при условии, что GrowStyle установлен в AddRows).

В другом приложении я очищаю элементы управления и устанавливаю для свойства RowCount необходимое значение. Это не добавляет RowStyles. Затем я добавляю свои элементы управления, на этот раз определяя индексы, и добавляю новый RowStyle (RowStyles.Add(new RowStyle(...)) и это тоже работает.

Итак, выберите один из этих методов, они оба работают. Я помню головные боли, которые вызвала у меня панель раскладки стола.

Я попытаюсь понять, будет ли он вести себя сам! Ash
0

Это прекрасно работает для добавления строк и элементов управления в TableLayoutPanel.

Определите пустую таблицу Tablelayoutpanel с 3 столбцами на странице дизайна

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

Другие мысли

I've never used DockStyle.Fill to make a control fill a cell in the Grid; I've done this by setting the Anchors property of the control.

If you're adding a lot of controls, make sure you call SuspendLayout and ResumeLayout around the process, else things will run slow as the entire form is relaid after each control is added.

Если это кому-нибудь пригодится, в моем случае мне пришлось позвонитьtableLayoutPanel1.ColumnStyles.Clear(); когда форма загружается.
70

Я только что сделал это на прошлой неделе. Установить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 всегда дает мне подходит с размером. В моем примере выше я подаю адресную карточку, которая может увеличиваться или уменьшаться в зависимости от учетной записи, имеющей адресную строку два, или страны. Поскольку последняя строка или столбец панели макета таблицы растягивается, я добавляю туда пустую метку, чтобы создать новую пустую строку, а затем все выстраивается в линию.

Вот код конструктора, чтобы вы могли увидеть таблицу, с которой я начинаю:

        //
        // 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;
Прекрасный, простой пример.
Спасибо за идею для пустой строки заполнителя! Решил мои проблемы с размерами.
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
Вопрос о TableLayoutPanel, этот пост о DataTable. Пост только для кода. В нем нет текста, описывающего, в чем смысл. Никаких комментариев в коде тоже нет. Таким образом, 1.

Похожие вопросы