2016-09-21 4 views
0

コントロールを見つけて有効にする方法を試みた結果、すべてのエラーメッセージが消えてしまいました。ボタンが無効から有効に切り替わりません

プロパティペインでメインウィンドウのボタンを無効にしました。

このコードは1秒おきにコードが実行されていることを示す別のmsgboxを与えてくれるので、うんざりですがうまくいきますが、正常に実行されます。しかし、ボタンを有効にしていません。私はC#を初めて使っているので、アラビア語のように見えます。 VBでそれだけで次のようになります。ここでは

btnMyButton.Enabled = True 

は私のコードは遅れている:

解決しよう
public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     System.Timers.Timer myTimer = new System.Timers.Timer(); 
     myTimer.Elapsed += new ElapsedEventHandler(DisplayTimeEvent); 
     myTimer.Interval = 1000; // 1000 ms is one second 
     myTimer.Start(); 
    } 

    public void DisplayTimeEvent(object source, ElapsedEventArgs e) 
    { 
     DateTime now = DateTime.Now; 
     DateTime today3am = now.Date.AddHours(3); 

     if (DateTime.Today == today3am.Date && now >= today3am) 
     { 
      MessageBox.Show("Code is being triggered"); 
      btnMyButton.IsEnabled = true; 
     } 
    } 
} 

:レスポンスはこれを示唆した:(ITが働いて)

public void DisplayTimeEvent(object source, ElapsedEventArgs e) 
{ 
    DateTime now = DateTime.Now; 
    DateTime today3am = now.Date.AddHours(3); 

    if (DateTime.Today == today3am.Date && now >= today3am) 
    { 
     MessageBox.Show("Button Should Enable"); 
     this.Dispatcher.Invoke(() => { 
      btnMyButton.IsEnabled = true; 
     }); 
    } 
} 

答えて

2

でUIスレッド上にないようディスパッチャスレッド上でプロパティを設定する必要があると思いますIsEnabledプロパティを設定しようとすると、(予想通り)私が得る、例外をあなたが提供したコードを貼り付けて、それを実行します。

別のスレッドがそれを所有しているので、呼び出し元のスレッドがこのオブジェクトにアクセスすることはできません。

これは標準の「間違ったスレッド」例外です。デバッガで実行していないため、例外が表示されません(明らかに)。 Timerスレッドは例外をキャッチし、例外を無視します。この問題を解決する

一つの方法は、他の人が示唆したように、Dispatcher.Invoke()を使用することです。問題は根本的にSystem.Timers.Timerクラスの使用によって引き起こされているので、

public void DisplayTimeEvent(object source, ElapsedEventArgs e) 
{ 
    DateTime now = DateTime.Now; 
    DateTime today3am = now.Date.AddHours(3); 

    if (DateTime.Today == today3am.Date && now >= today3am) 
    { 
     Dispatcher.Invoke(() => btnMyButton.IsEnabled = true); 
    } 
} 

しかし、それだけのために、より理にかなっています正しいタイマークラスを使用してください。System.Windows.Threading.DispatcherTimer

public MainWindow() 
{ 
    InitializeComponent(); 
    var myTimer = new DispatcherTimer(); 
    myTimer.Tick += DisplayTimeEvent; 
    myTimer.Interval = TimeSpan.FromSeconds(1); 
    myTimer.Start(); 
} 

public void DisplayTimeEvent(object source, EventArgs e) 
{ 
    DateTime now = DateTime.Now; 
    DateTime today3am = now.Date.AddHours(3); 

    if (DateTime.Today == today3am.Date && now >= today3am) 
    { 
     btnMyButton.IsEnabled = true; 
    } 
} 
+0

情報ありがとうございます。私が最初にタイマーを追加しようとしたとき、私は両方のオプションをクイックフィックスとして見た。最初に 'System.Windows.Threading.DispatcherTimer'を実行してから、timerクラスのusingステートメントを追加しました。私は完全なnoob笑です。私はあなたにそれを私に説明する時間を割いていただきありがとうございます。私はこのトピックについてもっと詳しく読むことになります。ありがとう。 – DavidG

1

Dispatcherを使用してみてください。 GUIがコードからのコントロールの変更をブロックすることがあります。 Dispatcherは、複数のスレッドから要素へのアクセスを座標:

this.Dispatcher.Invoke(() => { 
    btnMyButton.IsEnabled = true; 
}); 
+0

ありがとうございます!それがそれでした。今、私は様々なスレッドについて学ばなければならないでしょう。 – DavidG

0

私はあなたが私をコピーするときに、イベントハンドラ

関連する問題