Custom picture handling in DBAdvGrid

due to migration from another grid component, I need the complete control of pictures shown in grid cells.
For the easiest example, here is the code for a column with a database field that can be "Y" or "N" and displays a specific bitmap for "Y" and "N", respectively.
Bitmaps are stored in an image list but in other cases they are a TBitMap.

procedure TfrmManage.dbadvgBaseCustomCellDraw(Sender: TObject;
  Canvas: TCanvas; ACol, ARow: Integer; AState: TGridDrawState; ARect: TRect;
  Printing: Boolean);
    if (ARow > 0) and (ACol = 3) then
    if ( dbadvgBase.Cells[ACol,ARow] = 'Y')
       then imglistBaseGrid.Draw(Canvas,ARect.Left+2,ARect.Top+2,0,True)
       else imglistBaseGrid.Draw(Canvas,ARect.Left+2,ARect.Top+2,2,True);

This works perfectly, but I need to hide the field value in the cell because is mixed in the graphics rendering with the picture taken from imglistBaseGrid.

If I simply change the value in GetDisplText:
procedure TfrmManage.dbadvgBaseGetDisplText(Sender: TObject; ACol,
  ARow: Integer; var Value: string);
    if (ARow > 0) and (ACol = 3) then
        Value := '';

In this case CustomCellDraw does not work due to change of cell value.

My question is: how to hide the cell Value but preserving the cell content ? Or, alternatively, is there a way to get the field value and not the cell displayed so I can change CustomCellDraw with field content instead of displayed value ?

Thanks in advance, regards

Try getting the value via


Hi Bruno,
GridCells is always empty.

I cannot see a reason why grid.GridCells[] would be empty.
On the other side, I also can't see a reason for custom handling this while TDBAdvGrid has this feature built-in and you can enable it without writing any code. It is demonstrated in the ADODataImage demo in the DBAdvGrid demos folder.

grid version is , hope this helps.
I tried the ADODataImage demo but with one error. If there are no alternatives, I will recode like ADODataImage and ask you about the error.

The latest version of DBAdvGrid is v2.4.0.2 and I retested the ADODataImage demo here with the latest version but I cannot see a problem.

Sorry but ADODataImage example works only for integer fields. I need to work with images that depends on character fields. I cannot modify the database.

That mechanism can still be used if you use a calculated field to bind to the column and return in the calculated field the index of the image to use for a given text value of a DB field.

Hello Bruno,
the example of the first post is simple, just to show you the problem. Complex applications can have data and pictures separated in external files and sometimes these cannot be included in a TImagelist due to different dimensions etc. . Also the logic behind can be very complex, especially in industrial applications.
For that reson I need to follow your first answer it seems the best solution for this application. Remember we are migrating from another grid and the changes should be at minimum. Approx. 60 grids will be affected.

Please provide me a solution for accessing the underlying field data information in a cell, with no care about what is displayed, thanks.
In the meantime I am starting to upgrade TMS library, just to check if GridCells[] had some bugs in my previous version.
Thanks for your support, it is very appreciated.

I confirm you the  dbadvgBase.GridCells[ACol,ARow] is always an empty string in CustomCellDraw method.
Grid version is now
Let me know how to retrieve the underlying cell data with no care about what is displayed on the grid, thanks in advance.

An alternative solution is to use a PictureContainer you add to the form and connect to grid.PictureContainer. Add your pictures to the PictureContainer with the name as used in the DB field and set grid.Columns[col].DataPictureField = true.
Bruno Fierens2016-11-03 20:19:37

Or you can also do it this way:

procedure TForm1.DBAdvGrid1CustomCellDraw(Sender: TObject; Canvas: TCanvas;
  ACol, ARow: Integer; AState: TGridDrawState; ARect: TRect; Printing: Boolean);
  if (acol = 5) and (arow > 0) then
    if odd(dbadvgrid1.Ints[acol,arow]) then
      Canvas.Brush.Color := clRed
      Canvas.Brush.Color := clGreen;

    Canvas.Rectangle(arect.Left + 2, arect.Top, arect.Left + 14, arect.Bottom);

procedure TForm1.DBAdvGrid1GetCellColor(Sender: TObject; ARow, ACol: Integer;
  AState: TGridDrawState; ABrush: TBrush; AFont: TFont);
  DBAdvGrid1.NoDefaultDraw := (acol = 5) and (arow > 0);

This will draw a colored rectangle in column 5 depending on a cell value and not display the cell value itself.

Thanks Bruno for the second workaround.
Of course arect.Left + 14 is not an elegant solution but it works in the meanwhile I need to manage one character.
As I asked in the official support communication, a way to obtain the underlying data in the cell will be a great enhance in flexibility , with no care about what is displayed. I guess it is a big miss in this great component.
Thanks !

Also the first suggestion works fine, thanks.