2017-09-21 7 views
0

私はSystem.Windows.Forms.Timerを追加したUserControlを持っています。デザインタイムにタイマーが追加されました。既定では、EnabledプロパティはFalseです。インターバルを400msに変更しました。UserControl内のSystem.Windows.Forms.TimerがTickイベントを発生させないのはなぜですか?

UserControlはプログラムによってフォームに追加されます。タイマーは設計時に無効になっています。実行時に、タイマーはUserControlのProperty Setterによって有効になります。

ユーザーコントロールクラスは、このです:

Public Class LuminaireSign 
    Public Property MyLuminaire As Luminaire 
Private _state As LuminaireSignState 
Public Property State As LuminaireSignState 
    Get 
     Return _state 
    End Get 
    Set(value As LuminaireSignState) 
     If value <> _state Then 
      _state = value 

      If _state = LuminaireSignState.OK Then 
       Timer1.Enabled = False 
       Me.Image = luminSign_Green 
      Else 
       Timer1.Enabled = True 
      End If 

     End If 
    End Set 
End Property 

Public Sub New(ByRef associatedLumin As Luminaire) 

    ' This call is required by the designer. 
    InitializeComponent() 

    ' Add any initialization after the InitializeComponent() call. 

    MyLuminaire = associatedLumin 
    AddHandler MyLuminaire.PropertyChanged, New PropertyChangedEventHandler(AddressOf propChanged) 
End Sub 

Private Sub propChanged(sender As Object, e As PropertyChangedEventArgs) 
    If e.PropertyName = "Status" Then 
     If MyLuminaire.Status.BatteryEmpty Then 
      State = LuminaireSignState.Fault 
     Else 
      State = LuminaireSignState.OK 
     End If 
    End If 
End Sub 

奇妙なことは、タイマーが有効になりますにもかかわらず、タイマーのTickイベントがクビにしないということです。

ご覧のとおり、私はStatePropertyをMyLuminaire.PropertyChangedを処理するPropertyChangedEventHandlerであるサブpropChanged()で設定します。 MyLuminaireはUserControlのコンストラクタで参照渡しされます。実際のLuminaireオブジェクトのStatusは、UI以外のスレッドで設定されます。

propChangedイベントがUI以外のスレッドプロパティの変更によって起動されるため、チェックできませんか? 誰かが私に何が起こっているか説明できますか?

PS。設計時にタイマーを有効にすると、Tickイベントは、タイマーが一度無効になるまでうまく起動します。また、タイマーが有効になっても、Tickイベントは発生しません。

+0

タイマーはどのように初期化されていますか?どのように宣言されていますか? LuminaireSignStateプロパティを設定するときに、タイマーを時間切れにしますか? – sapi

+0

私はちょうどテストし、期待通りに、そのシナリオでは 'Timer'の' Tick'イベントが発生しました。あなたのシステムで何かが壊れているか、何か他のものがあります。ほとんどの場合、 'Enabled'プロパティは、それが誤ったロジックによるものだと思うときは設定されていません。つまり、 'Enabled'プロパティを設定した行にブレークポイントを配置して、期待通りに実行されることを確認してください。私は彼らがそうでないと賭けるでしょう。 – jmcilhinney

+0

@sapi質問を更新しました。はい、LuminaireSignStateプロパティを設定するときに、タイマーを点滅させたいと思います。 –

答えて

0

問題は、backgroundChangedがバックグラウンドスレッドで発生しているため、タイマーがTickイベントを発生できないことでした。したがって、スレッドセーフな方法でタイマーを有効にする必要があります。

解決策は、timer1.Enabledを直接設定するのではなく、代わりにtimer1を設定するサブクラス(SetStateOkを参照)を作成し、InvokeRequired = trueになるたびにこのサブクラスの代理人を呼び出します。

だから、Stateプロパティを変更し、SetStateOkサブと問題が解決呼び出しを追加:

Public Property State As LuminaireSignState 
Get 
    Return _state 
End Get 
Set(value As LuminaireSignState) 
    If value <> _state Then 
     _state = value 

     If _state = LuminaireSignState.OK Then 
      SetStateOk(true) 
      'Timer1.Enabled = False 
      'Me.Image = luminSign_Green 
     Else 
      SetStateOk(false) 
      'Timer1.Enabled = True 
     End If 

    End If 
End Set 
End Property 


Private Delegate Sub SetStateOKDelegate(ByVal stateIsOk As Boolean) 

Private Sub SetStateOK(ByVal stateIsOk As Boolean) 
    If Me.InvokeRequired Then 
     Me.Invoke(New SetStateOKDelegate(AddressOf SetStateOK), New Object() {stateIsOk}) 
    Else 
     If stateIsOk Then 
      timer1.Enabled = False 
      Image = luminSign_Green 
     Else 
      timer1.Enabled = True 
     End If 
    End If 
End Sub 

この方法でタイマーが有効になりますと、Tickイベントがのは、定期的に解雇!

関連する問題