James Wierzba
James Wierzba

Reputation: 17508

Dynamically generated controls not being found via FindControl

I have a asp:panel that on a button click, I add some number of checkboxes to dynamically.

On another button click, I need to look at these checkboxes and check if they are checked.

I can't find the controls. I've tried doing FindControl with the ID that I've supplied it, as well as the ClientID.

The markup with the panel that the checkboxes get placed into, and the two buttons:

<asp:Panel runat="server" ScrollBars="Vertical" ID="pnlEmailCheckboxes" Height="150">
    <br/>
    <asp:CheckBox runat="server" Text="Other" ID="cbOtherEmail"/>
    <asp:TextBox ID="txtOtherEmail" runat="server" Style="width: 270px;" CssClass="textbox-default"></asp:TextBox>
    <br/>
</asp:Panel>
<asp:LinkButton ID="btnSendEmail" Text="<span>Send Email</span>" runat="server" CssClass="page-footer-button-highlight" OnClick="btnSendEmail_Click"></asp:LinkButton>
<asp:LinkButton ID="btnCloseEmail" Text="<span>Close</span>" runat="server" CssClass="page-footer-button" CausesValidation="false" OnClick="btnCloseEmail_OnClick"></asp:LinkButton>

The event that generates the textboxes:

protected void btnEmail_Click(object sender, EventArgs e)
{
    List<CheckBox> cbList = new List<CheckBox>();
    for (int i = 0; i < 10; i++)
    {
        CheckBox cb = new CheckBox();
        cb.Text = "text" + i;
        cb.ID = Guid.newGuid().ToString();
        cb.ClientIDMode = ClientIDMode.Static;
        pnlEmailCheckboxes.Controls.AddAt(0, cb);
        pnlEmailCheckboxes.Controls.AddAt(0, new LiteralControl("<br/>"));
        cbList.Add(cb);
    }

    Session["checkboxes"] = cbList;
    mpeEmail.Show();
}

The button that tries to retrieve the textboxes (does not work):

protected void btnSendEmail_Click(object sender, EventArgs e)
{
    //the email recipients
    List<string> emailRecipients = new List<string>();

    List<CheckBox> cbList = (List<CheckBox>)Session["checkboxes"];

    foreach (CheckBox cb in cbList)
    {
        CheckBox cbClient = (CheckBox) pnlEmailCheckboxes.FindControl(cb.ClientID); //I've also tried to find it by cb.ID
        //null reference here, the checkbox cbClient was not found
        if (cbClient.Checked) emailRecipients.Add(cb.Text.Trim());
    }

    //Ive also tried this, it does not contain the dynamically generated checkboxes
    //var cbControls = pnlEmailCheckboxes.Controls.OfType<CheckBox>();
}

Edit:

The client side html even shows the with the correct ID that matches the ID I'm searching for.

<input id="00e3a485-2083-4ef8-810b-6ed4fb1f62f9" type="checkbox" name="ctl00$Body$00e3a485-2083-4ef8-810b-6ed4fb1f62f9">

Upvotes: 0

Views: 339

Answers (2)

James Wierzba
James Wierzba

Reputation: 17508

I've found a solution for my problem. If I add the controls in the OnInit method, I can see the checkboxes in the button click later on.

protected override void OnInit(EventArgs e)
{
    List<CheckBox> cbList = new List<CheckBox>();
    for (int i = 0; i < 10; i++)
    {
        CheckBox cb = new CheckBox();
        cb.Text = "text" + i;
        cb.ID = Guid.newGuid().ToString();
        pnlEmailCheckboxes.Controls.AddAt(0, cb);
        pnlEmailCheckboxes.Controls.AddAt(0, new LiteralControl("<br/>"));
        cbList.Add(cb);
    }

    Session["checkboxes"] = cbList;
}

Another problem is present now, each checkbox always has Checked==False even when they are Checked on the UI. However, this is cause for another question.

Upvotes: 0

Jesse Johnson
Jesse Johnson

Reputation: 1718

Try adding a unique ID to each dynamic control and setting the ClientIDMode = ClientIDMode.Static:

 List<CheckBox> cbList = new List<CheckBox>();
 for (int i = 0; i < 10; i++)
 {
    CheckBox cb = new CheckBox();
    cb.ID = "DynamicCb" + i";
    cb.ClientIDMode = ClientIDMode.Static;
    cb.Text = "text" + i;
    pnlEmailCheckboxes.Controls.AddAt(0, cb);
    pnlEmailCheckboxes.Controls.AddAt(0, new LiteralControl("<br/>"));
    cbList.Add(cb);
 }

Upvotes: 1

Related Questions