Search code examples
c#asp.netdynamic-controls

Cannot access dynamic Textbox/DropDown controls in a dynamic table inside a Panel


Okay so I have this panel inside a table's td.

In this panel I'm creating a dynamic table with text box and drop down controls on a button click.

Problem is that When trying to receive the controls, I FAIL. I've checked literally like more than 25 websites and couldn't find a decent solution or something similar to mine.

Here's the code in which I'm trying to access the controls. It's inside a button event handler.

         for (int i = 0; i < ClickCount; i++)
        {
            //Control myControls = Page.FindControl("table1");
            //Panel myPanel = (Panel)mainTable.FindControl("Panel1");
            //Table myTable = (Table)myPanel.FindControl("table1");
            string FirstName = null;
            string LastName = null;
            string Age = null;
            string PCountry = null;
            string PCommittee = null;

            TextBox txtF = (TextBox)Panel1.FindControl("TextBoxF" + i.ToString());
            FirstName = txtF.Text;

            TextBox txtL = (TextBox)Panel1.FindControl("TextBoxL" + i.ToString());
            LastName = txtL.Text;

            TextBox txtA = (TextBox)Panel1.FindControl("TextBoxA" + i.ToString());
            Age = txtA.Text;

            DropDownList ddlPCountry = (DropDownList)myTable.FindControl("ddlPCountry" + i.ToString());
            PCountry = ddlPCountry.SelectedValue;

            DropDownList ddlPCommittee = (DropDownList)myTable.FindControl("ddlCommittee" + i.ToString());
            PCommittee = ddlPCommittee.SelectedValue;


            string groupInsert = "insert into GroupUser (GroupUserID, FirstName, LastName, Age, PreferredCountry, PreferredCommittee) ";
            groupInsert += "values (@GroupUserID, @FirstName, @LastName, @Age, @PreferredCountry, @PreferredCommittee);";

            SqlCommand group = conn.CreateCommand();
            group.CommandType = CommandType.Text;
            group.CommandText = groupInsert;

            group.Parameters.Add(new SqlParameter("@GroupUserID", ID));
            group.Parameters.Add(new SqlParameter("@FirstName", FirstName));
            group.Parameters.Add(new SqlParameter("@LastName", LastName));
            group.Parameters.Add(new SqlParameter("@Age", Age));
            //group.Parameters.Add(new SqlParameter("@PreferredCountry", ddlPCountry.SelectedValue));
            //group.Parameters.Add(new SqlParameter("@PreferredCommittee", ddlPCommittee.SelectedValue));

            int temp = group.ExecuteNonQuery();

        }

        Response.Redirect("StartPage.aspx");

