Cannot cast from ControlCollection to ControlCollection
-
I'm trying to write a method that loops through a form and dumps the name of all controls and the data from each control into a string, it works fine until it gets to a control that its self has controls in it, like a tabcontrol. Is there any work around so I can get this to work in a single method? The getValue(childControl) function simply uses a typeof check and returns the data of that control as a string. Any help would be appreciated.
Public Function reportApplicationState(ByVal controlList As Windows.Forms.Form.ControlCollection) As String Dim strIndent As String = "" Dim report As String = "" Dim childControl As Control For Each childControl In controlList If childControl.Controls.Count > 0 Then layoutIndent &= " " report &= childControl.Name & ControlChars.CrLf Dim nextChildControl As Control For Each nextChildControl In childControl.Controls reportApplicationState(nextChildControl.Controls) Next Else report &= layoutIndent & childControl.Name & getValue(childControl) & controlChars.CrLf End If Next Return report End Function
-
I'm trying to write a method that loops through a form and dumps the name of all controls and the data from each control into a string, it works fine until it gets to a control that its self has controls in it, like a tabcontrol. Is there any work around so I can get this to work in a single method? The getValue(childControl) function simply uses a typeof check and returns the data of that control as a string. Any help would be appreciated.
Public Function reportApplicationState(ByVal controlList As Windows.Forms.Form.ControlCollection) As String Dim strIndent As String = "" Dim report As String = "" Dim childControl As Control For Each childControl In controlList If childControl.Controls.Count > 0 Then layoutIndent &= " " report &= childControl.Name & ControlChars.CrLf Dim nextChildControl As Control For Each nextChildControl In childControl.Controls reportApplicationState(nextChildControl.Controls) Next Else report &= layoutIndent & childControl.Name & getValue(childControl) & controlChars.CrLf End If Next Return report End Function
Additional info: reportApplicationState(nextChildControl.Controls) - throws exception Exception thrown at runtime: System.InvalidCastException was unhandled Message="Unable to cast object of type 'ControlCollection' to type 'ControlCollection'." Source="detailedErrorReports" StackTrace: at detailedErrorReports.StateReport.reportApplicationState(ControlCollection controlList) in C:\Documents and Settings\Ed\My Documents\Visual Studio 2005\Projects\detailedErrorReports\detailedErrorReports\StateReport.vb:line 12 at detailedErrorReports.Form1.Button1_Click(Object sender, EventArgs e) in C:\Documents and Settings\Ed\My Documents\Visual Studio 2005\Projects\detailedErrorReports\detailedErrorReports\Form1.vb:line 5 sorry about the code sample indentation
-
I'm trying to write a method that loops through a form and dumps the name of all controls and the data from each control into a string, it works fine until it gets to a control that its self has controls in it, like a tabcontrol. Is there any work around so I can get this to work in a single method? The getValue(childControl) function simply uses a typeof check and returns the data of that control as a string. Any help would be appreciated.
Public Function reportApplicationState(ByVal controlList As Windows.Forms.Form.ControlCollection) As String Dim strIndent As String = "" Dim report As String = "" Dim childControl As Control For Each childControl In controlList If childControl.Controls.Count > 0 Then layoutIndent &= " " report &= childControl.Name & ControlChars.CrLf Dim nextChildControl As Control For Each nextChildControl In childControl.Controls reportApplicationState(nextChildControl.Controls) Next Else report &= layoutIndent & childControl.Name & getValue(childControl) & controlChars.CrLf End If Next Return report End Function
I'd probably rewrite this so you don't have a "nextChildControl" section. One level should be enough. Speaking of level, I'd also change this method to take as parameters a ControlCollection AND an interger representing depth, so you can have a collection in a collection in a collection, ... Probably something like this:
Public Function reportApplicationState(ByVal controlCollection As ControlCollection, Optional ByVal childDepth As Integer = 0) As String
Dim layoutIndent As New String(" "c, childDepth)
Dim report As String = String.Empty
Dim childControl As ControlFor Each childControl In controlCollection If childControl.Controls.Count > 0 Then report &= childControl.Name & ":" & Environment.NewLine report &= reportApplicationState(childControl.Controls, childDepth + 1) Else report &= layoutIndent & childControl.Name & getValue(childControl) & Environment.NewLine End If Next Return report
End Function
This is by no means tested, but you should get the idea...
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007 -
I'd probably rewrite this so you don't have a "nextChildControl" section. One level should be enough. Speaking of level, I'd also change this method to take as parameters a ControlCollection AND an interger representing depth, so you can have a collection in a collection in a collection, ... Probably something like this:
Public Function reportApplicationState(ByVal controlCollection As ControlCollection, Optional ByVal childDepth As Integer = 0) As String
Dim layoutIndent As New String(" "c, childDepth)
Dim report As String = String.Empty
Dim childControl As ControlFor Each childControl In controlCollection If childControl.Controls.Count > 0 Then report &= childControl.Name & ":" & Environment.NewLine report &= reportApplicationState(childControl.Controls, childDepth + 1) Else report &= layoutIndent & childControl.Name & getValue(childControl) & Environment.NewLine End If Next Return report
End Function
This is by no means tested, but you should get the idea...
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007Your right in saying only one level is needed, the inner loop was only added after i initially had problems. This works fine for all controls on the controlList passed in, but when it calls its self when it finds a control with child controls i get an error casting from the child controls to a control list even though they appear to be of the same type. Any ideas on why the cast fails would be appreciated.