I want to programmatically reorder some rows in a listbox. Anybody have suggestions?
As you realized: Xojo has no functionality for it so you have to readout the Array representing the listbox, sort it like you want, clean the listbox and refill it in the order you want to have it. This would be the fastest way to get Listbox sorted as you need it. The istBox by self has no sorting functionality.
To do this task with multidimensional arrays is not trivial but should work. another way described in XoJo forum in 2021 is using an in memory sqlite database to sort the data and fill them into the listbox like you want it. With SQLite your sorting functionality would be much more robust and you would have more query functionality to reach the pont you want.
An old discussion about sorting a listbox you will find on XoJo forum here:
Perhaps these two listbox extensions can help:
Public Function RowData(extends list as DesktopListbox, row as integer) As Dictionary
dim ct(),rt as Variant, c(),cht() as Variant, cc() as Variant, cs() as Variant, rp as Variant
for col as integer = 0 to list.LastColumnIndex
ct.add list.CellTagAt(row, col)
c.add list.CellTextAt(row,col)
cc.add list.CellCheckBoxValueAt(row,col)
cht.add list.CellToolTipAt(row,col)
cs.add list.CellCheckBoxStateAt(row,col)
next
rt = list.RowTagAt(row)
rp = list.RowImageAt(row)
dim sel as boolean = list.RowSelectedAt(row)
return new Dictionary(“ct”:ct, “c”:c, “cc”:cc, “cht”:cht, “cs”:cs, “rt”:rt, “rp”:rp, “sel”:sel)
End Function
Public Sub RowData(extends list as DesktopListbox, row as integer, assigns d as Dictionary)
dim ct() as Variant = d.Value(“ct”)
dim rt as Variant = d.Value(“rt”)
dim c() as Variant = d.Value(“c”)
dim cht() as Variant = d.Value(“cht”)
dim cc() as Variant = d.Value(“cc”)
dim cs() as Variant = d.Value(“cs”)
dim rp as Variant = d.Value(“rp”)
dim sel as Variant = d.Value(“sel”)
for col as integer = 0 to list.LastColumnIndex
list.CellTagAt(row, col) = ct(col)
list.CellTextAt(row,col) = c(col)
list.CellCheckBoxValueAt(row,col) = cc(col)
list.CellToolTipAt(row,col) = cht(col)
list.CellCheckBoxStateAt(row,col) = cs(col)
next
list.RowTagAt(row) = rt
list.RowImageAt(row) = rp
list.RowSelectedAt(row)=sel
End Sub
It does
But it sorts lexically
if you want something else you end up implementing a method that compares rows in whatever way you want
Depending on what you want to do there may be several options
More details would help
Cough Cough.
I regularly do it.
It sorts as strings.
You can do a numerical sort by sorting a hidden column, or formatting numbers with leading spaces.
You need to get creative if you want to sort by x, then y -within-x if data is split over two or more columns.
Again, a hidden column can do the job, but it is easier to refill by that point.
Don’t forget the possibility that the listbox may have several columns and tags.
that’s clear. And not making it better. Except Android. There is no added Column for Listbox. Android Table is a one column table.
Norman was correct. I should have stated the problem more definitely. As stated very well in a post above I want to “sort by x, then y -within-x” where x is in column 1 and y is in column 2.
I can’t use the sql “ORDER BY” for the x sort since I fill the listbox with multiple SELECTs then want to order the resulting data. Anyway the x sort is easy after the data is all loaded. The y-within-x sort is the hard part.
I suspected I would have to load the data into either a dictionary or a dummy listbox and then copy it back to the listbox in desired order. I was hoping there was an easier solution. I better get to work.
Implement the listbox CompareRows event. Compare x from the given rows. If they are equal then compare y.
create a SQL VIEW from the various selects
Thanks prodman. I am embarrassed for not thinking of that. Took me about 2 minutes to modify the code.
Or implementing the CompareRows (or whatever they renamed it to now)
i would prefere a dictionary
