1

Working on a desktop application and having a probably silly problem that's still managing to driving me mad.

I have a listbox that gets its rows from a dynamic source.

I'm trying to change the forecolor of specific cells in the control if the underlying data for that cell changes to specific conditions.

The control also gets drawn once before the condition starts being checked,meaning every cells starts painted with the same (white) forecolor.

Also, this listbox sits inside a Canvas, and that Canvas is in turn inside a Window control.

This code checks for the condition vs. all the rows in the listbox:

for each dict as Dictionary in WidgetsDictionary
  Dim site as String = dict.Value("Site").StringValue
  Dim device as String = dict.Value("Device").StringValue
  Dim sensor as String = dict.Value("Sensor").StringValue
  for intC as integer = 0 to actualLstBox.ListCount
    Dim siteComp as String = actualLstBox.Cell(intC,4) 
    Dim deviceComp as String = actualLstBox.Cell(intC,0) 
    Dim sensorComp as String = actualLstBox.Cell(intC,1) 
    if  actualLstBox.Cell(intC,4) = site    AND
        actualLstBox.Cell(intC,1) = sensor  AND
        actualLstBox.Cell(intC,0) = device then
      actualLstBox.CellTag(intC,2) = RGB(255, 192, 203) 
      exit For
    end
  next
next

Where WidgetsDictionary contains the conditions I need to check against.

And that works,if i check the CellTags after it runs I find them set correctly where they are supposed to be.

Now,if after that code i call

actualLstBox.Refresh()

Note: I know Refresh isn't optimal but I need it to fire as soon as possible

I see the code jumping to the CellBackgroundPaint event of the ListBox

There I have this

If (row<me.ListCount ) then
  If Me.CellTag(row, column ) <>nil Then
    g.ForeColor = me.CellTag(row,column)
    g.FillRect(0, 0, g.Width, g.Height)
  End If
end

And again, I see this code executing correctly.

So, I'd expect the list to be redrawn with the correct cells in the new color.

But nothing changes, I see the CellBackgroundPaint event fire after every refresh but the end result shown is always the default (white) colored cells.

I've tried calling, in order

  • InvalidateCell on the specific cell
  • Invalidate on the whole Listbox instead of Refresh (since you never know)
  • Refresh on the containing Canvas

After the first block of code,to no avail.

So now I'm at a loss on what to try next.

Edit

If i replace the event handler with

If (row mod 2) = 0 Then
  g.ForeColor = RGB(232,235,255) 
  g.FillRect 0, 0, g.Width, g.Height
End If

if column = 2 then
  g.ForeColor = RGB(255,253,208) 
  g.FillRect 0, 0, g.Width, g.Height
end

I get alternating colors for the rows and the whole 3rd column of a different colour.

So I guess the fact that I'm trying to repaint it after the first time it's shown is where the problem lies.

Community
  • 1
  • 1
Fenr_it
  • 73
  • 8

1 Answers1

2

You need to return true from the handler in order to tell Xojo that you already have do e the painting. Otherwise Xojo will do its own FillRect after yours.

Keep in mind that this will also override the selection coloring. Meaning that if the row is selected, your cell won't show that unless you either return false in that case or draw your own special bg color for that case.

Also, what you are talking about is the background color, not foreground color, it seems to me. You could perhaps update your question title accordingly.

Thomas Tempelmann
  • 11,045
  • 8
  • 74
  • 149
  • Already tried returning true,still no effect.Also,if i swap the code in the handler with a simpler one that just paints alternating rows of different colours,that works fine – Fenr_it Jun 11 '19 at 12:36
  • 1
    The fact that it works with directly set colors suggests that you have something wrong with your setting of the CellTag, not with the Redraw (nothing wrong with that) – Thomas Tempelmann Jun 11 '19 at 12:38
  • Guess i found the reason... I was setting the tags using RGB,and while the tags itself "gets" it right (i.e i see the correct color in the celltag property) seems that once i pass it to the paint object it doesnt get recognized. Throwing the hex value inside the tag seems to work as expected.Going to test some more to be sure – Fenr_it Jun 11 '19 at 12:47
  • Nope,spoken too soon. If the listbox gets painted once without colors,every subsequent refresh still does not update it. If by chance i get the conditions before the control gets drawn (=> so the check actually works) then it gets drawn as i would expect – Fenr_it Jun 11 '19 at 12:55
  • I suggest you make a small test project and make that available, e.g. on github, or at least post all the relevant code, not just parts of it, so that others can try out what you do and find the error. – Thomas Tempelmann Jun 11 '19 at 18:39
  • Sadly, with it being my first Xojo project and feature creep requests being a continuous thing, the code is tangled enough that identifying and taking out the relevant parts to a fiddle would take time i don't really have right now. Even if it's far from what i wanted i'll probably skip doing this part and come back to it later when i have more space to dedicate to it. Still,thanks for the help, it'll come handy when i'll review things – Fenr_it Jul 26 '19 at 10:52