TAdvStringGrid continuous update on GetCellColor

To reproduce (I'm using C++ Builder 10.2 with TMS component pack
1. Create new VCL Forms application.
2. Drop TAdvStringGrid on form.  Leave all properties at defaults.
3. Add the code below to OnGetCellColor event handler.
4. Run, then select two cells, one of each colour.
5. Grid starts to flicker due to continously updating.

Possibly there is a better way as the selected and non-selected colours are handled differently, but this was the only way I could get it to work.

    if (ARow > 0)
        int line_idx = ARow - 1;
        if (line_idx < 5)
            if (AState.Contains(gdSelected))
                AdvStringGrid1->SelectionColor = clWebLimeGreen;
                ABrush->Color = clWebPaleGreen;
            if (AState.Contains(gdSelected))
                AdvStringGrid1->SelectionColor = clWebSalmon;
                ABrush->Color = clWebLightSalmon;

The issue here is that you change the SelectionColor from the OnGetCellColor event. OnGetCellColor is triggered during the grid repaint but setting the grid.SelectionColor triggers a new repaint. As such, a loop is caused of repainting cause a flickering. Please do not use code that causes a repaint from a method like OnGetCellColor invoked during paint.

Ok but then how do I dynamically change the "selected" colour depending
on the content of the cells?  Changing the brush colour doesn't have any
effect on the colour of a selected cell.

You need to do this outside an event invoked by grid painting, for example the OnSelectionChanged event.

This doesn't work with multiselect, where I might want more than one selection colour.  For example I might have:
Row 1 - green
Row 2 - green
Row 3 - red
Row 4 - red
Now when I select rows 2 and 3, I want row 2 to be dark green and row 3 to be dark red to show the selection.
I see two solutions:
1. OnGetCellColor should override SelectionColor.  This seems reasonable since the event provides the selection state of the cell.
2. You could add a new event OnGetSelectedCellColor.

If you wish that the color defined in OnGetCellColor takes priority over the selection color, set

grid.SelectionColorMixer := true and grid.SelectionColorMixerFactor := 0;

1 Like

That works perfectly thank you.