VB.NET - 迭代容器对象中的控件

Jos*_*ons 21 vb.net

我有一个带有"清除"按钮的表单.

当用户单击"清除"时,我想清除表单上所有可见元素的值.在日期控件的情况下,我想将它们重置为当前日期.

我的所有控件都包含在Panel中.

现在,我正在使用以下代码执行此操作.有没有比手动检查每种控件类型更简单的方法?这种方法似乎过于笨拙.

更糟糕的是,为了递归清除子容器内的控件(即面板中的组合框),我必须用重载的"GroupBox"版本重复整个怪物.

编辑:感谢您的建议,以下代码大大简化.

Private Sub btnClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClear.Click
    'User clicks Clear, so clear all the controls within this panel
    ClearAllControls(panMid, True) 'True indicates that yes, i want to recurse through sub-containers
End Sub

ClearAllControls(ByRef container As Panel, Optional Recurse As Boolean = True)   
  'Clear all of the controls within the container object
  'If "Recurse" is true, then also clear controls within any sub-containers
  Dim ctrl As Control
  For Each ctrl In container.Controls
      If (ctrl.GetType() Is GetType(TextBox)) Then
          Dim txt As TextBox = CType(ctrl, TextBox)
          txt.Text = ""
      End If
      If (ctrl.GetType() Is GetType(CheckBox)) Then
          Dim chkbx As CheckBox = CType(ctrl, CheckBox)
          chkbx.Checked = False
      End If
      If (ctrl.GetType() Is GetType(ComboBox)) Then
          Dim cbobx As ComboBox = CType(ctrl, ComboBox)
          cbobx.SelectedIndex = -1
      End If
      If (ctrl.GetType() Is GetType(DateTimePicker)) Then
          Dim dtp As DateTimePicker = CType(ctrl, DateTimePicker)
          dtp.Value = Now()
      End If

      If Recurse Then
          If (ctrl.GetType() Is GetType(Panel)) Then
              Dim pnl As Panel = CType(ctrl, Panel)
              ClearAllControls(pnl, Recurse)
          End If
          If ctrl.GetType() Is GetType(GroupBox) Then
              Dim grbx As GroupBox = CType(ctrl, GroupBox)
              ClearAllControls(grbx, Recurse)
          End If
      End If
  Next
End Sub
Run Code Online (Sandbox Code Playgroud)

@Theraccoonbear:我喜欢你的建议,但当我把声明更改为:

Private Sub ClearAllControls(ByRef controls As ControlCollection, Optional ByVal Recurse As Boolean = True)
Run Code Online (Sandbox Code Playgroud)

然后这行给了我"无法将类型为'ControlCollection'的对象强制转换为'ControlCollection'.":

  ClearAllControls(panMid.Controls)
Run Code Online (Sandbox Code Playgroud)

Mar*_*ett 16

您可以使用TryCast跳过GetType和CType舞蹈:

Dim dtp as DateTimePicker = TryCast(ctrl, DateTimePicker)
If dtp IsNot Nothing then dtp.Value = Now()
Run Code Online (Sandbox Code Playgroud)

这样可以节省大约10行.

关闭Control类的扩展方法应该保持整洁:

<Extension()> _
Public Shared Sub ClearValue(c as Control, recursive as Boolean)
   Dim dtp as DateTimePicker = TryCast(c, DateTimePicker)
   If dtp IsNot Nothing Then dtp.Value = Now()
   ' Blah, Blah, Blah
End Sub
Run Code Online (Sandbox Code Playgroud)

编辑:如果想到忽略NullReferenceExceptions的Evil扩展方法不会让你感到畏缩:

<Extension()> _
Public Shared Sub ClearValue(c as CheckBox)
   If c IsNot Nothing Then c.Checked = False
End Sub

TryCast(ctrl, CheckBox).ClearValue()
Run Code Online (Sandbox Code Playgroud)


Imr*_*ran 8

这是获取Form的All GroupControls的所有控件的代码,您可以在GroupBox控件中执行某些操作

Private Sub GetControls()
    For Each GroupBoxCntrol As Control In Me.Controls
        If TypeOf GroupBoxCntrol Is GroupBox Then
            For Each cntrl As Control In GroupBoxCntrol.Controls
                'do somethin here

            Next
        End If

    Next
End Sub
Run Code Online (Sandbox Code Playgroud)