"Specified cast is not valid"...why?

BenRosa

Newcomer
Joined
Nov 3, 2005
Messages
6
Location
Tampa, Florida, USA
Greetings:

The below code complies w/o error, however, upon running it the above error msg is generated (by second line in below code). Thing is, I'm not sure why as I'm defining the variable as a type that is in the collection. :confused: (The routine is for making all child panels on a main panel invisible upon initial load.)

Any and all guidance will be appreciated.

Private Sub HideAllPanels(ByVal ThePanel As Panel)
For Each ControlObj As Panel In ThePanel.Controls
If ControlObj.GetType.ToString() = "Panel" Then
ControlObj.Visible = False
If ControlObj.Controls.Count > 0 Then
HideAllPanels(ControlObj)
End If
End If
Next
End Sub


Ed in Tampa
 
Try
Visual Basic:
    Private Sub HideAllPanels(ByVal ThePanel As Panel)
        For Each ControlObj As Control In ThePanel.Controls
            If TypeOf ControlObj Is Panel Then
                ControlObj.Visible = False
                If ControlObj.Controls.Count > 0 Then
                    HideAllPanels(ControlObj)
                End If
            End If
        Next
    End Sub

Because the panel can contain other controls as well as panels you need to use as Control in the for ... each loop.
 
PlausiblyDamp...

I think you almost have it...however, I have the option Strict "On" and therefore need to cast ControlObj as a Panel when sending it to HideAllPanels in the embedded call (code will not compile unless this cast is done...I think). Problem for me is that I'm having trouble in VB.Net getting that syntax correct (I code in C# in my day job).

In that language, I'd simply go HideAllPanels((Panel)ControlObj) but that's not working here.

Can someone show me how to cast this more general Control obj as a Panel (and I think I'll be on my way)? :D

Many thanks!

PlausiblyDamp said:
Try
Visual Basic:
    Private Sub HideAllPanels(ByVal ThePanel As Panel)
        For Each ControlObj As Control In ThePanel.Controls
            If TypeOf ControlObj Is Panel Then
                ControlObj.Visible = False
                If ControlObj.Controls.Count > 0 Then
                    HideAllPanels(ControlObj)
                End If
            End If
        Next
    End Sub

Because the panel can contain other controls as well as panels you need to use as Control in the for ... each loop.
 
Last edited:
Ok...casting successfully

Ok, after poking around...I found a nice little function called CType which did the trick for this casting task.

Here's the final version...(with chgs in bold):

Private Sub HideAllPanels(ByVal ThePanel As Panel)
For Each ControlObj As Control In ThePanel.Controls
If TypeOf ControlObj Is Panel Then
ControlObj.Visible = False
If ControlObj.Controls.Count > 0 Then
Dim ChildControlObj As Panel
ChildControlObj = CType(ControlObj, Panel)
HideAllPanels(ChildControlObj)

End If
End If
Next
End Sub


I couldn't cast directly, so had to create another var to hold the new Panel obj.

Thanks PD! :)
BenRosa said:
PlausiblyDamp...

I think you almost have it...however, I have the option Strict "On" and therefore need to cast ControlObj as a Panel when sending it to HideAllPanels in the embedded call (code will not compile unless this cast is done...I think). Problem for me is that I'm having trouble in VB.Net getting that syntax correct (I code in C# in my day job).

In that language, I'd simply go HideAllPanels((Panel)ControlObj) but that's not working here.

Can someone show me how to cast this more general Control obj as a Panel (and I think I'll be on my way)? :D

Many thanks!
 
Visual Basic:
    Private Sub HideAllPanels(ByVal ThePanel As Panel)
        For Each ControlObj As Control In ThePanel.Controls
            If TypeOf ControlObj Is Panel Then
                ControlObj.Visible = False
                If ControlObj.Controls.Count > 0 Then
                    HideAllPanels(DirectCast(ControlObj, Panel))
                End If
            End If
        Next
    End Sub
 
Not that you can't look this up in MSDN, but CType will perform a conversion if one is found, where as DirectCast will only perform a cast if the object being casted is an appropriate type. (i.e. an int can be CTyped to a string, but not DirectCasted. A Form can be DirectCasted to a control.)
 
"CType succeeds as long as there is a valid conversion defined between the expression and the type, whereas DirectCast requires the run-time type of an object variable to be the same as the specified type."
 
marble_eater said:
DirectCast will only perform a cast if the object being casted is an appropriate type...

True...and I'm thinking I'll be okay using DirectCast here (verses CType) as I am checking beforehand, if I've got a Panel control object. Besides, I'm all for the performance gain realized from DirectCast.

Great responses.

Thank you all. :)
 
Last edited:
If you check the type before hand, DirectCast should always succeed. But just a note, the performance gain of CType is very minimal in most circumstances. You would have to do alot of casting to see any speed boost.

As a general practice, though, I do avoid CType because there is a little appearent ambiguity to it. When compiled, CType will be converted to another cast that you can perform on your own anyways. It could be a DirectCast, a conversion between numeric types (CInt, CLong, CDbl), to/from a string (ToString, type.Parse). I think it's just nice to be explicit.
 
Back
Top