Here's the creation of the controls in another button event handler.

        Table table = new Table();
        table.ID = "table1";

        for (int i = 0; i < ClickCount; i++)
        {
            TableRow row1 = new TableRow();
            TableRow row2 = new TableRow();
            TableRow row3 = new TableRow();
            TableRow row4 = new TableRow();
            TableRow row5 = new TableRow();
            TableRow row6 = new TableRow();
            TableRow row7 = new TableRow();

            TextBox TxtBoxF = new TextBox();
            TextBox TxtBoxL = new TextBox();
            TextBox TxtBoxA = new TextBox();

            DropDownList ddlPCountry = new DropDownList();
            DropDownList ddlPCommittee = new DropDownList();

            Label lblF = new Label();
            Label lblL = new Label();
            Label lblA = new Label();
            Label lblPCountry = new Label();
            Label lblPCommittee = new Label();

            TxtBoxF.ID = "TextBoxF" + i.ToString();
            TxtBoxL.ID = "TextBoxL" + i.ToString();
            TxtBoxA.ID = "TextBoxA" + i.ToString();

            ddlPCountry.ID = "ddlPCountry" + i.ToString();
            ddlPCommittee.ID = "ddlPCommittee" + i.ToString();

            lblF.ID = "LabelF" + i.ToString();
            lblL.ID = "LabelU" + i.ToString();
            lblA.ID = "LabelA" + i.ToString();
            lblPCountry.ID = "LabelPCountry" + i.ToString();
            lblPCommittee.ID = "LabelPCommittee" + i.ToString();

            lblF.Text = "First Name: ";
            lblL.Text = "Last Name :";
            lblA.Text = "Age: ";
            lblPCountry.Text = "Preferred Country: ";
            lblPCommittee.Text = "Preferred Committee: ";

            ddlPCountry.DataSource = countryDt;
            ddlPCountry.DataValueField = "CountryID";
            ddlPCountry.DataTextField = "CountryName";
            ddlPCountry.DataBind();

            ddlPCommittee.DataSource = committeeDt;
            ddlPCommittee.DataValueField = "CommitteeID";
            ddlPCommittee.DataTextField = "CommitteeName";
            ddlPCommittee.DataBind();

            TxtBoxF.Attributes.Add("runat", "server");
            TxtBoxL.Attributes.Add("runat", "server");
            TxtBoxA.Attributes.Add("runat", "server");

            ddlPCountry.Attributes.Add("runat", "server");
            ddlPCommittee.Attributes.Add("runat", "server");

            for (int a = 0; a < 2; a++)
            {
                TableCell cell1 = new TableCell();
                TableCell cell2 = new TableCell();

                cell1.Controls.Add(lblF);
                cell2.Controls.Add(TxtBoxF);
                row1.Controls.Add(cell1);
                row1.Controls.Add(cell2);
            }

            for (int b = 0; b < 2; b++)
            {
                TableCell cell1 = new TableCell();
                TableCell cell2 = new TableCell();

                cell1.Controls.Add(lblL);
                cell2.Controls.Add(TxtBoxL);
                row2.Controls.Add(cell1);
                row2.Controls.Add(cell2);
            }

            for (int c = 0; c < 2; c++)
            {
                TableCell cell1 = new TableCell();
                TableCell cell2 = new TableCell();

                cell1.Controls.Add(lblA);
                cell2.Controls.Add(TxtBoxA);
                row3.Controls.Add(cell1);
                row3.Controls.Add(cell2);
            }

            for (int d = 0; d < 2; d++)
            {
                TableCell cell1 = new TableCell();
                TableCell cell2 = new TableCell();

                cell1.Controls.Add(lblPCountry);
                cell2.Controls.Add(ddlPCountry);
                row4.Controls.Add(cell1);
                row4.Controls.Add(cell2);
            }

            for (int f = 0; f < 2; f++)
            {
                TableCell cell1 = new TableCell();
                TableCell cell2 = new TableCell();

                cell1.Controls.Add(lblPCommittee);
                cell2.Controls.Add(ddlPCommittee);
                row5.Controls.Add(cell1);
                row5.Controls.Add(cell2);
            }

            table.Rows.Add(row1);
            table.Rows.Add(row2);
            table.Rows.Add(row3);
            table.Rows.Add(row4);
            table.Rows.Add(row5);

        }
        Panel1.Controls.Add(table);
        Panel1.Controls.Add(new LiteralControl("<br />"));
        Panel1.Controls.Add(new LiteralControl("<br />"));
        conn.Close();

Here's the aspx:

