I have a program that I'm writing that connects to a database, calls a new form , and dynamicly creates controls (textbox, and label) for each item so that they can be edited. The problem I'm having, is I don't know how to pass these values back to the main part of my program. I'm just not sure how to access these dynamic controls after they've been created. They are being created durning the OnLoad function. Here is the code:

protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            for (m_iRow = 0; m_iRow < m_iTotalRows; m_iRow++)
            {
                int iColumn = 0, iMyColumn = 0;

                if (m_iRow == (m_iTotalRows - 1))
                {
                    txtOutsideTxtBox.Text = m_strDetails[m_iRow, iColumn];
                    m_iRow = m_iTotalRows;
                }
                else
                {
                    if (m_strDetails[m_iRow, iColumn] != null)
                    {                        
                        label1 = new Label();
                        label1.Name = "lblAmount" + (m_iRow + 1).ToString();
                        label1.Text = "Amount:";
                        tableLayoutPanel1.Controls.Add(label1, iColumn, m_iRow);
                        iColumn++;

                        txtBox1 = new TextBox();
                        txtBox1.Name = "txtAmount" + (m_iRow + 1).ToString();
                        txtBox1.Text = m_strDetails[m_iRow, iMyColumn];
                        tableLayoutPanel1.Controls.Add(txtBox1, iColumn, m_iRow);
                        iColumn++;
                        iMyColumn++;

                        label1 = new Label();
                        label1.Name = "lblUnit" + (m_iRow + 1).ToString();
                        label1.Text = "Unit:";
                        tableLayoutPanel1.Controls.Add(label1, iColumn, m_iRow);
                        iColumn++;

                        txtBox1 = new TextBox();
                        txtBox1.Name = "txtUnit" + (m_iRow + 1).ToString();
                        txtBox1.Text = m_strDetails[m_iRow, iMyColumn];
                        tableLayoutPanel1.Controls.Add(txtBox1, iColumn, m_iRow);
                        m_iRowCount++;
                    }
                }
            }            
        }

The Error I'm getting is

The name txtUnit1 does not exist in the current context

My first thought is DUH because it's created in a different function (I'm using a button I call save to pass back

DialogResults.OK

along with the values of each text box. So how do I do this. I suppose I'm needing to be creating the controls else where? Any suggestions?

Dani AI

Generated

Core problem: the controls are created inside the load loop and only referenced by a local variable, so the Save handler can't see those individual instances. Also avoid mutating your loop index inside the loop (that will skip rows and make naming/positioning unpredictable). was right to check whether controls are actually created; 's example shows the useful pattern of keeping control references at class scope.

Practical fixes (pick one):

  • Keep references in a class-level collection and read from it on Save. Example pattern:
    
    // class scope
    private List<TextBox> amountTextBoxes = new List<TextBox>();

// when creating
var tb = new TextBox();
tb.Name = "txtAmount" + row;
amountTextBoxes.Add(tb);
tableLayoutPanel1.Controls.Add(tb, col, row);

// on save
var values = amountTextBoxes.Select(t => t.Text).ToList();


- Locate controls from the layout by position or name if you didn't store them. Use TableLayoutPanel.GetControlFromPosition(column, row) to fetch the control placed in that cell, or Control.ControlCollection.Find to search by Name. Example:
```csharp
var ctrl = tableLayoutPanel1.GetControlFromPosition(1, rowIndex) as TextBox;
var matches = tableLayoutPanel1.Controls.Find("txtUnit1", true);

Docs: GetControlFromPosition and ControlCollection.Find (Microsoft docs).

Best practice: before closing a dialog, copy the edited values into a business/data structure (List, DataTable, DTO) or expose a read-only property like public List<Item> EditedRows { get; private set; }. Fill that in the Save handler, set DialogResult = DialogResult.OK, then Close. That avoids reading controls after the form is closed or disposed.

Extras: use Tag on each control to carry the row id or DB key; give each control a unique Name if you plan to find them later; declare local variables when creating controls (do not reuse a single field like txtBox1 for every instance).

Recommended Answers

All 4 Replies

Hi,
Do u create txtUnit1 dynamically? Even though it is created dynamically, it should have reference to refer later. Also check the modifier (Private, public ...). In your conditions the controls may not be created.

And how would I create a reference for later? Also, none of these dynamically created controls can be accessed outside of the function (the for loop actually) that they are created in. Any ideas? Maybe someone knows of a good tutorial on dynamic controls (for the not so bright :P )

Also post your coding where the errors occur. Anyone can find errors.

namespace C1_Testing
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Panel p = new Panel();
        int count = 5;
        RadioButton[] rbutton;

        private void Form1_Load(object sender, EventArgs e)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Option1");
            dt.Columns.Add("Option2");
            p.Name = "panel1";
            p.Width = 223;
            p.Height = 524;
            p.AccessibleName = "panel1";
            rbutton = new RadioButton[count];
            int j = 0;
            for (int i = 0; i < count; i++)
            {
                rbutton[i] = new RadioButton();
                rbutton[i].AccessibleName = p.Name+i.ToString();
                rbutton[i].Text = i.ToString();
                rbutton[i].Location = new Point(60, 60 + i * 20);
                p.Controls.Add(rbutton[i]);
                j = i;
            }

            Button btn = new Button();
            btn.AccessibleName = "btn1";
            btn.Text = "submit";
            btn.Size = new Size(75, 23);
            btn.Visible = true;
            btn.Click += new System.EventHandler(this.method);
            btn.Location=new Point(90, 60 + j* 20);
            this.Controls.Add(btn);
            this.Controls.Add(p);

        }
        public void method(object obj,EventArgs eargs)
        {
            MessageBox.Show("hello");
            Panel p1 = (Panel)p;

        }
    }
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.