【问题标题】:Why is ListView.CacheVirtualItems not called prior to RetrieveItem?为什么在 RetrieveItem 之前没有调用 ListView.CacheVirtualItems?
【发布时间】:2017-01-03 15:41:16
【问题描述】:

我有一个带有 ListView 的表单(.NET 4.5 VS.2015),其中可能包含几百甚至一千多行。实验已经表明,表单会因为在任何给定时间仅显示大约 20 个时尝试加载所有 ListViewItems 而陷入困境且无响应。

因此,我使用简单的缓存在 ListView 上实现了虚拟模式。我已经为 RetrieveItems 和 CacheVirtualItems 事件设置了 VirtualListSize、启用了虚拟模式并连接了事件处理程序。

现在,根据文档,您相信 CacheVirtualItems 会在 RetrieveItems 之前被调用,以允许您的缓存填充 ListView 打算查看的项目范围。

但就我所见,CacheVirtualItems 在第一个 RetrieveItems 之前从未被调用过!您可能希望调用它,以便您可以创建缓存并预填充它(至少设置容量),然后在缓存未命中时适当地填充。

我不是很好理解吗?如果没有首先调用 CacheVirtualItems 来让您的应用程序为请求做准备,那么有什么意义呢?

【问题讨论】:

  • 这个例子有一些缺陷,至少有两个。如果没有搜索功能(只是缓存和检索),我有一个轻微的变化,但我的实验表明 CacheVirtualItems 在检索之前从未被调用过。在第一次 CacheVirtualItems 调用发生之前有很多检索。
  • 文档示例功能正常,所以我不明白您的评论。

标签: c# winforms listview user-interface virtualmode


【解决方案1】:

WinForm ListView 是本机控件的包装器,虽然在 RetrieveVirtualItem 之前引发 CacheVirtualItems 事件似乎是可取的,但本机控件的行为排除了这种情况。备注部分中LVN_ODCACHEHINT 的文档指出:

请注意,此通知代码并不总是准确表示 LVN_GETDISPINFO 将请求的项目。因此,如果在处理 LVN_GETDISPINFO 时未缓存请求的项目,则应用程序必须准备好从缓存外部的源提供请求的信息。

这些是Listview 控件在引发相关事件时响应的消息。 See the code for the ListView WMReflectNotify method 从第 6010 行开始。

【讨论】:

  • 谢谢,现在这就解释了为什么,尽管这绝对不是我所期望的。缓存的目的是加载已请求或将要请求的数据。无论如何,这种奇怪的行为不会改变,所以现在我应该解决这个问题。感谢@TnTinMn 提供的信息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
  • 2011-04-19
  • 1970-01-01
  • 2018-03-27
  • 1970-01-01
  • 2021-01-26
  • 2012-08-01
相关资源
最近更新 更多