2012-10-19 71 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

您是否一次创建整棵树? 你是否为每个创建的项目触发调用?

我会考虑加载树的按需。也许当用户去扩展一个节点时,你可以处理这个事件并获取数据。我也会考虑每次调用加载项目组

相关问题