Getting and setting a winForms ListView scroll position
10:32 06 May 2020

How can I:

  • Retrieve A ListView's current scroll position as a pixel-based coordinate? (Ex: if the ListView is all the way to the bottom, then this function should return the equivalent of listHeight - viewPortLength.
  • Set a ListView's current scroll position to said pixel-based coordinate, causing the ListView to jump to this place?
  • Do this in vb.net or C#.net managed code?
  • Handle ListViews with 'groups'?

Here it can be assumed that the listView is a simple plain textual list view (Not the big/small pictures version(s)).

While there are a lot of answers pointing to using the EnsureVisible function, all this does is jump around randomly to ensure the item indicated is visible. If a certain 'scroll position' is desired, and one has no idea beforehand what the visible item(s) should be (because the underlying data might change), then this method is of little use.

I've also found suggestions of using the win32-api, specifically using setScrollInfo and setScrollWindowEx. Unfortunately, setScrollInfo only really ephemerally modifies the scroll bar itself and leaves the window content unchanged, and is only really useful for those implementing their own special scroll behaviours. setScrollWindowEx should in theory work via adjusting viewports and blitting in new content, but when used with this object said function will cheerily report that it was succesful without doing anything and reporting it has redrawn a rectangle of size [0, 0] at position [0, 0] in [w,h],[x,y] notation. In other words, the internal state of a ListView isn't very accessible.

c# .net vb.net listview