VB.NET - 遍历容器对象中的控件 [英] VB.NET - Iterating through controls in a container object
问题描述
我有一个带有清除"按钮的表单.
I have a form with a "Clear" button.
当用户单击清除"时,我想清除表单上所有可见元素的值.对于日期控件,我想将它们重置为当前日期.
When the user clicks "Clear", I want to clear the value of all the visible elements on the form. In the case of date controls, I want to reset them to the current date.
我的所有控件都包含在一个面板中.
All of my controls are contained on a Panel.
现在,我正在使用以下代码执行此操作.有没有比手动检查每种控件类型更简单的方法?这种方法似乎过于笨拙.
Right now, I'm doing this with the below code. Is there an easier way than manually checking for each control type? This method seems excessively unwieldy.
更糟糕的是,为了递归地清除子容器内的控件(即面板中的组框),我必须使用重载的GroupBox"版本重复整个怪物.
To make matters worse, in order to recursively clear controls inside sub-containers (i.e., a group box within the panel) I have to repeat the whole monster with an overloaded "GroupBox" version.
感谢您的建议,大大简化了以下代码.
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:我喜欢你的建议,但是当我把声明改成这样时:
@Theraccoonbear: I like your suggestion, but when I change the declaration to this:
Private Sub ClearAllControls(ByRef controls As ControlCollection, Optional ByVal Recurse As Boolean = True)
然后这一行给了我无法将'ControlCollection'类型的对象转换为'ControlCollection'类型.":
Then this line gives me "Unable to cast object of type 'ControlCollection' to type 'ControlCollection'.":
ClearAllControls(panMid.Controls)
推荐答案
您可以使用 TryCast:
Dim dtp as DateTimePicker = TryCast(ctrl, DateTimePicker)
If dtp IsNot Nothing then dtp.Value = Now()
这将为您节省大约 10 行代码.
That'll save you about 10 lines.
Control 类中的扩展方法应该让它保持整洁:
An extension method off the Control class should keep it pretty tidy:
<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 扩展方法不会让您感到畏缩:
If the thought of Evil extension methods that ignore NullReferenceExceptions don't make you cringe:
<Extension()> _
Public Shared Sub ClearValue(c as CheckBox)
If c IsNot Nothing Then c.Checked = False
End Sub
TryCast(ctrl, CheckBox).ClearValue()
这篇关于VB.NET - 遍历容器对象中的控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!