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

时间:2008-10-14 00:10:13

标签: 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

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

Private Sub ClearAllControls(ByRef controls As ControlCollection, Optional ByVal Recurse As Boolean = True)

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

  ClearAllControls(panMid.Controls)

10 个答案:

答案 0 :(得分:16)

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

Dim dtp as DateTimePicker = TryCast(ctrl, DateTimePicker)
If dtp IsNot Nothing then dtp.Value = Now()

这样可以节省大约10行。

Control类的extension method应该保持整洁:

<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

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

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

TryCast(ctrl, CheckBox).ClearValue()

答案 1 :(得分: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

答案 2 :(得分:2)

为什么不只有一个例程

ClearAllControls(ByRef container As Control, Optional ByVal Recurse As Boolean = True)

无论您开始调用的层次结构中的级别如何,您都可以递归到它,从表单级别到单个容器。

另外,在TextBox控件上,我使用Textbox.Text = String.Empty

答案 3 :(得分:1)

我做了类似的事情,这基本上就是我去做的事情。我可能建议的唯一更改不是重载方法,只需使传入的类型为Control,您可以为GroupBox,Panel或任何其他提供.Controls属性的容器控件使用相同的版本。除此之外,我认为“清除”控件的定义可能有些模棱两可,因此没有属于Control类的Clear()方法,因此您需要为每种控件类型实现这意味着什么。

答案 4 :(得分:1)

For Each c In CONTAINER.Controls
    If TypeOf c Is TextBox Then
        c.Text = ""
    End If
Next

用您的名字替换(CONTAINER)(可能是FORM,PANEL,GROUPBOX)
请注意您已将控件包含在其中。

答案 5 :(得分:1)

这里适用于所有内部控制 如果您需要清除任何其他控件,请添加。

Private Sub ClearAll()
    Try
        For Each ctrl As Control In Me.Controls
            If ctrl.[GetType]().Name = "Panel" Then
                ClearControls(ctrl)
            End If

            If ctrl.[GetType]().Name = "GroupBox" Then
                ClearControls(ctrl)
            End If
            If ctrl.[GetType]().Name = "ComboBox" Then
                Dim tb As ComboBox = TryCast(ctrl, ComboBox)
                tb.SelectedText = ""
            End If


            If ctrl.[GetType]().Name = "TabControl" Then
                ClearControls(ctrl)
            End If

            If ctrl.[GetType]().Name = "TextBox" Then
                Dim tb As TextBox = TryCast(ctrl, TextBox)
                tb.Clear()
            End If

            If ctrl.[GetType]().Name = "RadioButton" Then
                Dim tb As RadioButton = TryCast(ctrl, RadioButton)
                tb.Checked = False
            End If

            If ctrl.[GetType]().Name = "CheckBox" Then
                Dim tb As CheckBox = TryCast(ctrl, CheckBox)
                tb.Checked = False
            End If

            If ctrl.[GetType]().Name = "ComboBox" Then
                Dim tb As ComboBox = TryCast(ctrl, ComboBox)
                tb.SelectedIndex = 0
            End If

            If ctrl.[GetType]().Name = "RichTextBox" Then
                Dim tb As RichTextBox = TryCast(ctrl, RichTextBox)
                tb.Clear()

            End If
        Next
    Catch ex As Exception
        MessageBox.Show(ex.Message, "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
End Sub


Private Sub ClearControls(ByVal Type As Control)

    Try
        For Each ctrl As Control In Type.Controls

            If ctrl.[GetType]().Name = "TextBox" Then
                Dim tb As TextBox = TryCast(ctrl, TextBox)
                tb.Clear()
            End If

            If ctrl.[GetType]().Name = "Panel" Then
                ClearControls(ctrl)
            End If

            If ctrl.[GetType]().Name = "GroupBox" Then
                ClearControls(ctrl)
            End If

            If ctrl.[GetType]().Name = "TabPage" Then
                ClearControls(ctrl)
            End If

            If ctrl.[GetType]().Name = "ComboBox" Then
                Dim tb As ComboBox = TryCast(ctrl, ComboBox)
                tb.SelectedText = ""
            End If

            If ctrl.[GetType]().Name = "RadioButton" Then
                Dim tb As RadioButton = TryCast(ctrl, RadioButton)
                tb.Checked = False
            End If

            If ctrl.[GetType]().Name = "CheckBox" Then
                Dim tb As CheckBox = TryCast(ctrl, CheckBox)
                tb.Checked = False
            End If

            If ctrl.[GetType]().Name = "RichTextBox" Then
                Dim tb As RichTextBox = TryCast(ctrl, RichTextBox)
                tb.Clear()

            End If
        Next
    Catch ex As Exception
        MessageBox.Show(ex.Message, "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
End Sub

答案 6 :(得分:1)

这直接来自于article讨论的技术,现在控制阵列已经从VB6转到VB.NET。

Private Sub ClearForm(ByVal ctrlParent As Control)
    Dim ctrl As Control
    For Each ctrl In ctrlParent.Controls
        If TypeOf ctrl Is TextBox Then
           ctrl.Text = ""
        End If
        ' If the control has children, 
        ' recursively call this function
        If ctrl.HasChildren Then
            ClearForm(ctrl)
        End If
    Next
End Sub

答案 7 :(得分:1)

Public Sub raz(lst As Control.ControlCollection, Optional recursive As Boolean = True)
    For Each ctrl As Control In lst
        If TypeOf ctrl Is TextBox Then
            CType(ctrl, TextBox).Clear()
        End If

        If TypeOf ctrl Is MaskedTextBox Then
            CType(ctrl, MaskedTextBox).Clear()
        End If

        If TypeOf ctrl Is ComboBox Then
            CType(ctrl, ComboBox).SelectedIndex = -1
        End If

        If TypeOf ctrl Is DateTimePicker Then
            Dim dtp As DateTimePicker = CType(ctrl, DateTimePicker)
            dtp.CustomFormat = " "
        End If

        If TypeOf ctrl Is CheckedListBox Then
            Dim clbox As CheckedListBox = CType(ctrl, CheckedListBox)
            For i As Integer = 0 To clbox.Items.Count - 1
                clbox.SetItemChecked(i, False)
            Next
        End If

        If TypeOf ctrl Is RadioButton Then
            CType(ctrl, RadioButton).Checked = False

        End If

        If recursive Then
            If TypeOf ctrl Is GroupBox Then
                raz(CType(ctrl, GroupBox).Controls)
            End If
        End If
    Next
End Sub

答案 8 :(得分:0)

我向您展示我的ControlIterator班级

来源:http://pastebin.com/dubt4nPG

一些用法示例:

 ControlIterator.Disable(CheckBox1)

 ControlIterator.Enable({CheckBox1, CheckBox2})

 ControlIterator.Check(Of CheckBox)(Me)

 ControlIterator.Uncheck(Of CheckBox)(Me.GroupBox1)

 ControlIterator.Hide(Of CheckBox)("1")

 ControlIterator.PerformAction(Of CheckBox)(Sub(ctrl As CheckBox) ctrl.Visible = True)

 ControlIterator.AsyncPerformAction(RichTextBox1,
                                    Sub(rb As RichTextBox)
                                        For n As Integer = 0 To 9
                                            rb.AppendText(CStr(n))
                                        Next
                                    End Sub)

 ControlIterator.PerformAction(Me.Controls, Sub(c As Control)
                                                c.BackColor = Color.Green
                                            End Sub)

答案 9 :(得分:0)

这可能对未来的发展有所帮助...

GetAllButtons(Me)

Public Sub GetAllButtons(ByRef forms As Object)
    Dim list As New List(Of Button)
    Dim iIndx As Integer
    For Each c In forms.Controls
        For iIndx = 0 To forms.Controls.Count - 1
            If (TypeOf forms.Controls(iIndx) Is Button) Then
                list.Add(forms.Controls(iIndx))
            End If
            If (TypeOf forms.controls(iIndx) Is Panel) Then
                For Each cntrl As Control In forms.controls(iIndx).Controls
                    If TypeOf cntrl Is Button Then
                        list.Add(cntrl)
                    End If
                Next
            End If
        Next
    Next

Button(list.ToArray)

End Sub

Public Sub Button(btn() As Button)
    For Each bt In btn
       Do Something with Buttons
    next
End Sub