9

I am trying to loop through my repeater control and get the textbox values.
However, I am getting an error:

{"Object reference not set to an instance of an object."}

my code is:

    Dim txtField As TextBox
    Dim j As Integer = 0

   'Confirm if user has entered atleast one quantity
    For Each item In rptRequestForm.Items
        txtField = rptRequestForm.FindControl("txtBox")
        If txtField.Text <> Nothing Then
            j += 1
        Else

        End If
    Next

UPDATE: aspx code is:

        <td><asp:Repeater ID="rptRequestForm" runat="server">
            <HeaderTemplate>
                    <table border="0" width="100%">
                        <tr>
                            <td style="width:50%" class="TextFontBold"><asp:Label runat="server" ID="Label1" Text="Product"></asp:Label></td>
                            <td style="width:25%" class="TextFontBold"><asp:Label runat="server" ID="Label2" Text="Quantity"></asp:Label></td>
                            <td style="width:25%" class="TextFontBold"><asp:Label runat="server" ID="Label3" Text="Price (ea.)"></asp:Label></td>
                        </tr>
                    </table>
            </HeaderTemplate>
                <ItemTemplate>
                    <table border="0" width="100%">
                        <tr>
                            <td style="width:50%" class="TextFont"><span><%#Trim(Eval("Product_Title"))%></span></td>
                            <td style="width:25%"><asp:TextBox ID="txtBox" runat="server" Width="30%" onblur="Javascript:numberonly(this)"></asp:TextBox></td>
                            <td style="width:25%" class="TextFont"><span><%#Trim(FormatCurrency(Eval("Price")))%></span></td>
                        </tr>
                    </table>
                </ItemTemplate>
            </asp:Repeater>
Frank
  • 2,015
  • 10
  • 36
  • 57

4 Answers4

15

try

Dim someString as String = "Not set"  <-- used later to hold the values of the string
Dim txtField As TextBox    
Dim j As Integer = 0   
'Confirm if user has entered atleast one quantity    
For Each item In rptRequestForm.Items        
   txtField = item.FindControl("txtBox")        
   If Not IsNothing(txtField) Then      ' <--- this is the line I changed       
     j += 1  
     someString = txtField.Text ' <--  once you've checked and know that the textbox exists, you just grab the value like so. 
     ' do whatever you like with the contents of someString now.     
   Else        
   End If    
Next

The problem is that you're trying to access the ".Text" property of a TextBox that it didn't find. The TextBox itself is the object to which there is no reference.

Incidentally, the .Text property of an actual Textbox (one that exists and was found) can't be "Nothing". It can only be String.Empty or a valid string.

Edited my line of code

Sorry, my VB is rusty.

Final edit

AARGH! I'm blind. I can't believe I didn't see this. There were TWO problems withthe original code. This is the answer to the second issue:

Change

txtField = rptRequestForm.FindControl("txtBox")

to

txtField = item.FindControl("txtBox")

The ITEM has to find the control, not the repeater itself!

I created a small web app just to check to see if I was grabbing the textbox's text and finally found the issue above. my code is NOT the same as yours in the aspx, but here's a complete code listing so that you can see how it works:

vb code

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim t As New System.Data.DataTable

        t.Columns.Add("Name")

        Dim newRow(1) As Object

        t.Rows.Add(New Object() {"Frank"})
        t.Rows.Add(New Object() {"Dave"})
        t.Rows.Add(New Object() {"Muhammad"})

        rptRequestForm.DataSource = t
        rptRequestForm.DataBind()

        Dim txtField As TextBox
        Dim j As Integer = 0   'Confirm if user has entered atleast one quantity    
        For Each item As RepeaterItem In rptRequestForm.Items
            txtField = item.FindControl("txtBox")
            If Not IsNothing(txtField) Then     ' <--- this is the line I changed            
                j += 1
                System.Diagnostics.Debug.WriteLine(item.ItemType.ToString())
                System.Diagnostics.Debug.WriteLine(txtField.Text)
            Else
                System.Diagnostics.Debug.WriteLine(item.ItemType.ToString())
            End If
        Next
End Sub

aspx code

<asp:Repeater ID="rptRequestForm" runat="server">
        <HeaderTemplate>
            Hello!
        </HeaderTemplate>
        <ItemTemplate>
            <asp:TextBox ID="txtBox" runat="server" Text='<%#Bind("Name") %>'></asp:TextBox>
            <br />
        </ItemTemplate>
</asp:Repeater>

produces the following output in the System.Diagnostics.Debug window:

Item

Frank

AlternatingItem

Dave

Item

Muhammad

The thread 0x321c has exited with code 0 (0x0).

The thread 0x39b8 has exited with code 0 (0x0).

