C# 将WPF控件绑定到由后台线程修改的ObeservableCollection
这是我生命的延续 这是我的mainwindow.csC# 将WPF控件绑定到由后台线程修改的ObeservableCollection,c#,wpf,data-binding,C#,Wpf,Data Binding,这是我生命的延续 这是我的mainwindow.cs public partial class MainWindow : Window { ObservableCollection<string> store; public MainWindow() { SerialPort _serialPort = new SerialPort(SerialCom.findCOMPort(), 115200, Parity.None, 8, StopBit
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);
}
}
公共部分类主窗口:窗口
{
可观察收集存储;
公共主窗口()
{
SerialPort _SerialPort=新的SerialPort(SerialCom.findCOMPort(),115200,奇偶校验.None,8,stoppits.One);
_serialPort.Handshake=Handshake.None;
string[]query=新字符串[3]{“t02”、“t03”、“t04”};
store=新的ObservableCollection{“”,“”};
this.DataContext=this;
Thread Thread=新线程(委托(){进程(存储,查询,_serialPort);});
thread.IsBackground=true;
尝试
{
thread.Start();//捕获串行端口突然关闭异常
}
捕获(例外)
{
thread.Abort();
}
}
公共静态无效进程(ObservableCollection存储、字符串[]查询、SerialPort\u SerialPort)
{
while(true)
{
对于(int i=0;i<3;i++)
{
字符串add=SerialCom.returnData(查询[i],_serialPort);
如果(存储[i]!=添加)
{
存储。插入(i,添加);
}
}
睡眠(300);
}
}
我在我的XAML页面中有一个WPF listview控件。我想将该控件绑定到非UI线程中正在更改的ObservableCollection。似乎美中不足的是,在程序运行时,我必须查询设备的无限循环。此外,由于ObservableCollection实现INotifyPropertyChanged,因此在绑定时如果从绑定系统使用ObservableCollection,则不允许从后台线程对其进行更新。这是因为更新通知(通过InotifyCollection)已更改在进行更改的线程上发生。对ObservableCollection的更改必须发送到UI线程。在4.5中,使用
BindingOperations
类有一个很好的解决方案:
对于早期版本,您需要更新dispatcher线程上的集合,或者将更改通知事件推送到dispatcher线程:
当您将observablecollection绑定到listview时,它属于UI线程。如果您想更新集合,我认为您需要使用Dispatcher.BeginInvoke,一切都应该很好。这正是我所需要的。谢天谢地,我可以使用net 4.5分发!好的,我尝试通过codebehind使列表视图的ItemSource“存储”起来,但它抛出了错误“TargetInvocationException”,InnerException是“NullReferenceException”,这是我的新代码
store=newobserveCollection{“a”、“b”、“c”};BindingOperations.EnableCollectionSynchronization(store,_lock);//允许跨线程绑定thread thread=new thread(delegate(){Process(store,query,_serialPort);});thread.IsBackground=true;listview1.ItemsSource=store;
注释中的代码不太好。最明显要检查的是,您在调用EnableCollectionSynchronization
方法之前设置了\u lock
对象。奇怪的是,我得到了完全相同的exc如果我注释掉BindingOperations调用,则为eption。\u在调用该方法之前,lock是新的。在将ObservableCollection设置为ItemsSource之前,我确保它具有一些值。中列出的问题是否相关?听起来可能相关,特别是需要锁定自己对集合的访问。请尝试添加锁(_lock){…}
在if(store[i]!=add){store.Insert(i,add);}
块周围阻塞。