【发布时间】:2009-06-08 12:17:02
【问题描述】:
我开发了一个 wpf 应用程序来在列表框中加载图像。要加载 300mb 的图像需要时间。我听说要在列表框中更快地加载图像,我们必须使用 observablecollection,但我不知道如何使用那个。 任何建议请.. 提前致谢
【问题讨论】:
我开发了一个 wpf 应用程序来在列表框中加载图像。要加载 300mb 的图像需要时间。我听说要在列表框中更快地加载图像,我们必须使用 observablecollection,但我不知道如何使用那个。 任何建议请.. 提前致谢
【问题讨论】:
仅当您要添加/删除/替换集合中的项目并希望 UI 自动更新这些更改时,您才需要 ObservableCollection。也就是说,ObservableCollection 非常适合 Thomas 或 Andy 关于在后台线程中加载的建议。
这是另一种值得一提的可能性,尽管它有局限性。 ListBox 仅为当前滚动到视图中的列表项创建 UI 元素。如果一次只能在列表框中看到少量图像,而其他图像都将被滚动到视图之外,那么您可以利用这一点,让列表框延迟加载图像。
为此,您不会将实际的图像对象放在 ListBox 中。相反,您会放置一些可以按需加载图像的东西。如果您从磁盘或 Web 加载图像,则列表可能包含 Uris。如果您正在做一些更高级的事情,例如从 Web 服务加载,该列表可能包含具有延迟加载图像的 Image 属性的类的实例。
然后将您的集合(任何列表,不一定是 ObservableCollection)绑定到 ListBox,并将 ItemTemplate 设置为构造适当 UI 并绑定到 Uri 或延迟加载 Image 属性的 DataTemplate。
优点:简单。无需编写线程代码。
缺点:这取决于数据量,但这可能会使滚动变慢,因为在您开始滚动之前不会加载后面的图像。此外,正如我所指出的,如果大多数图像在第一次显示时都适合 ListBox,那么这不会给你带来太多好处,线程会是一个更好的答案。而且 Uri 有一个很大的问题,一旦你向下滚动,ListBox 将丢弃它为第一个项目加载的图像,因此向上滚动与向下滚动一样慢(尽管自定义类与延迟加载属性可以解决此问题)。
【讨论】:
ObservableCollection 可以完全像 List 一样使用。但这无助于更快地加载图像...
您应该做的是将您的 ListBox 绑定到包含图像的 ObservableCollection,并在单独的线程中用图像填充集合。通常无法从另一个线程修改绑定集合,但我编写了一个 AsyncObservableCollection 类可以处理此问题。
【讨论】:
只是将图像移动到ObservableCollection 不会神奇地使它们加载得更快。可能需要很长时间的是从磁盘加载图像数据。您应该将此移动到后台线程,以便在加载图像数据时不会挂起主 UI 线程。考虑使用BackgroundWorker 或Dispatcher,这样您就不必自己编写所有线程代码。
【讨论】: