我有一个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窗体控件类的调用方法 –