top displayed line in listbox

I have been trying to figure out a way to determine, on the fly, which row is the top displayed line in a listbox. I don’t mean row 0; I mean the one right at the top, or under the header if there is one, even as the listbox scrolls. Whether the scrolling is done by the mousewheel or the scrollbar, or the page up/page down keys, how do I determine what row is the one displayed at the top of the listbox.

I have been at this for several days now so am probably at the point of brain-mush.

Listbox.ScrollPosition

Thanks, Tim, but that doesn’t really solve my problem. ScrollPosition seems to be a historical value rather than a current one. Here’s why I say that.

I have a short listbox with the capability of displaying the header and 5 rows. The list itself has far more than 5 rows of data. I put the following code in the listbox’s MouseWheel event:

Textfield1.text = str(me.scrollposition)

When I move the mouse to the listbox and scroll the wheel one stop, ScrollPosition shows zero in the textfield even though the top line displayed in the listbox is line 3. A second one-stop turn of the listbox puts 3 in the textfield but the listbox has advanced to line 6. This tells me that ScrollPosition returns the position that was valid before the wheel was scrolled, not after.

Is there a way to monitor the true scrollposition in real-time other than by firing a short interval ModeSingle timer?

BTW, I’m running 2016R3 on Windows 10 (I can’t move to R4 until some of the Windows-only UI bugs are fixed).

That has to do with when ScrollWheel is fired.
If I put that code anywhere else, I always get the right scroll position.

I made a Listbox subclass with the timer built in for you, it fires a MouseWheelAfter event.
MouseWheelAfter.xojo_binary_project

Hang on a second, I see all kinds of confusion here.

  1. On macOS Sierra (smirks at Tim), the behavior is as I’d expect, and as I always thought this worked. i.e. I scroll the mouse wheel and the scrollposition is updated. It is not a historical value on my Mac, it is the current visible row.

  2. When I try Tim’s project, I get the same results for the standard ListBox and Tim’s subclass. Both show the current visible row.

  3. So, is this a Mac vs Windows thing? Are you on Windows, @Dale Arends ?

  4. feedback://showreport?report_id=22204 has a comment from @Joe Ranieri which says “The MouseWheel event fires before the ListBox processes the scroll in order to let the behavior be customized.” But, again, that isn’t the behavior I see.

So I guess we need to a) figure out what the expected behavior is and b) check that this expected behavior applies to all platforms.

Gavin are you using a Trackpad or a mouse with a scroll wheel.

I am able to reproduce the behavior Dale is experiencing on the non-modified Listbox with a logitech mouse scroll wheel here on my Mac running Mac OS X El Capitan.

I believe you may be getting different results because you might be using an Apple product that sends many more MouseWheel events than a clicky step wheel mouse.

[quote=305345:@Tim Parnell]That has to do with when ScrollWheel is fired.
If I put that code anywhere else, I always get the right scroll position.

I made a Listbox subclass with the timer built in for you, it fires a MouseWheelAfter event.
MouseWheelAfter.xojo_binary_project[/quote]
Thanks, Tim. That’s basically the same approach I had to take although your code is a bit cleaner than mine.

[quote=305440:@Tim Parnell]Gavin are you using a Trackpad or a mouse with a scroll wheel.

I am able to reproduce the behavior Dale is experiencing on the non-modified Listbox with a logitech mouse scroll wheel here on my Mac running Mac OS X El Capitan.

I believe you may be getting different results because you might be using an Apple product that sends many more MouseWheel events than a clicky step wheel mouse.[/quote]
That’s possible. I’m using an Apple Magic Mouse 2 which I always assumed acted like a clicky wheel. I think I’ve a physical clicky wheel mouse somewhere that I’ll try after turkey tomorrow.

Where this all started is that Xojo under Windows 10 (I don’t know about on a Mac) doesn’t draw the dividing line between the listbox header and the top data row. This makes it a bit visually confusing from a UI standpoint. My intent was to always know which data row is at the top and draw the line myself.

So, as is often the case with me, after going to the trouble of handling it I decided on a different approach; that of making the headers bold. I’d still like to see the line drawn but at least now the headers visually stand out.

Why not simply place a 1 px high rectangle where you need the line ?

Respectfully, Michel, follow the thread. It started as a way to always know which data row is at the top of the display area of a listbox regardless of the scrolling. So, exactly where would I draw the rectangle? You can’t draw in a ListBox’s Header, and if you want to draw in the data cells, and always have it at the top of the top row, you need to know which row is at that location. Then, with that approach, you need to erase the line (or rectangle) every time the list scrolls and redraw it in the new top row.

All this is certainly doable, except for drawing into the header, but is probably more trouble than it’s worth. That’s why I opted to go the Bold Header route.

Dale, respectfully, you don’t get it. Please read carefully the single phrase I posted.

I am not saying anything like drawing into the cells, but simply to place a Rectangle control 1px high and with the same width as the listbox just underneath the header, over the Listbox. No need to fuss with drawing or scrolling and all the rest.

You said you wanted the line anyway, after making the header bold. I just tried to suggest something that works without convoluted efforts. Sometimes simpler is better.

woo hoo… i’m better :smiley:

Hmmmm. You mean just letting it “float” in front of the listbox? That might be possible. I’ll have to try it and see how it works. It might get a bit hairy if the listbox is set to resize with the window. And it’ll take some work to reposition if the user changes the listbox’s font size. Still, it might work.

It does work. I tested it. And the line does not “float”. It becomes child of the listbox.

Now resize is probably simpler than you think. As far as I know the heading does not change in height when changing fonts. So a simple lock left and right can probably do.

Since you seem awfully doubtful, just try it and see. Or don’t. I am not the one looking for a solution.

In theory you should be able to get the top displayed row using the RowFromXY method. Something like RowFromXY(RowHeight * 1.5, 5) assuming that the heading is the same height as the row.

I say in theory because I haven’t tried it in practice.