有没有办法在后台线程上构建TreeView控件?

时间:2012-10-19 16:12:22

标签: c# wpf treeview

我有一个TreeView控件,我需要填充一个大的3层对象列表,这需要花费大量的时间来构建。我正在后台线程上加载数据,然后将GUI更新发送到GUI线程,但是有太多的更新,每次我添加一个我必须发送的节点,然后我必须调用ExpandSubTree()方法,然后展开所有子节点,然后触发更多的展开事件,然后崩溃。

有没有办法可以在后台线程中以某种方式构建控件及其打开/关闭状态,然后只有在完成后才将其编组?

2 个答案:

答案 0 :(得分:0)

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

我会考虑按需加载树。也许当用户去扩展节点时,您处理该事件并获取数据。我还会考虑每次调用加载项目组

答案 1 :(得分:0)

每个树视图项都有一个属性Children,如果将每个Tree View Item的Children绑定到ObservableCollection,您可以从BackGroundWorker或其他线程向其添加项。如果您使用follow集合绑定树视图项子项,您可以添加 - 从背景中删除子项到视图。它使用同步上下文将项添加到视图中:

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

希望这对你有用......