Wednesday, March 28, 2012

Trouble accessing object before insertion into panel...

Hey everyone,

I have a script that presents the user with a variable number of text boxes (with the ID's "TextBox1", "TextBox2", "TextBox3", etc.) with an image button, and a label asking the user for input. All this is contained in a panel called Panel1. The user puts some text into the boxes and clicks the image button.

When clicked, the image button raises an event that tries and access the text the user entered in the text boxes, assign that text to a label, and display it in Panel2. It will then hide Panel1 and make Panel2 visible. The event generates an error however. I don't understand the error because the code seems straight forward. Here is the code (intTxtCount contains the number of text boxes that the user was presented with):


Public Sub cmdContinueToDeparturePoints(Sender As Object, e As System.Web.UI.ImageClickEventArgs)

Dim i As Integer
For i = 1 To intTxtCount
Dim lblName As New Label()
lblName.ID = "lblName" & i
Dim txtTemp As TextBox
txtTemp = FindControl("TextBox" & i)
lblName.Text = txtTemp.Text '''' Error Generating Line
Panel2.Controls.Add(lblName)
Panel2.Controls.Add(New LiteralControl("<br>"))
Next i

Panel1.Visible = False
Panel2.Visible = True

End Sub


Here is the Error:

System.NullReferenceException: Object reference not set to an instance of an object.

I think this error is telling me that a control called lblName does not exist physically in my panel, which is true. But if I reference lblName the object (the one I just declared in the sub) shouldn't that be okay? Am I wrong?

Bewildering...Mike :-/1. NullReferenceException is one of the most common programming errors. So it will help to really learn it well. It means that an object that is being dereferenced (the object followed by a period) is 'null' or 'nothing' in VB terms.

In this line, there are two objects being dereferenced:
lblName.Text = txtTemp.Text

lblName is created just above and you dereferenced it when you assigned the ID. So that's not it. txtTemp is the result of FindControl. You are assuming that you will find a control with the ID "TextBox1" (or whatever number 'i' is when this fails). It is returning null at some point.

2. Its likely that you have not recreated the same list of TextBoxes on post back before this loop executes. Also consider that you have a loop maximum in variable that may not reflect the true number of textboxes.

3. If you are going to write code, please consider using a debugger. Single-step through code and review the values of variables, parameters, and properties as things happen. The debugger would stop on the line with the error and let you open a Watch or Local Variable window to see what the values are in lblName and txtTemp.
Peter,

Thanks for such a great response. Yes, I should be using a debugger. If only my company were not so cheap as to let me code without VisualStudio.NET... :-(

Ok. So we have managed to conclude that lblName is not generating the Null Exception. It must be that no value is being assigned to txtTemp.Text from "TextBox1". Your comments in line item number 2 really interest me:

What do you mean by, "you have not recreated the same list of TextBoxes on post back before this loop executes"? I have never had to "recreate" a form for a PostBack event. I don't even know what you mean by that. And as for the maximum loop variable, I am positive this value is correct every time the script runs. The HTML that the server generages clearly shows me the correct number of text boxes, all with the correct names (TextBox1, T...2, T...3, etc.). I don't understand why when this form is submitted and I try to assign the boxes values they are null. Just don't get it.

Here is some code that works fine, this is what I based my current work on:


Sub Page_Load(sender As Object, e As EventArgs)

Dim t As New TextBox()
Dim i As Integer = 1
t.Text = "testtext" & i.ToString()
t.ID = "myTextBox" & i.ToString()
Panel1.Controls.Add(t)
ViewState("i") = i

End Sub

Sub GetTextBoxValueAndAssignToLabel(sender As Object, e As System.EventArgs)

Dim i As Integer
i = ViewState("i")
Dim txtTemp As TextBox
txtTemp = FindControl("myTextBox" & i)
lblTest.Text = txtTemp.Text

End Sub


As you can see, a text box is created that has an ID of "myTextBox1". The number i is passed via ViewState to the event code for the button, and the Text property of the text box is successfully assigned to the label. As far as I can see, the only difference between my code and the code here is that the label control already exists in the form instead of the on-the-fly label creation I used.
Let's start with that darn debugger issue. My sympathies about your situation. The time you waste without a debugger will easily exceed the cost of VS.NET.

In the meantime, did you know that .net framework comes with a debugger? Lookup "DbgClr.exe" at MSDN.Microsoft.com. I have not used it though, since I'm using VS.NET.

On to your code. I'm confused by this, perhaps because you simplified it. I though you had a loop going on. I'm interested in that loop. For example, if you are assigning ViewState("i") = i in each interation of the loop, you are not changing the key passed to ViewState, and thus overwriting the value.

Please do this too: set <@.Page Trace=true >. When the page is first generated, it will show you each control by its ID. FindControl will only search in the "naming container" of that method. In this case, whatever object contains GetTextBoxValueAndAssignToLabel() is the naming container you are searching. If you did Panel1.FindControl, you will be assured of getting values from Panel1. Another thing you can do is simply grab each unique item in Panel1.Controls.
Panel1.Controls(0) - contains TextBox1
Panel1.Controls(1) - contains TextBox2

0 comments:

Post a Comment