Winforms TableLayoutPanel program aracılığıyla satır ekleme


85

Bir süredir bununla savaşıyorum ve bir dizi başka insanın da TableLayoutPanel (.net 2.0 Winforms) ile mücadele ettiğini gördüm.

Sorun

Tanımlanmış 10 sütun içeren bir 'boş' tablo düzeni paneli almaya çalışıyorum, ardından çalışma zamanında programlı olarak denetim satırları (yani hücre başına bir denetim) ekliyorum.

Bunun kadar basit olması gerektiği düşünülebilirdi.

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

Ama bu (benim için) satırları eklemiyor. Yani belki bir satır stili ekleyerek

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

Ama bu da işe yaramıyor. Etrafı araştırdım ve myTableLayoutPanel.RowCountkullanımın tasarım zamanından çalışma süresine değiştiğini, dolayısıyla myTableLayoutPanel.RowCount++;bunun için bir RowStyle girişi eklemeden önce / sonra bile başka bir satır eklemediğini öğrendim!

Karşılaştığım bir diğer ilgili sorun da, kontrollerin ekrana eklenecek olması, ancak hepsinin TableLayoutPanel'in 0,0 noktasında işlenmesi, ayrıca bunların olması gereken Hücre sınırları içinde bile olmaları. içinde görüntülenir (yani Dock = DockStyle.Fill ile bunlar hala çok büyük / küçük görünüyor).

Birisinin çalışma zamanında satırlar ve kontroller eklemeyle ilgili çalışan bir örneği var mı?


RowStyle eklemek aslında RowStyles.Count () değerini artıracaktır
Eduardo Hernández

Yanıtlar:


75

Bunu geçen hafta yaptım. Set GrowStyleüzerinde TableLayoutPanelhiç AddRowsveya AddColumns, sonra kod çalışması gerekir:

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

İşte yaptığınız şeye benzer görünen bazı çalışma kodları:

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

Her TableLayoutPanelzaman bana bedene uyuyor. Yukarıdaki örneğimde, ikinci adres satırı olan hesaba veya bir ülkeye bağlı olarak büyüyebilen veya küçülebilen bir adres kartı dolduruyorum. Tablo düzeni panelinin son satırı veya sütunu uzayacağından, boş etiketi yeni bir boş satıra zorlamak için oraya atıyorum, sonra her şey güzelce sıraya giriyor.

İşte tasarımcı kodu, böylece başladığım tabloyu görebilirsiniz:

        //
        // 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
Boş bir yer tutucu satırı fikri için teşekkürler! Boyutlandırma sorunlarımı çözdüm.
JNadal

30

Garip bir tasarım, ancak TableLayoutPanel.RowCountmülk RowStyleskoleksiyonun sayısını yansıtmıyor ve benzer şekilde ColumnCountmülk ve ColumnStyleskoleksiyon için de geçerli.

Ne benim kod için gerekli buldum elle güncelleme oldu RowCount/ ColumnCountdeğişiklik yaptıktan sonra RowStyles/ ' ColumnStyles.

İşte kullandığım bir kod örneği:

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

Diğer düşünceler

  • Hiçbir zaman DockStyle.Fillbir kontrolün Grid'deki bir hücreyi doldurmasını sağlamadım; Bunu Anchorskontrolün özelliğini ayarlayarak yaptım .

  • Çok fazla denetim ekliyorsanız , işlemi aradığınızdan SuspendLayoutve ResumeLayoutişlemin etrafından dolaştığınızdan emin olun , aksi takdirde her denetim eklendikten sonra tüm form yeniden verildiğinden işler yavaş çalışacaktır.


2
Herhangi biri için yararlıysa, benim durumumda tableLayoutPanel1.ColumnStyles.Clear (); form yüklenirken.
John

17

İki sütunlu bir TableLayoutColumn'a yeni bir satır eklemek için kodum:

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

Etiket denetimi sol sütuna ve değer denetimi sağ sütuna gider. Denetimler genellikle Label tipindedir ve AutoSize özelliği true olarak ayarlanmıştır.

