0

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?

Lord of Scripts
  • 3,579
  • 5
  • 41
  • 62
  • Have you tried following the [example provided in the documentation](https://msdn.microsoft.com/en-us/library/system.windows.forms.listview.virtualmode(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#Anchor_3)? – TnTinMn Aug 27 '16 at 00:14
  • That example has some flaws, two at least. I have a slight variation of that without the Search function (just cache & retrieve) but my experiments show that CacheVirtualItems is never called prior to Retrieve. There are many retrieves before the first CacheVirtualItems call takes place. – Lord of Scripts Aug 29 '16 at 20:11
  • The documentation example functions properly, so I do not understand your comment. – TnTinMn Aug 29 '16 at 22:29

1 Answers1

2

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.

TnTinMn
  • 11,522
  • 3
  • 18
  • 39
  • Thanks, now that explains why though it definitely not what I would expect. The purpose of a cache is to load it with data that is requested or going to be requested. Anyway, that odd behaviour is not going to change so now I should just work around that. Thanks for the info @TnTinMn – Lord of Scripts Aug 30 '16 at 23:02