【问题标题】:Modifying ObservableCollection while it is being displayed在显示时修改 ObservableCollection
【发布时间】:2012-08-21 00:46:30
【问题描述】:

我有一个树视图,其中 ItemsSource 是 ObservableCollection。每次用户通过使用后台工作者扩展子树并修改与子节点对应的底层 ObservableCollection 时,我都会动态加载子内容。但是,当我尝试在该线程中修改此 ObservableCollection 时,如果且仅当树已经展开时,它将失败(这意味着如果孩子的数量很少,那么它将正确填充)。

我希望实现的是,一旦我展开树,我可以看到孩子在处理过程中被动态填充。如何使用 ObservableCollection 实现该行为?

【问题讨论】:

  • 它是如何失败的?你在调用RunWorkerAsync() 方法吗?
  • 它默默地失败了。我在 VS 上运行调试,当调试器在后台工作线程中点击 collection.clear() 时,它就退出了。当我尝试评估该表达式时,我得到“NotSupportedException”
  • 是的,我正在调用 RunWorkerAsync 来启动我的后台线程。
  • 奇怪的是,只有当孩子的数量太大时它才会失败(大概需要太长时间并且树已经展开)

标签: wpf treeview observablecollection


【解决方案1】:

如何使用 ObservableCollection 实现该行为?

问题是您不能在 WPF 的后台线程上更新集合。绑定系统会自动将最简单的绑定编组到 UI 线程,而不是集合。你有两个选择。

  • 您可以使用 Dispatcher.Invoke 或 Dispatcher.BeginInvoke 编组调用以将数据添加回 UI 线程。这将允许添加数据,但不会在 WPF 更新绑定时导致跨线程异常。

  • (如果您使用的是 .NET 4.5)您可以在绑定上使用新的 EnableCollectionSynchronization 以允许跨线程访问集合。

【讨论】:

  • 如果我从静态实用程序类调用它,我如何访问 Dispatcher?谢谢!
  • 开个玩笑,我明白了。 Application.Current.Dispatcher
  • @Reed Copsey,使用一个比另一个有优势吗?我是 WPF 世界的新手,所以我最初的方法是使用 BeginInvoke 机制。但第二种方法似乎要简单得多。我正在使用.NET 4.5。有什么理由更喜欢前者而不是后者?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 2019-05-02
  • 1970-01-01
相关资源
最近更新 更多