I would like to draw an icon/bmp into a subitem of a TListView using delphi. But I don't know how to accomplish that. It works fine for the first item on the list, but having problems with the subitems.
Use a TImageList component to hold your images, assign it to the listviews's SmallImages property and set subitem's ImageIndex.
You could use the CustomDrawSubItem event.
The example below ignores the text and draws rectangles. Unfortunately it is a bit of a hassle to get the rectangle for the right column, but this approach works:
procedure TForm.ListViewCustomDrawSubItem(Sender: TCustomListView;
Item: TListItem; SubItem: Integer; State: TCustomDrawState;
var DefaultDraw: Boolean);
var
r : TRect;
i : Integer;
begin
r := Item.DisplayRect(drBounds);
for i := 0 to SubItem-1 do begin
r.Left := r.Left + ListView.Columns.Items[i].Width;
r.Right := r.Left + ListView.Columns.Items[i+1].Width;
end;
case SubItem of
1 : ListView.Canvas.Pen.Color := clRed;
else
ListView.Canvas.Pen.Color := clBlue;
end;
ListView.Canvas.Rectangle(r.Left, r.Top, r.Right, r.Bottom);
DefaultDraw := False;
end;
After tried Gamecat proposed solution, there are serious issues handling the redraw event after resizing the component, so at the end I came up with 2 possible workarounds:
1) Since subitems are Strings I handled to change the Font Family and using Wingdings I used a triangle-like character, then I just changed the font color to make it look like a glyph. (I know, it is not very clean, but it worked for me from a time and effort perspective)
2) Use a TDataGrid from the beginning, it knows the concept of cells and we can add practically anything and no need to worry with redrawing events. (Useless for me, cause the existing component already had a lot of functionality build on it).