invalidateCell not working as expected

mac os 10.11.6

I wanted to know if CellPackgroundPaint still has a bug being called 100’s of times after a “invaliDateCell()” is used.
example here of a possible bug in the past.
https://forum.xojo.com/4901-invalidatecell-bug

When i was on 10.10.5 - the invalidateCell actually worked well, it would update only certain rows using (row, -1) as the manual states
after i upgraded recently to 10.11.6 the invalidateCell recolors all rows, even rows with no content.

here a screen shot of the issue
http://culser.com/ex/ScreenShot.png

Code for CellBackgroundPaint

[code]g.ForeColor = &cffffff

if ColorFlag = True Then
g.ForeColor = &ce6b6e7
//ColorFlag = False
else
end if

g.FillRect(0, 0, g.Width, g.Height)

return True[/code]

a note: if ColorFlag = False after setting the color, non of the rows get redrawn with the “pink color”

Code that calls the InvalidateCell

[code]Dim row As Integer

For row = 0 to CCList.ListCount - 1
if CCList.Cell(row, 3) = “*” then
ColorFlag = True
//CCList.Selected(row) = true
CCList.InvalidateCell(row, -1)
end if
Next row
[/code]

right now it is not working as expected
keep in mind this exact code was working under 10.10.5

please advise.

How about making ColorFlag a Pair in which you store the Row and Column you want colored?

Or if it really is “color all of the cells that contain a *” why not do that in the CellBackgroundPaint event and skip the flag altogether?

yep i did cut out the ColorFlag
in the CellBackgroundPaint i am comparing for the “*”
however it still does not work as expected , all rows get colored.

In the CellBackGroundPaint:

[code]
//don’t check a global , test what you actually want to check

if col = 3 and row < me.listcount and me.cell(row,col) = “*” then
g.ForeColor = &ce6b6e7
else
g.ForeColor = &cffffff
end if
g.FillRect(0, 0, g.Width, g.Height)

return True[/code]

And just invalidate the cells in a loop when you feel you need to .

[quote=468109:@Jeff Tullin]In the CellBackGroundPaint:

[code]
//don’t check a global , test what you actually want to check

if col = 3 and row < me.listcount and me.cell(row,col) = “*” then
[/code][/quote]

I was going to post something similar. But as I understand the OP code’s intent, it isn’t just column 3 that should be colored but any column in a row where column 3 has the “*”. So I think the comparable IF statement would be:

if row < me.listcount and me.cell(row,3) = "*" then

Jeff actually that does highlight only the cells associated with the “*”
however only column 3 cell is highlighted, not the full row.
according to the Xojo manual using InvalidateCell(row, -1) should redraw the full row.

please advise.

invalidateCell(row,-1) does in fact cause the whole row to be redrawn. But Jeff’s code only changes the ForeColor when the col = 3, so that is why only that row changes color. The other cells are redrawn, but with the &cffffff color. Replace his IF statement with what I posted, and the entire row will get highlighted in the pink color. Compare his IF to my own and if you don’t understand why, ask again.

Another thing to understand about why you have to determine the proper background color in the CellBackGroundPaint event instead of your original code: Invalidate… variants do not cause the requested cells to be redrawn immediately. It marks those cells to be redrawn on the next event loop, but the code with the Invalidate… continues executing. So the status of your ColorFlag variable at the time the actual CellBackgroundPaint event fires is not what you thought it was at that point in time. That is why your entire grid was changing color. The whole grid would have painted in the state you last left ColorFlag. Since your last row in the screenshot had a * in column 3, ColorFlag was left as True and when the next event cycle had time, CellBackgroundPaint was called on all the cells you had invalidated. Thus all cells redrew with pink.

I suspect that if you took the original code, and changed the last row’s column 3 to have + instead of *, that none of the rows would end up pink. Using Invalidate… is the most efficient way to do this – you had that part right. But what you misunderstood is the timing of changing ColorFlag and calling Invalidate… vs when the actual CellBackgroundPaint would execute.

Reread this a few times until you understand why you MUST determine the proper color INSIDE the CellBackgroundPaint event.

Jeff’s code does that, but only colors col 3 (due to his IF tests) whereas my variation of it will cause every column to test column 3 for * instead of its own cell contents. Thereby making all cells in that row get the pink color.

Hope that helps…

yep i understand it.
one call to me.InvalidateCell(row, -1) will cause the me.CellBackgroundPaint to fire as many times as there are columns for a given row.

and if i am further understanding me.InvalidateCell(row, 0) should cause me.CellBackgroundPaint to fire once for one cell ?

But it works great,

many thanks.