递归类型特定控件 enable.state 设置

Recursive type-specific control enable.state setting

我正在尝试构建一个快速子程序,它将禁用表单上和该表单上的任何容器内给定类型 T 的所有控件,例如 GroupBox

我目前(下面)的代码似乎出于某种原因恼人地忽略了 GroupBox 控件(而且我意识到我只用 Form 容器尝试过它,否则它确实有效)。

Private Sub ChangeControlEnabledState(Of T As Control)(cc As ContainerControl, state As Boolean)
    Dim cl As ControlCollection = cc.Controls
    For Each c As Object In cc.Controls ' Iterate through every object in the container
        If TypeOf c Is T Then   ' Check if the object matches the type to set the state on
            CType(c, T).Enabled = state ' Set the state on the matching object
        ElseIf TypeOf c Is ContainerControl Then    ' Check if the object is a "sub" container type
            ChangeControlEnabledState(Of T)(c, state)   ' Recurse to handle the controls within the "sub" container
        End If
    Next
End Sub

'Usage
ChangeControlEnabledState(Of Button)(Me, False) 'Changes all buttons on this form to Button.Enabled = false

也许 GroupBox 不是 ContainerControl

编辑: 调整为:

        For Each c As Control In cc ' Iterate through every object in the container
            If TypeOf c Is T Then   ' Check if the object matches the type to set the state on
                CType(c, T).Enabled = state ' Set the state on the matching object
            ElseIf c.HasChildren Then  ' Check if the control has children
                ChangeControlEnabledState(Of T)(c.Controls, state)   ' Recurse to handle the child controls
            End If
        Next

但这会在第一个 GroupBox 尝试递归时引发异常:

System.InvalidCastException {"[A]ControlCollection cannot be cast to [B]ControlCollection. Type A originates from 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' in the context 'Default' at location 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll'. Type B originates from 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' in the context 'Default' at location 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll'."} System.InvalidCastException

据我有限的理解,这似乎是说不能将 X 类型转换为 X 类型,因为它是 X 类型...

不确定这是否有帮助,但我使用 control.haschildren 来确定递归调用。

Private Sub SetEnterHandler(ByVal ParentCtrl As Control)
    'recursive call to find all controls that can have focus
    For Each c As Control In ParentCtrl.Controls
        If c.HasChildren Then
            SetEnterHandler(c)
        Else
            'do non-container stuff here
        End If
    Next
End Sub

我从初始化子中调用这个子:

    For Each c As Control In Me.Controls
        If c.HasChildren Then SetEnterHandler(c)
    Next

我是形式。

此错误是因为 ContainerControl 是在“System.Windows.Forms”命名空间的 Control Class 中定义的,它是表单和任何控件的父级 class .
来自 Control 的所有子 classes 正在生成他们自己的 ControlCollection class,这并不是真正需要的。

只要使用Control.ContainerControl显式定义,这个错误就会消失!