Is there any event in a DesktopListBox I can use to know that the visible range of items has changed?
In my particular use case I’m going to have a list of rows with several million (often > 100M) rows in it. I don’t care to populate those rows as the cost of the transform required to do that will be prohibitively expensive.
Instead, I’d prefer to simply know what the 100 (or so) visible rows are, and perform a small subset transform of those (caching them) and simply using the PaintCellText event to render from the cached data. As the user moves around and scrolls, I can update the cache in real time.
But, this requires knowing when the visible range of rows has changed. I considered hiding the vertical scrollbar and instead creating my own, but this won’t capture keydown events that end up scrolling, paging, etc.
If there’s nothing like the above, my last consideration is to check the range loaded within the paint event and if the cell being drawn isn’t in the cache I can just load a slightly larger cache area, but this isn’t as desirable.
Certainly nothing with the built in ListBox. I created a grid control with a similar issue in mind. I used a canvas and draw the contents of the current rows onto the control. I then had my own scrollbars, which I set to the datas min and max. When my scrollbars signal a change I cause a repaint. You can implement the keyboard events within the custom control to imitate the listbox.
The general term for what you are describing it “Data on demand” and I have used both of the following to achieve this in various projects:
MacTechnologie’s shareware Data-On-Demand 2.4.2 which performs VERY well even when I pull rows from a remote database. It subclasses the Xojo Listbox and does most of the work for you. Highly recommended if all you need is what you are asking about.
piDog’s DataView control which does SO MUCH more than just also supporting Data On Demand. It does not subclass the Xojo Listbox but instead does its magic using a Canvas control so it supports LOTS of stuff you can’t easily do in a standard Listbox such as variable height rows, cells that span rows or columns, locking columns on the left to act similar to Excel’s “freeze panes”, and way to many other things to mention. It is available in both encrypted source and full source versions. At least check out the demo projects included with the trial.
I had to add the MouseWheel event to the listbox, and some code to it so mouse scrolling worked.
Function MouseWheel(X As Integer, Y As Integer, deltaX as Integer, deltaY as Integer) Handles MouseWheel as Boolean
If Listbox1.RowCount <> 0 Then
Var n As Integer = ScrollBar1.Value + deltaY
ScrollBar1.Value = n.Clamp(0, Data.LastIndex)
End If
Return False
End Function
The code below is in a global module.
Public Function Clamp(extends byref i as integer, min as integer, max as integer) As integer
If i > Max Then i = Max
If i < Min Then i = Min
return i
End Function
make a containercontrol, with your listbox(with no scrollbar) and a separate scrollbar (or two if you need)
you will then have your event in the scrollbar item, and you can scroll the listbox in sync.