wpf:通过调度程序更新多个控件

时间:2009-07-08 15:45:48

标签: wpf invoke dispatcher

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

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

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

谢谢!

1 个答案:

答案 0 :(得分: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);
  }
}

并且,如果您不接受(并且您希望将WPF编程为winforms应用程序),则可以在手动更新表单上的所有控件时使用Dispatcher.CurrentDispatcher调用一次。但那种方法很糟糕。