我有一个WinForm与NumericUpDowns(NUD),正常的文本框和MaskedTextBoxes。应该清除文本框,我尝试了以下代码:
For Each txtBox As TextBoxBase In Controls.OfType(Of TextBoxBase)
txtBox.Clear()
Next
这会清除文本框,但也会清除NUD的文本,这是不应该的。
使用CtrlClick查找NumericUpDown
的父代,据我所知,它甚至没有继承自TextBoxBase
。
不过,它们还是被清除了,所以我想在清除txtBox
之前添加一个条件来检查它是否不是NUD。我试着检查:
If txtBox.GetType() <> GetType(NumericUpDown) Then
txtBox.Clear()
End If
以及以下条件:
txtBox.GetType() IsNot GetType(NumericUpDown)
TypeOf txtBox IsNot NumericUpDown
所有这些都是UpDownBase
而不是NUD。没有什么比得上False
。
但是在调试时,我使用
Debug.Print(txtBox.GetType().ToString())
这是System.Windows.Forms.UpDownBase+UpDownEdit
。没有一个类型叫做UpDownEdit
,我也不知道我应该如何理解+
。
什么条件做工作,然后只是比较类型名称字符串:
txtBox.GetType().ToString().Contains(GetType(UpDownBase).ToString())
但这不是一个好方法,所以:
考虑到上述挑战,检查txtBox
中的对象是否真的是NUD的“正确”方法是什么?
这个问题出现的方法是下面的递归子:
Public Sub ClearInputControls(elements As ControlCollection)
' Recurse into containers.
For Each pnl As Panel In elements.OfType(Of Panel)
ClearInputControls(pnl.Controls)
Next
For Each cntr As ContainerControl elements.OfType(Of ContainerControl)
ClearInputControls(cntr.Controls)
Next
' Reset controls.
For Each txtBox As TextBoxBase In elements.OfType(Of TextBoxBase)
txtBox.Clear()
Next
For Each count As NumericUpDown In elements.OfType(Of NumericUpDown)
count.Value = count.Minimum
Next
For Each cbox As ListControl In elements.OfType(Of ListControl)
cbox.SelectedIndex = -1
Next
End Sub
如果NUD中的值从其默认值更改,则不会清除它们。
但这似乎是值的任何 * 更改 * 都会提示NUD再次显示该数字,因此每个循环的第二个仅在值与最小值(默认值)不同时更新NUD。
当它在清除循环之后出现时,由于通过更改进行更新,值再次显示。
2条答案
按热度按时间wz1wpwve1#
我现在找到了问题所在--评论是正确的:它不在我最初在问题中提供的一个循环中。
这个循环在一个sub中被调用,该sub递归到所有控件
OfType ContainerControl
中,以清除SplitContainers等中的所有文本框:问题是,NumericUpDown(NUD)是
OfType ContainerControl
(CC),它们包含的是OfType TextBoxBase
。因此,for each循环“打开”一个NUD作为CC。此CC“保存”一个TextBoxBase,然后由for循环清除。
当使用Ctrl+Click查看NUD的定义时,它只把我带到了UpDownBase,而不是进一步向下,但是现在查看NUD类文档,它确实从CC继承。
因此,解决方案是将for each循环改为仅在SplitContainers上执行:
TextBoxBases上的for循环可以保持原样。
或者,为了继续使用CC,可以在递归之前检查
OfType NumericUpDown
:qni6mghb2#
不需要执行单独的循环来遍历给定集合中的不同类型的控件。在一个过程中,循环执行递归部分,而其他循环处理目标控件。分开解决问题。
首先,创建一个recursive方法,获取给定父控件的所有子控件。
**注:**选项Strict、Explicit和Infer为
On
。第二个是调用方方法,它遍历子控件,处理目标类型,并跳过其余部分。
更好的是,您可以扩展类型
Control
,并将递归例程作为extension method。在vb.net
中,您需要在Module中拥有扩展方法,并使用<Extension>
属性装饰它们。现在,项目中所有类型为
Control
的对象都具有此方法。此外,如果需要的话,您可以有一个通用的扩展方法来获取特定类型的控件。
就这么叫吧。