2017-07-06 50 views
1

我想製作一個程序來停止任何給定表單的所有計時器。雖然當它建設說​​如何列出另一個表單的所有計時器

「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() 
      End If 
     Next 
End Sub 
+0

這是因爲Form沒有'components'屬性(就像錯誤說的那樣)。您只能調用存在的屬性。而不是'frm.components.components',請嘗試'frm.Controls'。 –

+0

@StevenDoggart:不幸的是,組件不是'Controls'集合的一部分。 –

+0

@LamineAbed:''component'屬性/字段僅由Visual Studio設計器創建,並且您需要將'frm'轉換爲您的特定形式之一才能使用它(除非它被標記爲'私人「或」受保護「)。 –

回答

1

您可以使用反射此:

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 
1

正如我在評論中已得到糾正,在Controls集合不包含組件 - 它只包含控件。對非定期組件(例如定時器)的引用保存在專用的Container字段中,通常稱爲components。那Container字段根本不是基類Form類的一部分。它由表單設計者分別在需要它的每個表單上進行聲明和實現。由於它不是基類的成員,所以沒有簡單的方法在任何給定的表單上訪問它。即使它是基類的成員,由於它通常被聲明爲私有字段,所以可訪問性仍然是一個問題。

的安全的方式來做到這一點,它保留適當的類型檢查,是創建一個接口:

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 

^h但是,如果您不關心類型檢查,並且您不介意性能略有下降,則可以使用反射來查找表單對象中的專用字段並提取其值:

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 
相關問題