如何在单独的线程中循环访问集合并在绑定的列表框中反映当前项目?

发布于 2024-09-15 20:23:04 字数 500 浏览 8 评论 0原文

我有一个绑定到 ObservableCollection 的 ListBox。集合中的每个项目都表示不同的步骤以及执行该步骤的方法。我想做的是让BackgroundWorker 循环遍历集合,运行每个项目的操作方法,并让ListBox 反映当前步骤。

我的第一次迭代没有使用线程,只是为了让步骤继续运行。现在我创建了一个 ListCollectionView,将其设置为表示 ObservableCollection 中的数据,并将 ListBox 的 ItemsSource 绑定到它而不是 ObservableCollection。我注意到,即使我显式递增 CurrentItem,执行这些步骤仍然会阻止 UI 线程的更新。

我想在BackgroundWorker 中使用ListCollectionView,但我发现的大多数示例都是假设您正在修改列表的内容或排序而编写的。我不想这样做;我只想为每次迭代增加 CurrentItem。我猜想简单地引用它不会让我走得太远,因为它与 UI 线程上的项目相关联,并且编译器会抱怨。任何想法或指示将不胜感激。

I have a ListBox bound to an ObservableCollection. The items in the collection each signify a different step with a method to perform that step. What I would like to do is have a BackgroundWorker loop through the collection, run each item's action method, and have the current step be reflected by the ListBox.

My first iteration used no threading and was just to get the step running going. Now I have created a ListCollectionView, set it to represent the data in the ObservableCollection, and have bound the ListBox's ItemsSource to it instead of the ObservableCollection. I noticed running through the steps still blocks the UI thread's updates even though I'm explicitly incrementing the CurrentItem.

I want to use the ListCollectionView inside a BackgroundWorker but most examples I'm finding are written assuming you are modifying the contents or sorting of the list. I don't wish to do this; I simply want to increment the CurrentItem for each iteration. I'm guessing simply referencing it won't get me very far as it is tied to items on the UI thread and the compiler will complain. Any thoughts or pointers would be much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

长发绾君心 2024-09-22 20:23:04

您不应该看到来自编译器的任何抱怨,但如果您尝试更新从后台线程触发 INotifyPropertyChanged PropertyChange 的任何内容,您将在运行时收到异常。有几种方法可以解决这个问题。您可以使用 Dispatcher.Current.Invoke 从 DoWork 方法内部进行更新。您可以尝试通过 ProgressChanged 处理程序(在调用线程上运行)进行操作,并为每个已完成的步骤调用 ReportProgress。或者您可以在 RunWorkerCompleted 处理程序中进行更新(也在调用线程上运行),并且可能使用从前一个完成的处理程序触发的一系列连续的 BackgroundWorker 调用(如果您不通过通用队列或类似的东西)。

You shouldn't be seeing any complaints from the compiler, but you will be getting exceptions at runtime if you try to update anything that fires an INotifyPropertyChanged PropertyChange from the background thread. There are a few ways around this. You can use Dispatcher.Current.Invoke to just do updates from inside your DoWork method. You can try to rig something through a ProgressChanged handler (runs on the calling thread) and calls to ReportProgress for each completed step. Or you could do the updates in the RunWorkerCompleted handler (also runs on calling thread) and maybe use a series of consecutive BackgroundWorker calls that are triggered from the previous one's completed handler (this can get messy if you don't manage the steps through a generic queue or something similar).

征棹 2024-09-22 20:23:04

您需要查看 WPF 跨线程集合绑定 – 第 4 部分 – 宏伟的解决方案,我认为来源位于 QuantumBitDesigns.Core

这允许您从另一个线程更新列表,并将更改自动反映在可绑定的可观察集合上。

多线程更新 Observable 集合
图:演示应用程序显示了对单个 ObservableCollection 的多个更新

我已在多个项目中使用它,并取得了出色的结果。

You need to check out WPF Cross-Thread Collection Binding – Part 4 – The Grand Solution and the source I think is on QuantumBitDesigns.Core

This allows you to update a list from another thread and have the changes automaticaly reflected on a bindable observable collection.

Multiple threads updating an Observable Collection
Figure: The demo app shows multiple updates to a single ObservableCollection

I have used this on multiple projects with fantastic results.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文