2009-07-17 12 views
74

मैं थोड़ी देर के लिए इसके साथ लड़ रहा हूं, और पाया है कि कई अन्य लोग TableLayoutPanel (.NET 2.0 Winforms) के साथ भी संघर्ष करते हैं।Winforms TableLayoutPanel प्रोग्रामेटिक रूप से पंक्तियों को जोड़ना

समस्या

मैं प्रोग्राम के रूप में नियंत्रण की पंक्तियों (अर्थात सेल प्रति एक नियंत्रण) जोड़ने के लिए एक 'खाली' 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 पर प्रस्तुत किए जाते हैं, इसके अतिरिक्त वे सेल सीमाओं के भीतर भी बाध्य नहीं होते हैं कि वे इन्हें प्रदर्शित किया जाना चाहिए (यानी डॉक = डॉक स्टाइल के साथ। फिर भी वे बहुत बड़े/छोटे तरीके से दिखाई देते हैं)।

क्या किसी के पास रनटाइम पर & नियंत्रण जोड़ने का एक कामकाजी उदाहरण है?

+0

रोशस्टाइल जोड़ना वास्तव में RowStyles.Count() –

उत्तर

4

मैंने अभी अपना कोड देखा है। एक आवेदन में, मैं केवल नियंत्रण जोड़ता हूं, लेकिन इंडेक्स निर्दिष्ट किए बिना, और जब किया जाता है, तो मैं सिर्फ पंक्ति शैलियों के माध्यम से लूप करता हूं और आकार का प्रकार ऑटोसाइज पर सेट करता हूं। इसलिए इंडेक्स निर्दिष्ट किए बिना उन्हें जोड़ना पंक्तियों को इरादे के रूप में जोड़ना प्रतीत होता है (बशर्ते GrowStyle AddRows पर सेट हो)।

