1

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.

Neal
  • 13
  • 1
  • 4
  • Are you using a master page? – Karl Anderson Oct 31 '13 at 14:17
  • 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 Oct 31 '13 at 14:19
  • 1
    Dynamic added controls won't be present at the PostBack. Check this out: http://forums.asp.net/t/1186195.aspx – melancia Oct 31 '13 at 14:21
  • 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 Oct 31 '13 at 14:23
  • Ah, thank you very much, MelanciaUK. I will check that out. That looks like it's my problem. – Neal Oct 31 '13 at 14:23
  • did you add it to the page? – terrybozzio Oct 31 '13 at 14:24
  • It's all about on which step on the Page life cycle you're adding them. – melancia Oct 31 '13 at 14:25
  • @Karl: Well since I'm unfamiliar with now ASP/C# works, all of this is on the same page, I'm just showing/hiding the panels and I did not think that the controls would be lost after submitting. But they are multiline textboxes when I create them in C#. I guess HTML displays them as textareas. – Neal Oct 31 '13 at 14:26
  • yes first panel added to page then controls to panel – terrybozzio Oct 31 '13 at 14:26
  • @Neal - ah yes multi-line text boxes would display that way, just wanted to make sure you were comparing apples to apples. :-) – Karl Anderson Oct 31 '13 at 14:28
  • @terrybozzio: Yes, in my 3rd sample code block: `Panel2.Controls.Add(symptomsList[litList.IndexOf(singleItem)]);` – Neal Oct 31 '13 at 14:29
  • possible duplicate of [ASP.NET dynamically created controls and Postback](http://stackoverflow.com/questions/4216329/asp-net-dynamically-created-controls-and-postback) – melancia Oct 31 '13 at 14:30
  • yes but that is control added to panel,do you first add panel to the page? – terrybozzio Oct 31 '13 at 14:30
  • @MelanciaUK: In Panel1 I have a multiline textbox where the user enters the list of hostnames, with a button `Submit`. `Submit_Click()` adds the controls to Panel2, then sets Panel1's visibility to false and Panel2's visibility to true. – Neal Oct 31 '13 at 14:31
  • @terrybozzio: The panel is there to begin with in the page markup. The panel is not dynamically created/added. – Neal Oct 31 '13 at 14:32

1 Answers1

1

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.

Karl Anderson
  • 33,426
  • 12
  • 62
  • 78