Search in a multicolumn list box

I need to search in all the cells of a multicolumn listbox (very little listbox with few data in it).
I’ve seen the ListBox.List but from the manual in multicolumn listbox it can search “the contents of the (only?) first column.”
And i need to search in all the columns.
And above all i don’t understand how to use it.

myStringToSearch.txt = myListBox.List(Index as Integer)

Index as Integer should be what ?

Thw Index of the Row.

You could iterate through the rows of the Listbox, but maybe it’s faster/easier to search the data source that fills the list?

If you really want to go that route, try something like this:

For XRow As Integer = 0 To myListBox.RowCount - 1
  For YColumn = 0 To myListBox.ColumnCount - 1 

    myStringToSearch.txt = myListBox.CellValueAt(xRow, YColumn)
    // Do your stuff here...

  Next
Next

But this is not the fastest way and can cause trouble if the List is changed while you go through it.

1 Like

Thanks Sascha S

I’ve added here the declaration as Integer

For YColumn As Integer = 0 To myListBox.ColumnCount - 1

I insert your code in the myStringToSearch.text (text change event)
But when insert the first character in myStringToSearch.text appears a NO text and no other text can be inserted …
I’ve tried to understand what happens in Debugger
Btw when you say
// Do your stuff here…
myListBox shouldn’t automagically show the rows where found a cell with the same text of myStringToSearch.text ?

I’d recommend to put the Search Method into it’s own Method in the Container/Window.
In your myStringToSearch.TextChange Event you then call this Method using a Xojo.Timer.CallLater.
I’d also recommend to not start this search after the first, but maybe the 3rd letter and to use a 250+ milliseconds delay in the CallLater. I also recommend a Xojo.Core.Timer.CancelCall before this Xojo.Core.Timer.CallLater to avoid stagnation.

If your TextField.Value is trying to do some type of autocomplete, you need to make sure you always take into account what the user has already typed and place the cursor at the correct position. You could also use the Hint Value of your TextField, to suggest an autcomplete solution and do your autocomplete with a TAB Keypress or so.

If you want to show the Row with the first hit, you should exit the For…Next Loops with Exit For YColumn and Exit For XRow.

If myListBox.CellValueAt(xRow, YColumn).IndexOf( myStringToSearch.Value ) > -1 Then
// or If myListBox.CellValueAt(xRow, YColumn).Left( myStringToSearch.Value.Length ) = myStringToSearch.Value Then 
  // Use ListBox.ScrollPosition and XRow to scroll to the hit in the ListBox
  Exit For YColumn
  Exit For XRow
End If

And you could return a TRUE from your Search Method to signal to your TextChange Event Login, that you had a hit?

BTW: Please be aware that everything in this Thread is written from my mind and untested (may contain errors).

When you populate the listbox you could concatenate the contents of all the cells of the row and put it into the RowTag of the row. Then when searching you are only searching the RowTags for the search criteria. Should be very fast and your not iterating through every cell.

1 Like

use -1 for the Column number to get the whole Row contents.

But since we do not know what the OP want… (the Row # where the search text reside or the Row,Colum numbers… (Cell #)

1 Like

So i could search only for the -1 Column and find all the data of the row in it ?
I need to show the Row/Rows # where the search text reside

Why that not works ? It searches also for a partial word ?

Var LoopIdx As Integer
For XRow As Integer = 0 To ListaNotifiche.RowCount - 1

// Loop code here
If ListaNotifiche.CellValueAt(LoopIdx,-1) = txt5CercaTest.value Then
msgbox ListaNotifiche.CellValueAt(LoopIdx,-1)
// Search String Found, so Show the Row
ListaNotifiche.ListIndex = LoopIdx

// Set the found Row as Selected
ListaNotifiche.SelectedRowIndex = LoopIdx

End If
// End Loop Code
Next

And if i would like to re-populate the list with only the founded rows i should save all the founded rows (in an array?) and then add them to the list ?