David
  • 72,686
  • 18
  • 132
  • 173
  • David, I get an error message: Operator '<>' is not defined for types 'System.Web.UI.WebControls.TextBox' and 'System.Web.UI.WebControls.TextBox'. – Frank Aug 12 '11 at 17:21
  • use "if not txtField is nothing then". VB uses different equality statements for reference types & value types – Simon Halsey Aug 12 '11 at 17:26
  • You're right - I edited my answer. Try the new line of code. My VB is rusty, and checking for a null reference is different in C#. In C# it would be "!= null" - I have a hard time switching back and forth for some of these simple things. – David Aug 12 '11 at 17:29
  • My updated answer compiles just fine - I tested it this time to ensure I had the right syntax. – David Aug 12 '11 at 17:31
  • it does compile, but it does not get me the textbox.text value – Frank Aug 12 '11 at 17:38
  • OK. re-edited to show how to grab the value once you've checked for the existence of the textbox. – David Aug 12 '11 at 17:41
  • I appreciate you working with me on this... but when I walk through the code, it goes into the "ELSE" clause..... – Frank Aug 12 '11 at 17:44
  • That means that the textbox is not being found. Can you show the code for the repeater as well? from the aspx page, not the .aspx.vb file? – David Aug 12 '11 at 17:48
  • @Frank let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2419/discussion-between-david-stratton-and-frank) – David Aug 12 '11 at 18:10
  • it works in the sense that the original error is gone. However, I am still not getting the txtBox.Text value :-( – Frank Aug 12 '11 at 18:12
  • Did you change the line of code from txtField = rptRequestForm.FindControl("txtBox") to txtField = item.FindControl("txtBox") as instructed? – David Aug 12 '11 at 18:17
  • Sorry, looking at your asp, there IS no text in the textbox. You haven't set the Text property or bound it to anything. – David Aug 12 '11 at 18:21
  • The user enters a quantity in the textbox on the user interface (thats the value I want to eventually get) – Frank Aug 12 '11 at 18:23
  • Are you databinding the repeater in the Page_Load event without checking the Page.IsPostback property? – David Aug 12 '11 at 18:25
  • If you are, then the textbox values would get wiped out because DataBind() re-generates the entire repeater - none of the user input would be kept. And if it happens in the Page_Load, then it's happening before any other event handler (such as a button click, etc) (google the Page Lifecycle). – David Aug 12 '11 at 18:29
  • yes I was... I need a vacation. Thanks VERY MUCH for seeing me through to the solution David... I appreciate your help – Frank Aug 12 '11 at 18:33
  • Glad to help. Although that's an awful lot of work for a mere 35 points. It was a fun exercise, though. Cheers! ;-) – David Aug 12 '11 at 18:33
3

You have to properly cast it as Textbox e.g.

TextBox txtField = (TextBox)rptRequestForm.FindControl("txtBox") // C# code

Here is VB.NET code:

Dim txtField As TextBox = CType(rptRequestForm.FindControl("txtBox"), TextBox)
Appulus
  • 18,630
  • 11
  • 38
  • 46
Muhammad Akhtar
  • 51,913
  • 37
  • 138
  • 191
  • error message: 'TextBox' is a type and cannot be used as an expression. – Frank Aug 12 '11 at 17:20
  • unless switched off, VB lets you do implicit casting as the OP has done. – Simon Halsey Aug 12 '11 at 17:23
  • @Muhammad, after trying your updated code, I still get the original error message: Object reference not set to an instance of an object. – Frank Aug 12 '11 at 17:28
  • Hey, you can't steal my edited answer as your own! His issue had nothing to do with casting, and even though I got the syntax wrong the first time, my answer was essentially correct. FOUL! Ref! ;-) – David Aug 12 '11 at 17:34
  • 2
    I know. that was "mock anger". No worries. I needed a laugh to break my daily monotony. Sorry, I was really only kidding. – David Aug 12 '11 at 17:36
1
Dim myText as string
Dim j As Integer = 0

'Confirm if user has entered atleast one quantity

For Each myItem as repeateritem In rptRequestForm.Items
    If NOT string.isnullorempty(CTYPE(myItem.FindControl("txtBox"),textbox).text) then
        j += 1
    End If
Next

I wouldn't use nothing -- not sure that causes a problem or not, but usually I see that for objects, not properties. String.IsNullOrNothing() is made for checking strings for null or empty ("").

You don't need to worry about whether or not the textbox exists, because if it exists in one row of the repeater, it will exist in all rows. I guess you could check it for 'nothing' if you weren't sure what "txtBox" was at design time...but otherwise, not necessary.

You should definately use the cast (CTYPE()). I think you might be able to get away with not using it if all you want is .text, but the CTYPE gives you access to all of the textbox's properties (not just it's inherited properties), and also, you might need to do checkboxes or other controls at some point where you pretty much have to CTYPE in order to get to .ischecked, etc.

Chains
  • 12,541
  • 8
  • 45
  • 62
  • same error message (occurs when it hits the "If NOT string...) Object reference not set to an instance of an object – Frank Aug 12 '11 at 18:06
  • @Frank -- you're not, by chance, doing this inside of a master page are you? (If so, try setting the "ClientID".) – Chains Aug 12 '11 at 18:24
  • Oh -- wait -- I see the problem (I think) -- will amend my answer. – Chains Aug 12 '11 at 18:30
0

I made a generic method for set the property visible, I think you can take it as an example

Sub SetVisibleControlRepeater(ByRef repetidor As Repeater, ByVal idControl As String, ByVal esVisible As Boolean)

        For Each item As RepeaterItem In repetidor.Items

            Dim boton As System.Web.UI.WebControls.Button = CType(item.FindControl(idControl), Button)

            boton.Visible = esVisible

        Next

    End Sub
Samer
  • 1,923
  • 3
  • 34
  • 54
Doberon
  • 611
  • 9
  • 19