2

SerialPort クラスのイベント リスナーを使用して、シリアル ポートからデータを読み取っています。私のイベント ハンドラーでは、ウィンドウ内の多く (30 ~ 40) のコントロールを、シリアル ポート経由で送信される xml データで更新する必要があります。

別のスレッド上にあるため、myControl.Dispatcher.Invoke() を使用して更新する必要があることはわかっていますが、それぞれに対して個別の Invoke 呼び出しを行うのではなく、多数のコントロールをまとめて更新する方法があります (つまり、myCon1.Dispatcher. Invoke()、myCon2.Dispatcher.Invoke() など)?

コンテナーで Invoke を呼び出し、各子コントロールを個別に更新するようなものを探していますが、これを達成する方法がわかりません。

ありがとう!

4

1 に答える 1

1

あなたがする必要があるのはMVVMを使うことです。

コントロールを ViewModel のパブリック プロパティにバインドします。VM は、シリアル ポートをリッスンし、xml データを解析し、パブリック プロパティを更新してから、 INotifyPropertyChangedを使用して UI にバインドを更新するように指示できます。

通知をバッチ処理し、必要に応じて Dispatcher を使用して UI スレッドでイベントを呼び出すことができるため、このルートをお勧めします。

UI:

<Window ...>
  <Window.DataContext>
    <me:SerialWindowViewModel />
  </Window.DataContext>
  <Grid>
    <TextBlock Text="{Binding LatestXml}/>
  </Grid>
</Window>

SerialWindowViewModel:

public class SerialWindowViewModel : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;

  public string LatestXml {get;set;}

  private SerialWatcher _serialWatcher;

  public SerialWindowViewModel()
  {
    _serialWatcher = new SerialWatcher();
    _serialWatcher.Incoming += IncomingData;
  }

  private void IncomingData(object sender, DataEventArgs args)
  {
    LatestXml = args.Data;
    OnPropertyChanged(new PropertyChangedEventArgs("LatestXml"));
  }

  OnPropertyChanged(PropertyChangedEventArgs args)
  {
    // tired of writing code; make this threadsafe and
    // ensure it fires on the UI thread or that it doesn't matter
    PropertyChanged(this, args);
  }
}

そして、それが受け入れられない場合 (そして、Winforms アプリのように WPF をプログラムしたい場合) は、Dispatcher.CurrentDispatcher を使用して、フォーム上のすべてのコントロールを手動で更新するときに 1 回呼び出すことができます。しかし、その方法は臭いです。

于 2009-07-08T15:51:46.230 に答える