【发布时间】:2017-12-14 09:24:54
【问题描述】:
我在列表框中加载了很多图像。 在我尝试虚拟化之前有一段合理的加载时间。
现在我使用虚拟化,只加载视图中的元素,完全符合我的要求; 但是一旦它们落在视图之外,它们似乎就不会卸载,所以如果我一直向下滚动到底部,所有项目都已加载,我将失去虚拟化的优势。
在我显示任何图像之前,我的应用程序消耗 140MB,然后我显示 10 张图像,我的内存使用量等于 161MB,如果我滚动到最后一张图像,使用量是 300MB。如果 10 张图片使用 21 MB,则必须加载 300MB 的所有图片。
通过使用 Snoop 检查加载的 ListBoxItems 的数量,进一步确认了此行为。
代码中没有什么特别之处,我只是确保CanContentScroll 对enable 是正确的,而不是禁用虚拟化。我自定义了ItemContainerStyle 和ListBox 的模板,但它不应该影响虚拟化(或者至少不仅仅是卸载部分),不是吗?
<ListBox ItemsSource="{Binding myItems}" CanContentScroll="True"/>
我错过了什么吗?
结论
虚拟化显然有效。当每个 ItemContainer 落在视图之外时,它们都会在某个时刻被卸载。
问题可能是 BitmapImage 是如何缓存的。事实上,我正在使用以下 DataTemplate 来显示图像:
<Image>
<Image.Source>
<BitmapImage UriSource="{Binding}" />
</Image.Source>
</Image>
【问题讨论】:
-
在“他们似乎没有卸载”中,“似乎”这个词表明你正在以某种方式感知某些东西,这您解释为他们没有“卸载”。您能否更具体一点,以及您所说的“卸载”是什么意思?您只是在谈论
Unloaded事件吗? -
CanContentScroll启用虚拟化?<ListView VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling"/>呢? -
@EdPlunkett 当然:在我显示任何图像之前,我的应用程序消耗 140MB,然后我显示 10 张图像,我的内存使用量等于 161MB,如果我滚动到最后一张图像,使用量是 300MB。如果 10 张图片使用 21 MB,则必须加载 300MB 的所有图片。
-
@sam 谢谢。这将是对问题的一个很好的补充。
-
@sam 除了内存消耗,你如何检测项目容器没有被卸载?您是否附加了 Unloaded 事件处理程序?
标签: wpf listbox virtualization