0

这是我之前的问题的延续 这 是我的 mainwindow.cs

   public partial class MainWindow : Window
{
    ObservableCollection<string> store;
    public MainWindow()
    {
     SerialPort _serialPort = new SerialPort(SerialCom.findCOMPort(), 115200, Parity.None, 8, StopBits.One);
     _serialPort.Handshake = Handshake.None;
     string[] query = new string[3] { "t02", "t03", "t04" };
     store = new ObservableCollection<string> { " ", " ", " " };
     this.DataContext = this;
     Thread thread = new Thread(delegate(){Process(store,query,_serialPort);});
     thread.IsBackground = true;
     try
     {
        thread.Start(); //catch sudden serial port closure exception
     }
     catch (Exception)
     {
        thread.Abort();
     }
   }

 public static void Process(ObservableCollection<string> store, string[] query, SerialPort _serialPort)
 {          
     while (true)
     {             
         for (int i = 0; i < 3; i++)
         {
             string add = SerialCom.returnData(query[i], _serialPort);
             if (store[i] != add)
             {
                 store.Insert(i,add);
             }
         }             
         Thread.Sleep(300);

     }
 }

我的 XAML 页面中有一个 WPF listview 控件。我想将该控件绑定到在非 UI 线程中更改的 ObservableCollection。似乎美中不足的是程序运行时我必须查询设备的无限循环。另外,由于 ObservableCollection 实现了 INotifyPropertyChanged,所以当我将集合绑定到控件时,控件应该会自动更新而无需任何其他代码在代码后面或 XAML 中?

4

2 回答 2

1

如果您使用绑定系统中的 ObservableCollection,则不允许从后台线程更新它。这是因为更新通知(通过 INotifyCollectionChanged)发生在进行更改的线程上。必须将 ObservableCollection 的更改分派到 UI 线程。

于 2012-10-31T16:00:56.870 回答
1

4.5 中有一个很好的解决方案,使用BindingOperations该类:http: //10rem.net/blog/2012/01/16/wpf-45-observable-collection-cross-thread-change-notification

对于早期版本,您需要在调度程序线程上更新集合,或者将更改通知事件推送到调度程序线程:http: //julmar.com/blog/mark/ ?p=41

于 2012-10-31T16:09:48.517 回答