Highlight keyword match in listbox

Hello! I have been successful in getting my application to determine if certain text is inside of a listbox. However, I’m a little lost on figuring out how to highlight the text that was found. I understand the listbox1.list(index) function but that’s if you know the row index. How would I get my app to know which row to highlight? I hope I described this correctly.

If you don’t know the index, then how did you determine the text was there?

Well I have this code to determine if the text is in second column of the listbox

for i as integer = 0 to codelist.listindex - 1

if searchtext.text = codelist.cell(i,1) then
result.text = "Keyword Found"
end if

next i

When that statement is true, i holds the value of the rowindex you need to Select (highlight)

For i As Integer = 0 To codelist.RowCount - 1
  
  If searchtext.Text = codelist.CellTextAt(i,1) Then
    
    result.Text = "Keyword Found"
    CodeList.SelectedRowIndex = i 
    
    Exit For
    
  End If
  
Next i 

That works. Thank you Hector!!

1 Like

If you search all the rows in a listBox with many thousands or even a million rows, searching the lot will lock up the UI - unless you do that in a thread.

You could instead use the PaintCellText event to draw the text in a different colour, or the PaintCellBackGround event to fill the cell with some colour (instead of white). The code only searches the rows drawn in the listbox - not the entire list, so the speed to do this is only dependent on the number of rows actually displayed - not the entire list.

For example, I have a subclass of listBox which has an attribute “filter” as string. The rowTagin each row is used to store an object (aElement) which has several attributes including a “name” which is drawn into the cell in the appropriate colour (in this case black if there is a match, or grey if no match).

Function PaintCellText(g as Graphics, row as Integer, column as Integer, x as Integer, y as Integer) Handles PaintCellText as Boolean
Var e as aElement
Var n as string

if row>-1 then
e = me.RowTagAt(row)
if e<>nil then
if me.filter.Length > 0 then
if e.name.IndexOf(me.filter) > -1 then
g.DrawingColor = mc_Black
else
g.DrawingColor = mc_Grey
end if
else
g.DrawingColor = mc_Black
end if
g.DrawText e.name, x, y
end if
end if

return True
End Function

If you use this approach, it is upto you to decide how to manage which rows are selected (or not) since you’re not using the listbox’s own way of doing it…

In this case, do not make the seach on the ListBox contents, but on the original file…

In all cases, with so many Rows, you populate the ListBox with far fewer lines; YOU DO NOT FILL THE LISTBOX WITH “many thousands or even a million rows”…

True. However no mention of millions of rows was made. He asked a simple question I provided a simple answer :wink:

Then again who in his right mind would populate a Listbox with millions of rows?

Thousands is OK. I put 23k rows in a listbox, read from an SQLite db and it takes less than a second (timings vary).

But then you would probably search for a record in the DB and just let the UI know what it needs to hightlight wouldn’t you?

Indeed.

As an aside, doing a timing test threw up a potential race condition in my app, now fixed, so that was useful! :smiley:

1 Like