Please help me understand the DesktopListbox.SelectionChanged event

There is probably some explanation for this structure that I don’t understand, and I can work around it, but I find it odd that one of the triggers for the DesktopListbox.SelectionChanged event is “When a cell is clicked even if it already is selected and the column is not editable” (emphasis added). That is, one of the triggers of SelectionChanged occurs specifically when the selection has NOT changed. Can someone please make sense of this for me? Thanks.

1 Like


for me SelectionChanged is called when you:

  • change the selection in the listbox (manually through click or through code e.g: SelectedRowIndex = 0)
  • click on a row or not on row (blank part)

And the event occurs even if the action if the same, like clicking on an already selected row or clicking on the blank part of the listbox when no rows were selected.

After the code will change depending if the RowSelectionType is Single or Multiple

The weird part is selecting the same row twice or more and firing “changed” while clearly it is not; the current selection is the same. So you need to annotate the last SelectedRowIndex and check if the current one matches to know if a REAL SelectionChanged has occurred. And that only works for RowSelectionType as Single. Because if it is Multiple, and you click, for example, on row 3, you will get a SelectedRowIndex = 3 and then if you click after on row 5 holding SHIFT, the selection will change the range to 3 to 5, but SelectedRowIndex will still the same, row 3. It will only change if you click on rows below, as 2, 1… So while selecting a range, it returns the lowest selected row from that range as the SelectedRowIndex .

While I can’t provide any kind of explanation for why it’s built the way it is, I did want to stop by and say *I do make use of it*. Clicking on your already selected row works as a view refresh in Lifeboat. It would cause me more work should the behavior change.



Thanks Tim. In my case, unfortunately, the refresh behavior is exactly what I would like to avoid.

If you’re having trouble with that, this at the top of SelectionChanged should do the trick:

if miLastKnownSelection = me.SelectedRowIndex then return
miLastKnownSelection = me.SelectedRowIndex

Again, no explanations, just “Hi, I use it the way it is, please don’t change it.”

1 Like

Listed as “Not a bug, a feature” from now on. :smile:

Thank you Tim. My approach to [your feature | my bug], as Rick puts it, is essentially the same as that you recommend, but as you know I’m mostly trying to figure out the logic of the SelectionChanged design.

The logic is as Julien + myself said, with an extra explanation from Tim why some people would want the changed() event behave as clicked() to avoid an extra event.

I appreciate the input. I understand that some like and rely on the current approach, and I get the idea that this event is intended to interpret a variety of actions automatically, but in my view, the current design doesn’t make a lot of sense.

I think a “SelectionChanged” event should never fire when the user takes an action that does not result in the selection changing. The issue is partly semantic and partly functional.

First, the semantic. Either rename the event to describe what is actually happening – “RowSelected” or something similar – or have two events, RowSelected and SelectionChanged, but with the latter only firing when the selection has actually changed.

Second, the functional. As it stands, actions are combined which, in my view, really shouldn’t be combined. It’s like having a MouseEnter event automatically causing an object to refresh, without the option, or having MouseDown and MouseUp events combined into a single event, without the option. These are of course separated for more granular control.

Ok, back to regularly scheduled programming.

1 Like

You made me curious how PopupMenu behaves. So, I checked!

On macOS, selecting the already selected item raises SelectionChanged (though it hasn’t)
On Windows, selecting the already selected item does nothing

Personally, I prefer to receive too many events and ignore them. There isn’t much I can do to receive an event that never occurred. I could certainly agree to renaming the event to clarify the action. This Desktop* prefixed framework is supposed to be the new names though, so who knows if they’ll rename the event now.

Xojo as a company is on holiday until the 9th. We might have to wait a bit to get an official comment.

1 Like