listbox selection post-edit & sort

I have a listbox that’s driving me a bit crazy.

I double-click a cell, edit the contents, then hit return.

my code in the celllostfocus event grabs the cell contents, updates my data structure and then I want to sort the listbox to ensure its order remains alphabetical after the edit.

No problem, except the list item now selected is in the position where the edited row was, pre-sort. I want to retain the selection of the same row, even if it’s in a different position due to the sort.

So I’ve written code that loops though the newly sorted list to find the row that belongs to my desired selection and set listIndex= to it.

it still doesn’t work.

If I step through the code and watch the listbox’s changed event I see that it gets my listindex change and then gets another event putting it back to the row I don’t want.

Am I missing something simple here? I think it’s the “return” that I hit after editing but I don’t seem to have the means to stop the selection.

I can try some extra bits like setting a timer to make my selection after everything event-wise has calmed down but I’d sure like to find if I’m just missing something…

and where is this code? post it please… it may just be a matter of “timing”

it’s pretty basic stuff

    dim LB as Listbox = self.listBox1
    dim i, num0 as Integer
    num0 = LB.ListCount - 1
    for i = 0 to num0
      if LB.RowTag(i) is selectedObject then
        LB.Selected(i) = true
      end if
    next 'i

but what I’ve found is that, as long as the execution of anything I try starts with the celllostfocus event, there’s anyways something that triggers after I’m done.

Finally I just created a timer that executes 10ms after the other code and makes the selection. It’s cumbersome but it works.

I’m wondering if I’m looking at a bug or… this project is in 2015r2.2

I may be wrong, but what if you use RowTag (or CellTag if you use RowTag) and set it True (this Row is selected) and False (this Row is not selected) before the change(s), do your changes, Sort, and:

a. Clear all selections using Listbox std code,

b. Scan a second time and set as selected every Row where RowTag (or CellTag) is True


Try putting the re-select in a timer to allow the listbox to finish updating before the selection.

@Emile Schwarz : thanks but iterating through the list to find the item that should be selected isn’t the problem. It’s that no matter what I do, the selection changes.

@Scott Siegrist : yes, a timer is exactly what I did, and it works fine.

The question I have is, am I the only one to deal with this issue? Is this intended behavior? a bug? a massive time sink?

This works:

Add a Boolean property bSetListIndex and then:

Sub CellAction(row As Integer, column As Integer) Me.RowTag(row) = True Me.Sort bSetListIndex = True End Sub

Sub Change() If bSetListIndex = True Then For i As Integer = 0 to Me.ListCount - 1 If Me.RowTag(i) = True Then Me.RowTag(i) = False bSetListIndex = False Me.ListIndex = i Exit for i End If Next i End If End Sub

No, you’re not the only one to have ever been bit by making assumptions about the timing of events. Many events happen in the middle of a sequence of steps the framework is going through. Most of the time, this works in your favor. When it doesn’t, however, it can be perplexing. Most of the time, the most straight-forward thing to do is to use a timer to “jump out” of the process sequence so you can do something once everthing else is done. A 1ms timer will do, you don’t want to introduce any delay, you just want your code to happen “next”. Note that you can instantiate the timer in code, so everything is self-contained. No need for timers littering your layout.

Or fire a CallLater singleshot. (that always sound so cool)