プログラムで行を追加するWinformsTableLayoutPanel


85

私はしばらくこれと戦ってきましたが、他の多くの人々もTableLayoutPanel(.net 2.0 Winforms)で苦労していることがわかりました。

問題

10列が定義されている「空白」のtablelayoutpanelを取得し、実行時にプログラムでコントロールの行を追加しようとしています(つまり、セルごとに1つのコントロール)。

と同じくらい簡単なはずだと思ったかもしれません

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でレンダリングされるだけであり、さらに、本来あるべきセル境界内にあるように制約されることさえありません。内に表示されます(つまり、Dock = DockStyle.Fillを使用すると、まだ大きすぎたり小さすぎたりします)。

実行時に行とコントロールを追加する実用的な例はありますか?


RowStyleを追加すると、実際にRowStyles.Countを増加させるであろう()
エドゥアルド・ヘルナンデス

回答:


75

私は先週これをしました。をまたはに設定するGrowStyleと、コードが機能するはずです。TableLayoutPanelAddRowsAddColumns

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

2
空のプレースホルダー行のアイデアをありがとう!サイズの問題を解決しました。
jNadal 2012年

30

これは奇妙なデザインですが、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;
    }

他の考え

  • DockStyle.Fillコントロールをグリッドのセルに塗りつぶすのに使用したことはありません。これAnchorsは、コントロールのプロパティを設定することで行いました。

  • あなたがコントロールの多くを追加する場合は、必ずお電話させるSuspendLayoutResumeLayout、プロセスを中心に、それ以外のものは、各コントロールが追加された後、フォーム全体がrelaidされるように遅い実行されます。


2
だれにとっても便利な場合は、私の場合、tableLayoutPanel1.ColumnStyles.Clear();を呼び出す必要がありました。フォームが読み込まれているとき。
ジョン

17

2列の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全体を破棄して新しいコントロールを作成することをお勧めします。


これはとても役に立ちました。DockStyle.Fill属性が不可欠であることがわかりました。また、カウントを間違えるのは驚くほど簡単です!また、スタイルで設定された列と行のサイズにも注意してください。RowStyleがAutoSizeに設定されている場合、TextAlign設定(Top、Middle、およびBottomの間)の意図しないバリエーションにより、テーブルが奇妙な方法で余分な行を生成しているように見えることがわかりましたが、そうではありませんでした。一度理解すればかなりうまくいきますが、そこにたどり着くのは大変でした!
Jan Hettich 2011

7

フォームに2つの列があるテーブルレイアウトパネルを作成し、名前を付け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
}

最後に、コードを実行します。


どのようにtlpfieldsにアクセスしていますか?tablelayoutpanelを作成し、その名前はtabkelayoutですが、これにアクセスすることはできません。
Muneem Habib 2015

tabkelayoutプロパティと変更に行く@MuneemHabib修飾子国民に民間から
RookieCoder

4

コードを調べたところです。1つのアプリケーションでは、コントロールを追加するだけですが、インデックスを指定せずに、行スタイルをループしてサイズタイプをAutoSizeに設定します。したがって、インデックスを指定せずにそれらを追加するだけで、意図したとおりに行が追加されるようです(GrowStyleがAddRowsに設定されている場合)。

別のアプリケーションでは、コントロールをクリアして、RowCountプロパティを必要な値に設定します。これはRowStylesを追加しません。次に、コントロールを追加し、今回はインデックスを指定して、新しいRowStyle(RowStyles.Add(new RowStyle(...))を追加します。これも機能します。

したがって、これらの方法の1つを選択すると、どちらも機能します。テーブルレイアウトパネルが原因で頭痛がしたのを覚えています。


これらのものを試してみて、それ自体が動作するかどうかを確認します。
アッシュ

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。
NickAlexeev18年

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()を最適化と見なしますが、この場合、コードをそれらでラップすると、行と列が正しく動作します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.