2012-10-31 58 views
0

該修改的ObeservableCollection是我previous question 這裏是我的mainwindow.cs綁定WPF控件由一個後臺線程

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?

+1

當您將observablecollection綁定到listview時,它由UI線程所擁有。如果你想更新集合,我認爲你需要使用Dispatcher.BeginInvoke,一切都會好的。 – MrEdge

回答

1

有使用BindingOperations類4.5一個很好的解決方案: http://10rem.net/blog/2012/01/16/wpf-45-observable-collection-cross-thread-change-notification

對於早期版本,你要麼需要更新調度線程上收集,或按變更通知事件的調度線程: http://julmar.com/blog/mark/?p=41

+0

正是我需要的。謝天謝地,我可以用net 4.5發佈! – bakedpatato

+0

好吧,我試圖通過代碼隱藏的方式讓我的列表視圖的ItemSource「store」,但它拋出「TargetInvocationException」,InnerException是「NullReferenceException」這裏是我的新代碼'store = new ObservableCollection {「a」,「b」,「c」} ; BindingOperations.EnableCollectionSynchronization(store,_lock); //允許跨線程綁定 Thread thread = new Thread(delegate(){Process(store,query,_serialPort);}); thread.IsBackground = true; listview1.ItemsSource = store;' – bakedpatato

+0

該代碼在評論中顯得不太好。最明顯的要檢查的是你在調用EnableCollectionSynchronization方法之前設置了_lock對象。 –

1

如果您使用綁定系統中的ObservableCollection,則不允許從後臺線程更新它。這是因爲更新通知(通過INotifyCollectionChanged)發生在進行更改的線程上。 ObservableCollection的更改必須分配給UI線程。