Bunun çok önemli olduğunu sanmıyorum, ancak referans için, burada detailTable'ı oluşturan tasarımcı kodu:

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;

Bunların hepsi gayet iyi çalışıyor. Controls özelliğini kullanarak (en azından çerçevenin bazı sürümlerinde) bir TableLayoutPanel'den kontrolleri dinamik olarak atarken bazı sorunlar var gibi göründüğünün farkında olmalısınız. Denetimleri kaldırmanız gerekirse, TableLayoutPanel'in tamamını atmanızı ve yeni bir tane oluşturmanızı öneririm.


Bu çok yardımcı oldu. DockStyle.Fill özniteliğinin gerekli olduğunu buldum. Ayrıca, sayma sırasında hata yapmak şaşırtıcı derecede kolaydır! Ayrıca stillerle ayarlanan sütun ve satır boyutlarına dikkat edin. RowStyle, AutoSize olarak ayarlandığında, TextAlign ayarlarındaki (Üst, Orta ve Alt arasında) bazı istenmeyen varyasyonların, tablonun garip bir şekilde fazladan satırlar oluşturduğunu gösterdiğini buldum, ancak durum böyle değildi. Bir kez çözdüğünüzde oldukça iyi çalışıyor, ancak oraya gitmek acı vericiydi!
Jan Hettich

7

Formunuzda iki sütun bulunan bir tablo düzeni paneli oluşturun ve adlandırın tlpFields.

Ardından, tablo düzeni paneline yeni bir denetim ekleyin (bu durumda sütun 1'e 5 etiket ve sütun 2'ye 5 metin kutusu ekledim).

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
}

Son olarak kodu çalıştırın.


tlpfields'a nasıl erişiyorsunuz? Tablayoutpanel oluşturdum ve adı tabkelayout ama buna erişemiyorum.
Muneem Habib

@MuneemHabib tabkelayout özelliklerine gidin ve Değiştiricileri
özelden

4

Sadece koduma baktım. Bir uygulamada, sadece kontrolleri ekliyorum, ancak indeksi belirtmeden ve bittiğinde, sadece satır stillerinde döngü yapıyorum ve boyut türünü Otomatik Boyut olarak ayarlıyorum. Dolayısıyla, endeksleri belirtmeden yalnızca bunları eklemek, satırları amaçlandığı gibi ekler gibi görünür (GrowStyle'ın AddRows olarak ayarlanması koşuluyla).

Başka bir uygulamada, kontrolleri temizleyip RowCount özelliğini gerekli değere ayarlıyorum. Bu, RowStyles'ı eklemez. Sonra bu sefer indisleri belirleyerek kontrollerimi ekliyorum ve yeni bir RowStyle ( RowStyles.Add(new RowStyle(...)) ekliyorum ve bu da çalışıyor.

Öyleyse, bu yöntemlerden birini seçin, ikisi de işe yarar. Masa düzeni panelinin bende neden olduğu baş ağrılarını hatırlıyorum.


Bunlara kendi kendine davranıp davranmadığını görmeye çalışacağım!
Ash

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

Soru TableLayoutPanel ile ilgili, bu gönderi DataTable hakkındadır. Gönderi yalnızca koddur. Konunun ne olabileceğini açıklayan herhangi bir metni yok. Kodda da yorum yok. Số 1.
Nick Alexeev

0

Bu, TableLayoutPanel'de satırlar ve denetimler eklemek için mükemmel şekilde çalışır.

Tasarım sayfasında 3 sütunlu boş bir Tablelayout paneli tanımlayın

    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)

Her tıklamada satır eklemek için bir btnAddRow düğmesi oluşturun

     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

Dinamik olarak eklenen satır ve sütun stillerimin etkili olmadığı ilgili bir problemim vardı (bu konuyu bu şekilde buldum). Genellikle SuspendLayout () / ResumeLayout () 'u optimizasyon olarak düşünürüm, ancak bu durumda, kodumu bunlara sarmak satırların ve sütunların doğru davranmasını sağladı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.