从后台Worker更新ObservableCollection
我有一个DatGrid,它绑定到var Result_Full = new ObservableCollection()
。 这是一个包含多个字符串和双变量的简单类。 没什么难的。
我所做的是,我读了一个Excel文件(使用Telerik RadSpreadProcessing),它将行解析到我的类中。 我在一个线程上执行此操作,以便不阻止UI。 我遇到了一些问题:
1)我不能在读取excel文件的长进程中使用ref
关键字(因为Result_Full是绑定到DataGrid的公共属性),但是我必须创建临时ObservableCollection()
,其中放置值。 完成该过程后,我运行以下脚本来复制值:
foreach (var item in tmpFull) { InvokeOnUIThread(() => { Result_Full.Add(item); }); }
我想做的是,能够实时查看(如果可能)如何将项目添加到我的DataGrid中的集合中。
当我使用.Net 4.5时,我尝试按照其他post的建议实现BindingOperations.EnableCollectionSynchronization
,但我无法弄清楚如何将我的UI模型集合Result_Full绑定到进程中临时使用的。
2)即使使用当前设置,当我(在我的UI下)移动到包含DataGrid的我的Tab(我的DataGrid在不同的TabPage上)时,我尝试使用上面提到的代码将新项添加到集合中,它返回错误说: 调用线程无法访问此对象,因为另一个线程拥有它。 ,这是相当奇怪的,因为InvokeOnUIThread只是Dispatcher.Invoke()
,它应该是线程安全的?
任何帮助将受到高度赞赏。
编辑:显示更多代码:
这是我从BackgroundWorker调用的过程:
public void ProcessFile() { var tmpError = new ObservableCollection(); var tmpFull = new ObservableCollection(); var _reader = new IP_ExcelReader(sExcelPath, ref tmpError, ref tmpFull); string sResult = _reader.ReadExcelFile(); if (sResult != string.Empty) { System.Windows.MessageBox.Show("Error processing selected Excel File!" + Environment.NewLine + Environment.NewLine + "Error message:" + Environment.NewLine + sResult); } foreach (var item in tmpError)//populates error list { IP_InvokeOnUIThread(() => { Result_Error.Add(item); }); } foreach (var item in tmpFull)//populates full list { IP_InvokeOnUIThread(() => { Result_Full.Add(item); }); } OnPropertyChanged("Result_Full"); //OnPropertyChanged("Result_Error"); iSelectedTabIndex = 1; }
在这里你可以看到,我必须创建临时集合tmpError,tmpFull ,我收集我的数据。 在进程结束时,我手动将值复制到绑定到DataGrid的主集合中。 我想改变这一点,这意味着在过程中将值复制到主集合(而不是临时集合),以便用户可以实时查看如何将值添加到集合中。
PS2:由于我的原因,我的InvokeOnUIThread
调用中存在一个问题。 一旦我从App.Current.Dispatcher.Invoke(action);
改变了App.Current.Dispatcher.Invoke(action);
到App.Current.Dispatcher.BeginInvoke(action);
错误与..different线程拥有它停止。
- 您可以使用BackgroundWorker而不是线程来报告进度。 这是一个简单的教程
- 我相信简单地调用Dispatcher将使用上下文的线程,在您的情况下不是UI线程。 请尝试使用
Application.Current.Dispatcher
简而言之,我相信你应该做到以下几点:
上述就是C#学习教程:从后台Worker更新ObservableCollection分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
- 在UI线程中创建公共ObservableCollection并将其绑定到DataGrid
- 创建后台工作者。 将报告设置为true。 订阅ReportProgress和DoWork事件。
- 运行worker async
- 在DoWork处理程序中创建一个列表并读取一些值。 当你达到一定数量时,让我们说一百个,调用
(sender as BackgroundWorker).ReportProgress
方法,传入事件args这个你已经填充的集合。 - 在报告进度处理程序中,从您通过事件args传递的列表中填充ObservableCollection。
- 重复步骤4 – 5直到完成所有操作
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/955971.html