<body>
<form id="form1" runat="server">
<div>
<h1>Group Registration</h1>
    <br />
    <table style="width:100%;" id="mainTable" runat="server">
        <tr>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>First Name:</td>
            <td>
                <asp:TextBox ID="txtFirstName" runat="server"></asp:TextBox>
            </td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>Last Name:</td>
            <td>
                <asp:TextBox ID="txtLastName" runat="server"></asp:TextBox>
            </td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>Age:</td>
            <td>
                <asp:TextBox ID="txtAge" runat="server"></asp:TextBox>
            </td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td class="auto-style1">Contact Number:</td>
            <td class="auto-style1">
                <asp:TextBox ID="txtContactNumber" runat="server"></asp:TextBox>
            </td>
            <td class="auto-style1"></td>
        </tr>
        <tr>
            <td>Email Address:</td>
            <td>
                <asp:TextBox ID="txtEmail" runat="server"></asp:TextBox>
            </td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>Institute</td>
            <td>
                <asp:TextBox ID="txtInstitute" runat="server" Width="400px"></asp:TextBox>
            </td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td class="auto-style1">Preferred Country:</td>
            <td class="auto-style1">
                <asp:DropDownList ID="ddlCountry" runat="server">
                </asp:DropDownList>
            </td>
            <td class="auto-style1"></td>
        </tr>
        <tr>
            <td>Preferred Committee:</td>
            <td>
                <asp:DropDownList ID="ddlCommittee" runat="server">
                </asp:DropDownList>
            </td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>Username:</td>
            <td><asp:TextBox ID="txtUsername" runat="server"></asp:TextBox>
            </td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>Password:</td>
            <td>
                <asp:TextBox ID="txtPassword" runat="server" TextMode="Password"></asp:TextBox>
            </td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td>
                <asp:Panel ID="Panel1" runat="server">
                </asp:Panel>
            </td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td>
                <asp:Button ID="btnAddAnother" runat="server" OnClick="btnAddAnother_Click" Text="Add Another Member" />
            </td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td>
                <asp:Button ID="btnRegister" runat="server" Text="Sign Up" OnClick="btnRegister_Click" />
            </td>
            <td>&nbsp;</td>
        </tr>
    </table>
</div>
</form>


Solution

  • Problem 1:

    You cannot access any control on the server-side (from C# code-behind) if it dosent have the attribute runat="server". So, you must add:

    .Attributes.Add("runat", "server");

    to every control that you want to access in your button event handler. After each control declaration, you must do the following:

    TxtBoxF.Attributes.Add("runat", "server");
    TxtBoxL.Attributes.Add("runat", "server");
    TxtBoxA.Attributes.Add("runat", "server");
    
    ddlPCountry.Attributes.Add("runat", "server");
    ddlPCommittee.Attributes.Add("runat", "server");
    
    lblF.Attributes.Add("runat", "server");
    lblL.Attributes.Add("runat", "server");
    lblA.Attributes.Add("runat", "server");
    lblPCountry.Attributes.Add("runat", "server");
    lblPCommittee.Attributes.Add("runat", "server");
    

    Problem 2:

    You should be searching for your controls in Panel1, not the tables. However, since I cannot see your ASPX Code, I am unsure if your panel has the attribute runat=server.

    I suggest you make the following change to your ASPX page:

    Change the after tag:

    <form id="form1" runat="server">
    <div>
    

    to

    <div id="myControls" runat="server">
    

    Then, at the end of your dynamic control creation, change:

    Panel1.Controls.Add(table);
    Panel1.Controls.Add(new LiteralControl("<br />"));
    Panel1.Controls.Add(new LiteralControl("<br />"));
    

    to

    myControls.Controls.Add(table);
    myControls.Controls.Add(new LiteralControl("<br />"));
    myControls.Controls.Add(new LiteralControl("<br />"));
    

    Then, in your control access code you need to change:

    TextBox txtF = (TextBox)Panel1.FindControl("TextBoxF" + i.ToString());
    TextBox txtL = (TextBox)Panel1.FindControl("TextBoxL" + i.ToString());
    TextBox txtA = (TextBox)Panel1.FindControl("TextBoxA" + i.ToString());
    DropDownList ddlPCountry = (DropDownList)myTable.FindControl("ddlPCountry" + i.ToString());
    DropDownList ddlPCommittee = (DropDownList)myTable.FindControl("ddlCommittee" + i.ToString());
    

    to

    TextBox txtF = (TextBox)myControls.FindControl("TextBoxF" + i.ToString());
    TextBox txtL = (TextBox)myControls.FindControl("TextBoxL" + i.ToString());
    TextBox txtA = (TextBox)myControls.FindControl("TextBoxA" + i.ToString());
    DropDownList ddlPCountry = (DropDownList)myControls.FindControl("ddlPCountry" + i.ToString());
    DropDownList ddlPCommittee = (DropDownList)myControls.FindControl("ddlCommittee" + i.ToString());
    

    Possible Problem 3:

    New controls should be created during Page Init. So you should take all your dynamic control creation code and put it inside page_init:

    protected void Page_Init(object sender, EventArgs e)
    {
       // Put dynamic controls creation here!
    }