我有一個DatGrid,它綁定到var Result_Full = new ObservableCollection<IP_DataRow>()
。這是一個簡單的類,包含幾個字符串&雙變量。沒什麼困難。從後臺更新ObservableCollection工作人員
我所做的是,我讀了一個Excel文件(使用Telerik RadSpreadProcessing),它將行分析到我的類中。我在一個線程上這樣做,以便UI不被阻塞。我遇到了一些問題,但:
1)我不能使用ref
關鍵字在一個很長的過程中讀取excel文件(因爲Result_Full是綁定到DataGrid的公共屬性),但我必須創建臨時ObservableCollection<IP_DataRow>()
,其中值被放置。一旦這個過程完成後我運行下面的腳本複製值:
foreach (var item in tmpFull)
{
InvokeOnUIThread(() =>
{
Result_Full.Add(item);
});
}
我想什麼做的,是能夠在實時(如果可能的話)的項目是如何被加入到看我的DataGrid中的集合。
由於我使用.NET 4.5我試圖執行BindingOperations.EnableCollectionSynchronization
這已在一些其他職位的建議,但我無法弄清楚如何我的UI鮑爾德收集Result_Full綁定到臨時使用的一個過程。
2)即使使用當前設置,當(在我的UI下)我移動到包含DataGrid(我的DataGrid在不同的TabPage上)的Tab中,並且嘗試使用上面提到的將新項添加到集合中代碼,它返回一個錯誤說:調用線程不能訪問此對象,因爲不同的線程擁有它。,這很奇怪,因爲InvokeOnUIThread沒有別的,只有Dispatcher.Invoke()
,應該是線程安全的?
任何幫助將不勝感激。
編輯:顯示更多的代碼:
這是我從BackgroundWorker的調用過程:
public void ProcessFile()
{
var tmpError = new ObservableCollection<IP_DataRow>();
var tmpFull = new ObservableCollection<IP_DataRow>();
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的主集合中。我想對此進行更改,這意味着在過程中將值複製到主集合(不是臨時集合),以便用戶可以實時查看向集合中添加值的方式。
P.S.2: 因爲我不知道的原因,其中一個問題在我的InvokeOnUIThread
調用中。一旦我從App.Current.Dispatcher.Invoke(action);
更改爲App.Current.Dispatcher.BeginInvoke(action);
錯誤..不同線程擁有它停止。
哪個線程擁有'item'和'tmpFull'? – Pieter21
*哪個調度程序?* Dispatcher.Current保存在TLS中,因此每個線程都有自己的調度程序。您需要訪問UI線程的調度程序。 – Will
我正在使用** App.Current.Dispatcher.Invoke(action); **。我雖然這是UI調度員?那麼我如何訪問它? –