get control recursion

  • Thread starter Thread starter bannaman
  • Start date Start date
B

bannaman

I am using the function below to returns a control to the recursionobj
object. For some reason when i get to the line 'If
child.ID.ToString.ToUpper = toFind.ToUpper Then' it errors saying
object reference not set to an instance of an object. Can anyone tell
me why this would happen?

Public Sub getControl(ByVal passedCtrl As Control, ByVal toFind As
String)

For Each child As Control In passedCtrl.Controls

If (TypeOf child Is TextBox) Or (TypeOf child Is
HiddenField) Or (TypeOf child Is Label) Then
If child.ID.ToString.ToUpper = toFind.ToUpper Then
recursionobj = child
End If
End If
If child.Controls.Count > 0 Then
getControl(child, toFind)
End If
Next
End Sub
 
Is the value of child.ID or toFind ever a nothing/null string? That
would cause ToString to raise an exception

Actually do you need to do ToString on child.ID isn't that already a
string type?

Also you might want to try a case insensitive compare:
String.Compare(child.ID, toFind, true) = 0
 
There is never a null value in either child.id or tofind. The problem
seems to be it is getting into the first if statement even if the
typeof child is not one of the types listed.
 
Wouldn't you want to pass "passedCtrl" by reference? Passing it by
value causes every call to the method to make a copy of the control.
However, I'm not a VB coder, so I might be wrong -- I wouldn't be
surprised if passing an object-type parameter by value ends up passing
it by reference, anyway...

Anyway, I don't know if this is the problem -- but maybe if a shallow
copy of the control is being passed as the parameter, maybe its ID
property doesn't get copied for some reason...

HTH
Luke

P.S. Unrelatedly, do you want to be exiting the method after
successfully finding the control? i.e.,

If child.ID.ToString.ToUpper = toFind.ToUpper Then
recursionobj = child
Return
End If
 
null (nothing in vb) is a valid value for ID, so you need to test.


if not child.ID is nothing then
If child.ID.ToString.ToUpper = toFind.ToUpper Then
recursionobj = child
End If
end if

as vb does not do if short circuits, it need to be a seperate test.

-- bruce (sqlwork.com)
 
bannaman said:
How do you exit a recursive control which could be ten controls deep.

That's the beauty of recursion -- it doesn't matter how many levels
deep you go (as long as it's not infinite!).

I modified your code a bit -- try this out (note that this code is
untested). Note that the getControl() method now returns the control
you're looking for, if found -- otherwise it returns Nothing. (Also
note that I use String.Compare(), which ignores case -- if the last
parameter is True -- so you can avoid the inefficiency of using
ToUpper().)

--------------------------------------------------------------------------

Public Function getControl(ByRef passedCtrl As Control, ByVal toFind As
String) As Control
Dim ctrl As Control

' Check whether passedCtrl is the control we're looking for
If (TypeOf child Is TextBox) Or (TypeOf child Is HiddenField) Or
(TypeOf child Is Label) Then
If String.Compare(passedCtrl.ID, toFind, True) Then
Return passedCtrl
End If
End If

' Check whether any children of passedCtrl is the control we're
looking for
If child.Controls.Count > 0 Then
For Each child As Control In passedCtrl.Controls
ctrl = getControl(child, toFind)
If Not ctrl Is Nothing Then
Return ctrl
End If
Next
End If

Return Nothing
End Function
....

Public Sub SomeSub()
recursionobj = getControl(someContrl, "someID")
If Not recursionobj Is Nothing Then
' Use your found control (a.k.a. recursionobj) here
Else
' Your control wasn't found
End If
End Sub
 
Back
Top