Why is ListView.CacheVirtualItems not called prior to RetrieveItem?

536 Views Asked by At

I have a form (.NET 4.5 VS.2015) with a ListView that may contain a couple hundred even more than a thousand rows. Experiments show already that the form gets bogged down and unresponsive because it tries to load ALL ListViewItems when only about 20 are shown at any given time.

Therefore I implemented Virtual Mode on my ListView with a simple cache. I have set the VirtualListSize, enabled Virtual Mode and hooked up event handlers for both RetrieveItems and CacheVirtualItems events.

Now, as per the documentation you are made to believe CacheVirtualItems would be called prior to the RetrieveItems to allow your cache to be populated with the range of items the ListView intends to have in view.

But for what I see, CacheVirtualItems is never called before the first RetrieveItems! You would expect it to be called so that you can create your cache and prefill it (at least set capacity) and then fill appropriately on a cache miss.

Am I not understanding something well? If CacheVirtualItems is not called first to let your application prepare for the requests then what's the point?

1

There are 1 best solutions below

1
TnTinMn On

The WinForm ListView is a wrapper for the native control and while it would seem desirable that CacheVirtualItems event would be raised prior to RetrieveVirtualItem, the behavior of the native control precludes that. The documentation for LVN_ODCACHEHINT in the Remarks section states:

Note that this notification code is not always an exact representation of the items that will be requested by LVN_GETDISPINFO. Therefore, if the requested item is not cached while handling LVN_GETDISPINFO, the application must be prepared to supply the requested information from a source outside the cache.

These are the messages that the Listview control is responding to when it raises the events in question. See the code for the ListView WMReflectNotify method starting at line 6010.