1
votes

I start with a page with a form and two panels, Panel1 and Panel2. Panel2 has dynamically generated controls based on a list of server hostnames that the user enters on Panel1. Pressing "submit" on Panel1 sets Panel1's visibility to false and Panel2's visibility to true. After pressing "Submit2" button on Panel2 with all of the fields filled out by the user, I want to get the information from these controls for processing. However, I use FindControl("symptoms_" + i.ToString()) (something along those lines, depending on each control name), but it is returning null.

Here is the form I start with, before controls are generated:

<form id="btil_form" runat="server">
    <div>
    <asp:Panel ID="Panel2" runat="server" Visible="False">
        <asp:Button ID="Submit2" runat="server" Text="Submit" OnClick="Submit2_Click" />
        <br />
        <asp:Literal ID="result" runat="server"></asp:Literal>
        <br />
    </asp:Panel>
</form>

Then after the controls are generated, the page source shows the correct ID values for each control:

<div id="Panel2">

    <input type="submit" name="Submit2" value="Submit" id="Submit2" />
    <br />

    Hostname: g1x5554<br />Issue Reported:
    <select name="issue_1" id="issue_1">
        <option value="blank"></option>
        <!-- snip -->
        <option value="VC Profile Issue">VC Profile Issue</option>
    </select>

<br />
Symptoms: <textarea name="symptoms_1" rows="2" cols="20" id="symptoms_1"></textarea>
<br />
Problem Notes: <textarea name="notes_1" rows="2" cols="20" id="notes_1"></textarea>

***** snip *****

</div>

Here is a sample of the code used to add these controls. symptomsList is a TextBox, containing the textboxes I am adding.

Panel2.Controls.Add(new Literal() { Text = "Symptoms: " });
Panel2.Controls.Add(symptomsList[litList.IndexOf(singleItem)]);

Then I go to loop through the controls associated with each host. Each of these controls has the same ID, so for controls "symptoms" and "notes", the IDs for each field will be "symptoms_1" and "notes_1" for the first host, "symptoms_2" and "notes_2" for the 2nd host, and so on. Within the loop, I try to get the control values like so:

TextBox thisTB = new TextBox();
thisTB = (TextBox)Panel2.FindControl("symptoms_" + i.ToString());
thisBTIL.symptoms = thisTB.Text;

However, apparently FindControl apparently returns null, and trying to cast the null as a TextBox throws a NullReferenceException when it reaches thisBTIL.symptoms = thisTB.Text;

Any help will be greatly appreciated! Many thanks.

1
Are you using a master page? - Karl Anderson
I don't believe so. I'm new to C#/ASP/.NET, I'm learning as I go on this project. I don't really know what a "master page" is. I just looked it up while typing this comment and no, I did not create a master page. - Neal
Dynamic added controls won't be present at the PostBack. Check this out: forums.asp.net/t/1186195.aspx - melancia
In your Page_Load are you creating the dynamic content every time? Also, textarea != TextBox, so your cast is failing because of that. - Karl Anderson
Ah, thank you very much, MelanciaUK. I will check that out. That looks like it's my problem. - Neal

1 Answers

1
votes

I would recommend rewriting your casting logic to this:

TextBox thisTB = Panel2.FindControl("symptoms_" + i.ToString()) as TextBox;

// Check to make sure the text box exists before we try to use it
if(thisTB != null)
{
    thisBTIL.symptoms = thisTB.Text;
}

The as operator does not throw an exception if the cast fails, but instead returns null, thus the need to check for null in the if.