在我們的應用程序中,我們有一個TreeView綁定到一個ObservableCollection,我們經常在後臺線程中更新,從我們的存儲中請求數據。它完美的工作!
哎呦。我被誤通知=))
對,我們實際上是繼承ObservableCollection<T>
並覆蓋OnCollectionChanged
方法以避免UI crossthreading異常。我們使用this solution:
public class MTObservableCollection<T> : ObservableCollection<T>
{
public override event NotifyCollectionChangedEventHandler CollectionChanged;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
var eh = CollectionChanged;
if (eh != null)
{
Dispatcher dispatcher = (from NotifyCollectionChangedEventHandler nh in eh.GetInvocationList()
let dpo = nh.Target as DispatcherObject
where dpo != null
select dpo.Dispatcher).FirstOrDefault();
if (dispatcher != null && dispatcher.CheckAccess() == false)
{
dispatcher.Invoke(DispatcherPriority.DataBind, (Action)(() => OnCollectionChanged(e)));
}
else
{
foreach (NotifyCollectionChangedEventHandler nh in eh.GetInvocationList())
nh.Invoke(this, e);
}
}
}
}
如果沒有超越你會得到這樣的
System.NotSupportedException異常:這種類型 的的CollectionView不從它的 SourceCollection不 支持更改線程 與Dispatcher線程不同。
現在我們唯一的問題是所選擇的項目位置,在某些情況下,如果當前選擇的項目是從集合中刪除TreeView中移動選擇到下一個項目(這會導致其他一些不必要的UI操作我們應用程序)。但這是一個小問題。
一個可行的替代方案http://stackoverflow.com/questions/12881489/asynchronously-adding-to-observablecollection-or-an-alternative – Narkha 2013-09-25 15:53:33
或者你可以嘗試這是完全線程安全的,從任何線程工作,並且可以由多個UI線程的數據綁定:http://www.codeproject.com/Articles/64936/Multithreaded-ObservableImmutableCollection – Anthony 2014-04-15 00:59:06
好收集的工作! – 2014-06-26 17:31:33