Listbox Selected Row BackgroundColor

I have a textfield and button which I use together to search for a particular item in a Listbox. However, I am having difficulty getting the selected Listbox item highlighted consistently. Most of the time, it is highlighted in gray (which isn’t what I want) but sometimes the desired blue coloring is provided. Here is my code.

In the button Action I have

if TextFieldFindName.text > "" then
  for x as integer = 0 to ListboxResults.LastRowIndex
    if ListboxResults.CellValueAt(x, 0).IndexOf(TextFieldFindName.text) > -1 then
       ListboxResults.Selected(x) = true
       ListboxResults.ScrollPosition = x
      exit
    end if
  next
end if
ListBoxResults.Invalidate 'just experimenting to see if it helps

In the Listbox CellBackgroundPaint I have

dim c as integer
c=column
//alternate row colors
if (row mod 2)=0 then
  g.foreColor = rgb(232,235,255)
  g.fillrect 0,0,g.Width,g.height
end if

//if selected, fill in row with dark blue color and white text 
//otherwise draw with black text 
if me.selected(row) then
  g.foreColor = rgb(66,82,255)
  g.fillrect 0,0,g.Width,g.height
  g.foreColor = rgb(255,255,255)
else
  g.foreColor = rgb(0,0,0)
end if

I am currently using Version 2022 Release 1.1 (although the project was started over a decade ago and undergoes frequent updates–although this is a completely new addition to the program). I am running the project on Monterey Version 12.1.

You need to return True in CellBackgroundPaint to tell the system that you handled the event

2 Likes

The default selection color is grey when the listbox doesn’t have focus,

2 Likes

Thanks Marcus and Tim. Adding return True has improved things. I will test further.

That program flow is wrong too. Try in the Listbox CellBackgroundPaint event:

Function CellBackgroundPaint(g As Graphics, row As Integer, column As Integer) Handles CellBackgroundPaint as Boolean

  //alternate row colors
  If (row Mod 2)=0 Then
    g.foreColor = RGB(232,235,255)
  Else
    g.foreColor = RGB(255,255,255)
  End If
  
  //if selected, fill in row with dark blue color and white text 
  //otherwise draw with black text 
  If Me.selected(row) Then g.foreColor = RGB(66,82,255)
  
  g.fillrect 0,0,g.Width,g.height
  
  Return True
  
End Function

Note: if you draw the background in a dark colour then macOS automatically switches the text to white

P.S. If you want to change the text colour (eg to red) you should do that in the CellTextPaint event:

Function CellTextPaint(g As Graphics, row As Integer, column As Integer, x as Integer, y as Integer) Handles CellTextPaint as Boolean

  If Me.selected(row) Then g.foreColor = color.Red
 
End Function

Markus, your code is cleaner and works except that when using the find button, the Listbox text for the selected item remains black, which is hard to read with a darker background. I am experimenting with better (lighter) backgrounds like rgb(153, 153, 255).

When I make a selection by clicking in the Listbox, the darker background appears AND the text color does turn to white.

Chris, my code works perfectly fine - the problem is whatever code you have.

Here is an example project: Dropbox - test lb.xojo_binary_project.zip - Simplify your life

Thank you for the sample code Markus. As you said it works perfectly, but for whatever reason I also had to add

Me.SetFocus

to the very beginning of my CellBackgroundPaint to get my code make the text color appear in white when I clicked on my find button for the first time.

The help that you and Tim provided is much appreciated. Thanks again.

Don’t put that in CellBackgroundPaint. That’s very inefficient. Put listbox SetFocus in your search code just before you set the list index.

3 Likes

Will do. Thanks!

Tim beat me to it, but here is why it is inefficient:

Part of the art of programming is to put your code in the right place.

The code in CellBackgroundPaint is called EVERY TIME a cell scrolls into view, so if you click on the scrollbar and 100 cells come into view you set the focus 100 times.

So every time you scroll around in the listbox your CPU usage goes up. That is the kind of thing that determines whether your app uses 3% or 25% of the CPU or even flickers.

So you need to put the code where and when it is needed - which is when you do the search and set the selected row.

3 Likes