Why are controls missing from Me.Controls()
Hey guys. I must be missing something. I am trying to cycle throught the lables on my form but it would appear that I am missing quite a few labels... I have a total of 69 lables on my form and I only get 5 hits on the msgbox. All controls were placed on design time on the form and not on panels or tabs. Also upon i开发者_如何学运维nspecting the me.controls. the count is incorrect as it is missing exactly 64 controls. (The missing lables).
Dim ctl As Control
For Each ctl In Me.Controls
If TypeOf ctl Is Label Then
MsgBox(ctl.Name)
End If
Next ctl
Any ideas why they would not show up?
Brad Swindell
The Controls collection is a heirarchy. You are only getting top level controls. If you want to get all controls then you will need to recursively dig into each child controls Control collection.
All controls were placed on design time on the form and not on panels or tabs.
Remember that GroupBox
is also a control, with it's own Controls property as well.
This function should give you what you want, but my VB.Net is very, very rusty so if it doesn't compile I apologize.
Private Sub PrintAllControlsRecursive(col As Control.ControlCollection, ctrlType As Type)
If col Is Nothing OrElse col.Count = 0 Then
Return
End If
For Each c As Control In col
If c.GetType() = ctrlType Then
MessageBox.Show(c.Name)
End If
If c.HasChildren Then
PrintAllControlsRecursive(c.Controls, ctrlType)
End If
Next
End Sub
Sub PrintAllControls(ByVal ParentCtl As Control)
Dim ctl As Control
MsgBox(ParentCtl.Name + " start", MsgBoxStyle.Exclamation)
For Each ctl In ParentCtl.Controls
MsgBox(ctl.Name)
If ctl.HasChildren = True Then
PrintAllControls(ctl)
End If
Next
MsgBox(ParentCtl.Name + " End", MsgBoxStyle.Information)
End Sub
Flatten.
Just use LINQ and a recursive lambda with selectmany to flatten the hierarchy:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim act As Func(Of Control, IEnumerable(Of Control)) =
Function(ctl) ctl.Controls.Cast(Of Control)().SelectMany(
Function(ctl2) ctl2.Controls.Cast(Of Control)().
Union(act(ctl2))).Union(ctl.Controls.Cast(Of Control))
MsgBox(Join((From c In act(Me).Distinct Order By c.Name
Select c.Name & "--" & c.GetType.ToString).ToArray, vbCrLf))
End Sub
Not barnyard programming at all nor chance of repeated items or obscure bugs...
be sure that you're finding controls AFTER the form has been completelly charged, otherwise if you try to list controls during load process the me.controls.count will be zero.
精彩评论