如何在WPF中覆盖TreeViewItem以允许异步子加载?

时间:2009-09-15 22:46:03

标签: wpf asynchronous treeviewitem

我使用MVVM作为我的WPF架构,并且我将WPF TreeView实现为延迟加载(在扩展之前不会递归加载子项。)

但是,我需要在扩展时实现异步加载。有没有办法做到这一点?我需要将其保持在控制级别而不是代码隐藏/应用程序级别。

由于

4 个答案:

答案 0 :(得分:2)

为什么需要在控件本身中实现它?

假设这不是绝对要求,我将在返回指定节点的子节点的属性中处理此问题。如果尚未填充子项,请使用后台线程加载子项,并在找到它们时通知UI线程,然后将子对象添加到子项集合中。假设您正在使用ObservableCollection(或至少是一个实现INotifyCollectionChanged的集合),则在添加子项时,它们将异步显示在UI中。

答案 1 :(得分:0)

如果您使用延迟加载和HierarchicalDataTemplates,则只会获得您选择加载的项目。请记住,TreeView需要加载一个低于它显示的级别,以确定它是否应该显示Expand / Collapse Toggle按钮

答案 2 :(得分:0)

以下是如何执行此操作:

  1. 创建IEnumerable类型的附加属性
  2. 在属性的PropertyChanged处理程序中,将发件人强制转换为TreeViewItem并检查IsExpanded属性。
  3. 如果IsExpanded为true,请在ApplicationPriority.ApplicationIdle优先级处为您的填充例程执行Dispatcher.BeginInvoke
  4. 如果IsExpanded为false,请设置一个事件以检测它何时变为true并在回调中将Dispatcher.BeginInvoke设置为填充例程
  5. 在填充例程中,将目标控件的ItemsSource设置为附加属性值
  6. 使用样式在TreeViewItem上设置附加属性,而不是通过HierarchicalDataTemplate设置它(在那里省略ItemsSource)
  7. 这可以防止TreeViewItem在扩展之前设置其ItemsSource。创建这个机制是一些工作,但是一旦创建它,​​您可以通过简单地从HierarchicalDataTemplate中删除ItemsSource并在ItemContainerStyle中设置它来进行任何TreeView延迟加载。

答案 3 :(得分:-3)

对于需要延迟加载的每个UI元素,我使用了“查看GUID”。

示例说明:

  1. 一开始,Control.Tag =“0000-0000 ....”
  2. 用户进行互动,
    • 生成随机GUID,即guid1
    • Control.Tag = guid1
    • 创建了一个线程,其中包含(做什么,控制,guid1)
  3. 介于两者之间,用户进行另一次互动
    • 生成随机GUID(此次为guid2)
    • Control.Tag = guid2
    • 创建了一个线程,它接受(做什么,控制,guid2)
  4. 第一个主题完成:
    • 它将代码调用到UI线程中,该线程获取结果和执行前获得的guid
    • 调用的代码检查Control.Tag!= guid1,使 no 更改
  5. 第二个线程结束:
    • 它将代码调用到UI线程中,该线程获取结果和执行前获得的guid
    • 调用的代码看到Control.Tag == guid2,进行更改