Question

Je lis des données à partir d'un port série en utilisant un écouteur d'événement de la classe SerialPort. Dans mon gestionnaire d'événements, je dois mettre à jour plusieurs (30-40) les contrôles dans ma fenêtre avec des données XML à venir sur le port série.

Je sais que je dois utiliser myControl.Dispatcher.Invoke () pour le mettre à jour car il est sur un thread différent, mais est-il un moyen de mettre à jour beaucoup de contrôles ensemble, plutôt que de faire un appel Invoke pour chaque (c.-à-myCon1 .Dispatcher.Invoke (), myCon2.Dispatcher.Invoke (), etc.)?

Je cherche quelque chose comme appeler Invoke sur le récipient, et mettre à jour chaque contrôle enfant individuellement, mais je ne peux pas sembler travailler sur la façon d'y parvenir.

Merci!

Était-ce utile?

La solution

Ce que vous devez faire est d'utiliser MVVM .

Vous liez vos contrôles aux propriétés publiques sur un ViewModel. Votre machine virtuelle peut écouter le port série, analyser les données XML, mettre à jour ses propriétés publiques et puis utilisez INotifyPropertyChanged pour dire l'interface utilisateur de mettre à jour ses fixations.

Je vous suggère de cette route que vous pouvez les notifications par lots et, si vous devez, utilisez le Dispatcher pour invoquer l'événement sur le thread d'interface utilisateur.

IU:

<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);
  }
}

Et, si ce n'est pas acceptable pour vous (et que vous voulez programmer WPF comme son une application WinForms) vous pouvez utiliser Dispatcher.CurrentDispatcher pour Invoquer une fois pendant que vous mettez à jour manuellement tous les contrôles sur votre formulaire. Mais cette méthode pue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top