2

私はこれらを持っています:

  • ラベルが付いたフォーム
  • クラス「ビジネス」
  • クラス「TimerHelper」

MyTimeプロパティを更新するときに、テキストボックスも更新したいのですが

私の「ビジネス」クラスは次のようになります。

public class MyBusinessClass : INotifyPropertyChanged
{
    public void MakeSound(object sender, ElapsedEventArgs e)
    {
        // I change MyTime here
    }   
    public event PropertyChangedEventHandler PropertyChanged;
    private int myTime;
    public int MyTime
    {
        get { return myTime; }
        set
        {
            myTime= value;
            InvokePropertyChanged(new PropertyChangedEventArgs("MyTime"));
        }
    }
    public void InvokePropertyChanged(PropertyChangedEventArgs e)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, e);
    }
}

「TimerHelper」は次のようになります。

public class TimerHelper
{
    private Timer _timer;
    public void Run()
    {
        _timer = new Timer(1000);
        _timer.Enabled = true;
        _timer.Elapsed += new ElapsedEventHandler(MyBusinessClass.MakeSound);
    }
}

フォームで、私はこれを試しました:

myTextBox.DataBindings.Add("Text", new MyBusinessClass(), "MyTime");

しかし、メソッド「InvokePropertyChanged」で例外が発生します ここに画像の説明を入力してください

私はこれを試しました:

Invoke((MethodInvoker)delegate { myTextBox.Text = new MyBusinessClass().MyTime; });

ただし、textBoxは更新されません

4

3 に答える 3

1

あなたの問題は、他のスレッドからの databibding を通じてテキスト ボックスを更新しようとしていると思います。つまり、スレッドプールで Elapsed イベントを呼び出す System.Timers.Timer クラスを使用しています。そのスレッドプールでビジネス クラスを変更しているため、データ バインディングはコントロールの更新に失敗します。Elapsed イベント ハンドラーでスレッド コンテキストを変更し、メイン スレッド (テキスト ボックスが作成された場所) でビジネス モデルを更新する必要があります。

public class TimerHelper
{    
   private Timer _timer;
   public void Run()
   {
      _timer = new Timer(1000);
      _timer.Enabled = true;
      _timer.Elapsed += new ElapsedEventHandler(OnTimerElapsed);
   }
}

void OnTimerElapsed (object sender, ElapsedEventArgs e)
{
    if (myTextBox.InvokeRequired)
    {
        myTextBox.Invoke(MyBusinessClass.MakeSound);
    }
}

}

于 2013-02-12T14:27:48.890 に答える
1

私はそこに答えを見つけました: 一般的な非同期 INotifyPropertyChanged ヘルパー

于 2013-02-12T14:21:44.097 に答える
0

の値をどこに設定しているのかわかりませんがMyTime(私はそれがMakeSound?にあると思います)、MyTimeUIスレッド以外のスレッドでの値を設定しています。System.Timers.TimerUIスレッドでイベントハンドラーを実行しないクラスを使用している可能性があります。デリゲートでUIを使用System.Timers.Timerおよび変更する場合は、タイマーElapsedEventHandlerのプロパティを使用する必要があります。SynchronizingObject詳細については、このMSDNの記事を参照してください:タイマークラスの比較

于 2013-02-12T12:56:44.930 に答える