2

我正在使用 SerialPort 类中的事件侦听器从串行端口读取数据。在我的事件处理程序中,我需要使用来自串行端口的 xml 数据更新窗口中的许多 (30-40) 控件。

我知道我必须使用 myControl.Dispatcher.Invoke() 来更新它,因为它位于不同的线程上,但是有没有办法一起更新许多控件,而不是为每个控件进行单独的 Invoke 调用(即 myCon1.Dispatcher. Invoke()、myCon2.Dispatcher.Invoke() 等)?

我正在寻找类似在容器上调用 Invoke 并单独更新每个子控件的东西,但我似乎无法弄清楚如何实现这一点。

谢谢!

4

1 回答 1

1

您需要做的是使用MVVM

您将控件绑定到 ViewModel 上的公共属性。您的 VM 可以侦听串行端口、解析 xml 数据、更新其公共属性,然后使用INotifyPropertyChanged告诉 UI 更新其绑定。

我建议您使用这条路线,因为您可以批量通知,如果必须,请使用 Dispatcher 在 UI 线程上调用事件。

用户界面:

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

串行窗口视图模型:

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 调用一次。但这种方法很臭。

于 2009-07-08T15:51:46.230 回答