Weird defect in DesktopListBox SelectionChanged

I’ve observed some weird behavior (likely a defect) when DesktopListBox’s SelectionChanged is called when the Requires Selection option is enabled:

My SelectionChanged event:

Var selectedRow as Integer = serialNumbersListBox.SelectedRowIndex

System.DebugLog("SelectionChanged: row = " + Str(selectedRow))

if (selectedRow = ListBox.NoSelection) Then
  myActivationsListBox.RemoveAllRows
else
  // do my code for the selection changing (irrelevant to this example)
End If

This works GREAT. UNTIL I click below the last row.

In that case, I get a SelectionChanged where the selected row index is the last row (3). OK, fine.

But what happens next is that DesktopListBox.SelectionChanged is called in a cascade dozens of times!

Here’s some simple message debugging that shows what’s going on:

Here I click on the last row, row 3 (there are four rows):

SelectionChanged: row = 3

That’s perfect. SelectionChanged is called. I click on another row, row 1:

SelectionChanged: row = 1

Same good, expected behavior. NOW, I click BELOW the last row, row 3:

              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3
              SelectionChanged: row = 3

This doesn’t happen when Requires Selection is NOT enabled. In that case, SelectionChanged is called ONCE, with the row passed -1, as expected.

I can (and should) inhibit my own code from doing anything if there’s no change to the selected row, which will prevent the unexpected SelectionChanged cascade from impacting performance (which it would). But this appears to be a unexpected defect.

Turns out this is a a big going back to API 1… I just tested it in 2019R1.1 (and only that)

At least in 2019r1.1, It looks like the number of times the change event fires, regardless of if the selection changes or not, is equal to the the # of populated (or a least visible - did not test extensively) rows in the listbox.

BUT that only happens with mouse clicks. If you use the arrow keys to change selection it only fires once.

In any case means a I have a LOT of old inefficient code!

So it looks like 2 bugs when using mouse clicks:

  1. fires change event on mouse clicks even when there is no change in row selection
  2. when it fires, it fires once for each row in the listbox

-Karen

@KarenA – I’m very confident I only have four rows, period, in this DesktopListBox. I DO have three columns, but I don’t think there’s any way the mat adds up to the 21 times SelectionChanged is being called for me.

As I said i tested in 2019R1.1 so pure API 1… That listbox had 1 column and 5 rows and very time I clicked on it, if the selection changed or not, I got 5 change events firing.

I don’t know how different the API 2 listbox might be in that respect… I just wanted to know if the API 1 listbox was affected.
-Karen

You sure that’s not just because all five rows are visible? I could see the event being called for all visible rows.

I got over 21000 rows in my listbox, loads up from an SQLite database in under a second and is just as snappy as those with fewer rows.

RemoveAllRows can cause a selection change. Calling it inside of a selection change is like calling Refresh inside a Paint event.

Edit: Oh these are different Listboxes oops! :man_shrugging:

OK, the number of times the event fires is related to how long you hold down the mouse / trackpad.

Try keeping the mouse down for a while. The event is repeated. Even a quick click seems to do it 3 or 4 times. Depending on how long your click is.

You can work around the issue with the following code:

Static OldValue as Integer = -2
If Me.SelectedRowIndex <> OldValue then
    OldValue = Me.SelectedRowIndex
    ' Your code here.
End if

Also, changing:

Var selectedRow as Integer = serialNumbersListBox.SelectedRowIndex

to this:

Var selectedRow as Integer = Me.SelectedRowIndex

Make the code a little more generic. It will better survive changes to the name of controls. It also makes the code more readable as you instantly know Me is referring to this ListBox, rather than another one.

It’s worth adding it to Feedback.

1 Like

Do you also have a SelectionChanged event in myActivationsListBox that logs this way?

I don’t have a similar SelectionChanged event in the myActivationsListBox, because that listbox doesn’t rely on items being selected. Any reason to suspect it would be any different?

As i said that might be a possibility as I did not test extensively… While that list box had 5 rows it was tall enough to display 15 rows.

Doing a bit more testing i find If I shrink the listbox so only 3 rows are visible and the the vertical scrollbar appears, the Change event only fires once when changing selection!!!

So at least for API 1, it looks like it is related to having a listbox with “empty” visible rows… Don’t know about DesktopListbox in API 2.

-Karen

-Karen

As I said, the number of repeats is down to how long you hold the mouse down on the click. It repeats as long as you hold the mouse down in the blank area.

1 Like

Make sure you report that if you haven’t already. That seems like an obvious bug.

2 Likes

Just adding one now, with project.

1 Like

OK, justed added to feedback:
<https://xojo.com/issue/67939>

2 Likes

I reported this in July 2017 <https://xojo.com/issue/48908>

I ned to go through my old Archived cases but I’m waiting on <https://xojo.com/issue/67324> before I do it so I don’t have to do it multiple times.