我有一個TreeView控件,需要用大量的3層對象列表來填充,這些列表需要花費大量的時間來構建。我正在後臺線程上加載數據,然後將GUI更新發送到GUI線程,但是有太多更新,因爲每次添加一個節點時,我都必須發送該節點,然後我必須調用ExpandSubTree()方法,然後展開所有子節點,然後引發更多展開事件,並且它崩潰。有沒有辦法在後臺線程上建立TreeView控件?
有沒有一種方法可以構建控件,並且它在後臺線程上以某種方式打開/關閉狀態,然後只有在完成時才整理它?
我有一個TreeView控件,需要用大量的3層對象列表來填充,這些列表需要花費大量的時間來構建。我正在後臺線程上加載數據,然後將GUI更新發送到GUI線程,但是有太多更新,因爲每次添加一個節點時,我都必須發送該節點,然後我必須調用ExpandSubTree()方法,然後展開所有子節點,然後引發更多展開事件,並且它崩潰。有沒有辦法在後臺線程上建立TreeView控件?
有沒有一種方法可以構建控件,並且它在後臺線程上以某種方式打開/關閉狀態,然後只有在完成時才整理它?
每個樹視圖項都有一個屬性Children,如果您將每個Tree View項的子項綁定到ObservableCollection,則可以從BackGroundWorker或其他線程向其添加項目。如果使用後續集合綁定樹視圖項目子項,則可以添加 - 從後臺將子項移除到視圖。它使用同步上下文項添加到視圖:
public class ThreadSafeObservableCollection<T> : ObservableCollection<T>
{
private SynchronizationContext SynchronizationContext;
public ThreadSafeObservableCollection()
{
SynchronizationContext = SynchronizationContext.Current;
// current synchronization context will be null if we're not in UI Thread
if (SynchronizationContext == null)
throw new InvalidOperationException("This collection must be instantiated from UI Thread, if not, you have to pass SynchronizationContext to con structor.");
}
public ThreadSafeObservableCollection(SynchronizationContext synchronizationContext)
{
if (synchronizationContext == null)
throw new ArgumentNullException("synchronizationContext");
this.SynchronizationContext = synchronizationContext;
}
protected override void ClearItems()
{
this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.ClearItems()), null);
}
protected override void InsertItem(int index, T item)
{
this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.InsertItem(index, item)), null);
}
protected override void RemoveItem(int index)
{
this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.RemoveItem(index)), null);
}
protected override void SetItem(int index, T item)
{
this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.SetItem(index, item)), null);
}
protected override void MoveItem(int oldIndex, int newIndex)
{
this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.MoveItem(oldIndex, newIndex)), null);
}
}
此外,我認爲,這條一定是對你有用:
Simplifying the WPF TreeView by Using the ViewModel Pattern
希望這將是有益的爲你...
謝謝,Ive實際上決定ap現在就用MVVM進行處理,因爲這似乎是很好的設計方式 - 再加上一個很好的機會嘗試一種新模式:)該鏈接非常有用,謝謝 – NZJames
Im非常高興,MVVM非常棒!也希望你考慮接受這個答案,如果它真的適合你。謝謝 –
您是否一次創建整棵樹? 你是否爲每個創建的項目觸發調用?
我會考慮加載樹的按需。也許當用戶去擴展一個節點時,你可以處理這個事件並獲取數據。我也會考慮每次調用加載項目組
爲什麼你不使用Windows窗體控件類的調用方法 –