किसी अन्य एप्लिकेशन में, मैं नियंत्रण साफ़ करता हूं और RowCount प्रॉपर्टी को आवश्यक मान पर सेट करता हूं। यह RowStyles जोड़ नहीं है। फिर मैं अपने नियंत्रण जोड़ता हूं, इस बार सूचकांक निर्दिष्ट करता हूं, और एक नया रोस्ट स्टाइल (RowStyles.Add(new RowStyle(...)) जोड़ता हूं और यह भी काम करता है।

तो, इन तरीकों में से एक को चुनें, वे दोनों काम करते हैं। मुझे लगता है कि टेबल लेआउट पैनल ने मुझे सिरदर्द का कारण बताया।

+0

बढ़ाएगा, मैं इन्हें यह देखने का प्रयास करूंगा कि यह स्वयं व्यवहार करता है या नहीं! – Ash

68

मैंने अभी पिछले सप्ताह ऐसा किया था। TableLayoutPanelAddRows या AddColumns है, तो अपने कोड काम करना चाहिए पर GrowStyle सेट करें:

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 हमेशा मुझे देता है:

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

यहाँ कुछ काम कर कोड है कि आप क्या कर रहे हैं के समान लगता है आकार के साथ फिट बैठता है। ऊपर दिए गए मेरे उदाहरण में, मैं एक एड्रेस कार्ड दर्ज कर रहा हूं जो पता पंक्ति दो या किसी देश वाले खाते के आधार पर बढ़ता या घट सकता है। चूंकि टेबल लेआउट पैनल की आखिरी पंक्ति, या कॉलम फैल जाएगा, इसलिए मैं एक खाली खाली पंक्ति को मजबूर करने के लिए वहां खाली लेबल फेंकता हूं, फिर सबकुछ अच्छी तरह से बढ़ता है।

यहाँ है डिजाइनर कोड ताकि आप तालिका मैं के साथ शुरू देख सकते हैं:

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

+2

खाली प्लेसहोल्डर पंक्ति के विचार के लिए धन्यवाद! मेरे आकार के मुद्दों को हल किया। – JNadal

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

लेबल नियंत्रण बाएं कॉलम में जाता है और मान नियंत्रण दाएं कॉलम में जाता है। नियंत्रण आम तौर पर लेबल प्रकार के होते हैं और उनकी ऑटोसाइज संपत्ति सत्य पर सेट होती है।

मैं इसे बहुत ज्यादा मायने रखती है नहीं लगता है, लेकिन संदर्भ के लिए, यहाँ डिजाइनर कोड कि 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 से नियंत्रण निपटाने के साथ कुछ समस्याएं दिखाई देती हैं। यदि आपको नियंत्रण हटाने की आवश्यकता है, तो मैं पूरे टेबललेआउट पैनेल का निपटान करने और एक नया निर्माण करने का सुझाव देता हूं।

+0

यह बहुत उपयोगी था। मैंने पाया कि डॉक स्टाइल। भरने की विशेषता आवश्यक थी। इसके अलावा, गिनती के साथ गलतियों को करना आश्चर्यजनक रूप से आसान है! साथ ही, शैलियों के साथ सेट कॉलम और पंक्ति आकार नोट करें। मैंने पाया कि जब रोस्ट स्टाइल ऑटोसाइज पर सेट किया गया था, तो टेक्स्ट एलाइन सेटिंग्स (शीर्ष, मध्य और नीचे के बीच) में कुछ अनजान भिन्नताओं ने यह दिखाई दिया कि तालिका कुछ अजीब तरीके से अतिरिक्त पंक्तियां उत्पन्न कर रही थी, लेकिन ऐसा नहीं था। एक बार जब आप इसे समझ लेंगे तो यह चीज़ बहुत अच्छी तरह से काम करती है, लेकिन वहां दर्दनाक था! –

+0

सही समाधान –

28

यह एक अजीब डिजाइन है, लेकिन TableLayoutPanel.RowCount संपत्ति RowStyles संग्रह की गिनती को प्रतिबिंबित नहीं करता, और इसी ColumnCount संपत्ति और ColumnStyles संग्रह के लिए।

मैं क्या पाया है मैं जरूरत में मेरी कोड मैन्युअल RowStyles/ColumnStyles में परिवर्तन करने के बाद RowCount/ColumnCount अद्यतन करने के लिए किया गया था।

यहाँ मैं का उपयोग किया है कोड का एक उदाहरण है:

/// <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 संपत्ति सेट करके यह किया है।

  • आप नियंत्रण का एक बहुत कुछ जोड़ रहे हैं तो आप इस प्रक्रिया के आसपास SuspendLayout और ResumeLayout फोन के लिए सुनिश्चित करें, बाकी चीजें धीमी गति से चलेंगे रूप में पूरे फार्म के बाद प्रत्येक नियंत्रण जोड़ा जाता है relaid है।

+2

यदि यह किसी के लिए उपयोगी है, तो मेरे मामले में मुझे * tableLayoutPanel1.ColumnStyles.Clear(); * जब फॉर्म लोड हो रहा है। – 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

प्रश्न TableLayoutPanel के बारे में है, यह पोस्ट डेटाटेबल के बारे में है। पोस्ट केवल कोड है। इसमें कोई टेक्स्ट नहीं है जो बताता है कि बिंदु क्या हो सकता है। कोड में कोई टिप्पणी नहीं है। Số 1। –

7

अपने फार्म और नाम यह 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 
} 

अंत में, कोड चलाएं।

+0

आप tlpfields तक कैसे पहुंच रहे हैं? मैंने tablelayoutpanel बनाया है और इसका नाम tabkelayout है लेकिन मैं इसे एक्सेस करने के लिए unabla हूँ। –

+0

@MuneemHabib tabkelayout गुणों पर जाएं और बदलें ** Modifiers ** निजी से सार्वजनिक तक – RookieCoder

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() को ऑप्टिमाइज़ेशन के रूप में मानता हूं, लेकिन इस मामले में, मेरे कोड को लपेटने से पंक्तियां और कॉलम सही तरीके से व्यवहार करते हैं।

संबंधित मुद्दे