Testing whether item is visible in virtual ListView
-
11-09-2019 - |
Question
I'm using a ListView control in virtual and OwnerDraw mode to display a number of items. Is there a way to test whether a certain item is visible (within the client area of the control) without triggering a draw event or a RetrieveVirtualItem event?
The problem is, I have a background thread that periodically adds more items to the listview. But for some reason, every time I add more items (increment VirtualListSize), it triggers a RetrieveVirtualItem for the last item added, even though it's nowhere near the visible range. And, of course, I only want to draw items that are actually visible.
Any ideas?
Solution
On virtual lists, Windows fires RetrieveVirtualItem
events in many strange places -- and they are different between XP, Vista and Win7. Owner drawn virtual lists are the worst.
If your goal is to reduce the number of RetrieveVirtualItem
events, you are out of luck.
If your goal is to reduce the number of redraws necessary for your OwnerDrawn
rows, you will be better off optimizing the redrawing more directly. For example, you can capture the rectangle of the damaged region in the WM_PAINT
event, and then use that in your subitem drawing method to determine if that subitem was damaged.
Or you could use ObjectListView -- an open source wrapper around a .NET WinForms ListView -- that has already dealt with this problem. If you are going to allow horizontal scrolling AND column rearranging, you really do want to use an ObjectListView -- for reasons explained here.