Vb.net 如何列出其他窗体的所有计时器
我想做一个程序,停止任何给定形式的所有计时器。尽管在建造时它说 “组件”不是“System.Windows.Forms.Form”的成员 代码如下:Vb.net 如何列出其他窗体的所有计时器,vb.net,winforms,timer,components,Vb.net,Winforms,Timer,Components,我想做一个程序,停止任何给定形式的所有计时器。尽管在建造时它说 “组件”不是“System.Windows.Forms.Form”的成员 代码如下: Public Sub _Timers_Stop(frm As Form) For Each itm As Object In frm.components.components If TypeOf (itm) Is Timer Then itm.stop()
Public Sub _Timers_Stop(frm As Form)
For Each itm As Object In frm.components.components
If TypeOf (itm) Is Timer Then
itm.stop()
End If
Next
End Sub
您可以为此使用反射:
Public Sub StopTimers(Form As Form)
For Each Item In Form.GetType.GetFields(Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public).Where(Function(x) TypeOf x.GetValue(Form) Is Timer)
Dim Timer As Timer
Timer = Item.GetValue(Form)
Timer.Stop()
Next
End Sub
正如我在注释中更正的那样,
控件
集合不包含组件,它只包含控件。对非可视组件(如计时器)的引用保存在专用容器
字段中,通常称为组件
。该容器
字段根本不是基本表单
类的一部分。表单设计器在每个需要它的表单上分别声明和实现它。因为它不是基类的成员,所以在任何给定的表单上都无法轻松访问它。即使它是基类的成员,可访问性仍然是一个问题,因为它通常声明为私有字段
这样做的安全方法是创建一个接口,它保留了正确的类型检查:
Public Interface IFormWithComponents
ReadOnly Property Components As ComponentCollection
End Interface
然后,您可以在每种表单上实施(如适用):
Public Class MyForm
Implements IFormWithComponents
Public ReadOnly Property Components As ComponentCollection Implements IFormWithComponents.Components
Get
Return components.Components
End Get
End Property
End Class
然后,计时器停止方法可以将该接口作为其参数:
Public Sub _Timers_Stop(frm As IFormWithComponents)
For Each t As Timer In frm.Components.Cast(Of Component).OfType(Of Timer)
t.stop()
Next
End Sub
但是,如果您并不真正关心类型检查,也不介意性能稍有下降,您也可以使用反射来查找表单对象中的私有字段并提取其值:
Public Sub _Timers_Stop(frm As Form)
Dim timers As IEnumerable(Of Timer) = frm.
GetType().
GetFields(BindingFlags.FlattenHierarchy Or BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.Public).
Select(Function(fieldInfo) fieldInfo.GetValue(frm)).
OfType(Of Container)().
SelectMany(Function(container) container.Components.OfType(Of Timer)())
For Each t As Timer In timers
t.Stop()
Next
End Sub
这是因为
Form
没有components
属性(就像错误所说的那样)。只能调用存在的属性。而不是frm.components.components
,请尝试frm.Controls
@StevenDoggart:不幸的是组件不是Controls
集合的一部分。@lamiabed:components
属性/字段仅由Visual Studio designer创建,您需要将frm
强制转换到您的特定表单中才能使用它(除非标记为Private
或Protected
)。只需将计时器列表或数组作为该表单的公共属性,这将是直接访问它们的最简单方法。表单的frm.Controls集合可能包含的不仅仅是几个计时器谢谢各位:)我会尝试