2012-10-19 115 views
3

我有一個TreeView控件,需要用大量的3層對象列表來填充,這些列表需要花費大量的時間來構建。我正在後臺線程上加載數據,然後將GUI更新發送到GUI線程,但是有太多更新,因爲每次添加一個節點時,我都必須發送該節點,然後我必須調用ExpandSubTree()方法,然後展開所有子節點,然後引發更多展開事件,並且它崩潰。有沒有辦法在後臺線程上建立TreeView控件?

有沒有一種方法可以構建控件,並且它在後臺線程上以某種方式打開/關閉狀態,然後只有在完成時才整理它?

+0

爲什麼你不使用Windows窗體控件類的調用方法 –

回答

0

每個樹視圖項都有一個屬性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

Custom TreeView Layout in WPF

希望這將是有益的爲你...

+0

謝謝,Ive實際上決定ap現在就用MVVM進行處理,因爲這似乎是很好的設計方式 - 再加上一個很好的機會嘗試一種新模式:)該鏈接非常有用,謝謝 – NZJames

+0

Im非常高興,MVVM非常棒!也希望你考慮接受這個答案,如果它真的適合你。謝謝 –

0

您是否一次創建整棵樹? 你是否爲每個創建的項目觸發調用?

我會考慮加載樹的按需。也許當用戶去擴展一個節點時,你可以處理這個事件並獲取數據。我也會考慮每次調用加載項目組

相關問題