How to color specific List View Item in Delphi? - delphi-xe5

I'm making a Scheduling System and I want to color some specific Items in the List View. For example, if the current time in the clock is 07:00 AM then the list view would color all the items that has 07:00 AM in it. How would I do this? I really don't know where to start. What i have right now is this,
View Schedule

You can set the font properties in OnCustomDrawItem and OnCustomDrawSubItem event handlers. For instance:
procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView; Item: TListItem;
State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if odd(Item.Index) then begin
Sender.Canvas.Font.Color := clRed;
end;
end;
procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView; Item: TListItem;
SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if odd(Item.Index) then begin
Sender.Canvas.Font.Color := clRed;
end;
end;

Related

Change font style only from the caption in a TListView in vsReport mode

I have 3 columns in a TListView in vsReport mode, with the Checkboxes property enabled. I'd like to make only the caption font bold when an item is checked. I tried using the OnCustomDrawItem event but it makes all the rows bold.
procedure TfrmMain.lvwCompsCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if (Item.Checked) then
Sender.Canvas.Font.Style := [fsBold]
else
Sender.Canvas.Font.Style := [];
end;
I cannot find in method OnCustomDrawItem how to isolate the first column (caption). So I also tried to use the OnCustomDrawSubItem event, to "remove" the bold style from the subitems, without success.
procedure TfrmMain.lvwCompsCustomDrawSubItem(Sender: TCustomListView;
Item: TListItem; SubItem: Integer; State: TCustomDrawState;
var DefaultDraw: Boolean);
begin
if (SubItem > 0) then
Sender.Canvas.Font.Style := [];
end;
Please, can someone help me?

listview and custom font color per item with delphi

I am trying to find a way so when I add an item to a TListView I can assign its own text color (by matching its name with a name I am entering into an edit box). I got it working, sort of, but the issue is when I add more then 2 items the font colors are changed for all of the items.
Here is my test code:
procedure TMainForm.ListCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if Edit2.Text = Item.Caption then // match my name with item name
begin
Sender.Canvas.Font.Color := Font.Font.Color; // assign from font dialogue
Sender.Canvas.Font.Style := Font.Font.Style; // assign from font dialogue
end;
end;
Does anyone have any ideas?
You are not resetting the ListView's Canvas.Font parameters for list items that do not match your text.
procedure TMainForm.ListCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if Edit2.Text = Item.Caption then
begin
Sender.Canvas.Font.Color := Font.Font.Color;
Sender.Canvas.Font.Style := Font.Font.Style;
end else begin
// add this...
Sender.Canvas.Font.Color := Sender.Font.Color;
Sender.Canvas.Font.Style := Sender.Font.Style;
end;
end;
That being said, if you know the colors you want to use ahead of time, a different way to set per-item colors is to derive a new class from TListItem and add your own Font property to it, then you can use that during drawing.
type
TMyListItem = class(TListItem)
private
fFont: TFont;
procedure FontChanged(Sender: TObject);
procedure SetFont(AValue: TFont);
public
constructor Create(AOwner: TListItems); override;
destructor Destroy; override;
property Font: TFont read fFont write SetFont;
end;
constructor TMyListItem.Create(AOwner: TListItems);
begin
inherited;
fFont := TFont.Create;
fFont.OnChange := FontChanged;
end;
destructor TMyListItem.Destroy;
begin
fFont.Free;
inherited;
end;
procedure TMyListItem.FontChanged(Sender: TObject);
begin
Update;
end;
procedure TMyListItem.SetFont(AValue: TFont);
begin
fFont.Assign(AValue);
end;
// OnCreateItemClass event handler
procedure TMainForm.ListCreateItemClass(Sender: TCustomListView; var ItemClass: TListItemClass);
begin
ItemClass := TMyListItem;
end;
procedure TMainForm.ListCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
Sender.Canvas.Font := TMyListItem(Item).Font;
end;
...
var
Item: TMyListItem;
begin
...
Item := TMyListItem(List.Items.Add);
Item.Caption := ...;
if Edit2.Text = Item.Caption then
Item.Font := Font.Font // assign from font dialogue
else
Item.Font := List.Font; // assign from listview
...
end;
if Edit2.Text = Item.Caption then // match my name with item name
begin
Sender.Canvas.Font.Color := Font.Font.Color; // assign from font dialogue
Sender.Canvas.Font.Style := Font.Font.Style; // assign from font dialogue
end;
The problem is what happens when the if condition is False. You don't specify font color and style, and so the state of the canvas remains what it was previously. You need to do the following:
For each item in the list you must remember that items color and style.
When ListCustomDrawItem is called you must specify the canvas color and style to the the value that you remembered in step 1.

Background Item list view - Delphi

I would like to know how to paint items Listview.
My situation is as follows:
I have a listview where every time you do a check and this check returns true, you have to change the listview line color. I saw examples by changing the color, but I cannot adapt to what I want.
procedure TForm1.OncustomDrawItem(Sender: TCustomListView; Item: TListItem;
State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if corlistview then Begin
LstbxDados.Canvas.Brush.Color:= RGB(0, 0, 0);
corlistview := false;
End;
end;
Procedure
var corlistview : boolean = false;
procedure carrega(t:String);
begin
if beginNada then begin
corlistview := true;
end;
LstbxDados.Items.BeginUpdate;
try
countX := countX +1;
with LstbxDados.Items.Add do begin
Caption := IntToStr(i+1);
Subitems.add(title);
Subitems.add(url);
end;
finally
LstbxDados.Items.EndUpdate;
end;
end;
How do I adapt the code for my situation?
Try this. I used random odd and even numbers for TListItem captions to emulate the function with boolean result that you have in your sample.
procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
var i:integer;
begin
i:= strtoint(Item.Caption);
if i mod 2 =0 then
begin
Sender.Canvas.Brush.Color:=clNavy;
Sender.Canvas.FillRect(Item.DisplayRect(TDisplayCode.drBounds));
end;
end;

Delphi ListView String in Bold

I am trying to get some text to appear in Bold.
Here is the code:
if (mfDeleted in flags) then
begin
//Font.Style:=[fsBold]; //This is just changing all to bold not just this row
s := s + 'Deleted,'; //I need this Deleted string or whole row to be bold.
end;
How can I do this?
Note: See comments in code
You need to handle OnAdvancedCustomDrawItem and OnAdvancedCustomDrawSubItem. Like this:
procedure TMyForm.ListViewAdvancedCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
var DefaultDraw: Boolean);
begin
Sender.Canvas.Font.Style := [fsBold];
end;
procedure TMyForm.ListViewAdvancedCustomDrawSubItem(Sender: TCustomListView;
Item: TListItem; SubItem: Integer; State: TCustomDrawState;
Stage: TCustomDrawStage; var DefaultDraw: Boolean);
begin
Sender.Canvas.Font.Style := [fsBold];
end;
Obviously you need to hook these event handlers up to the appropriate events. And you'll need to add some logic to ensure that you only do this for rows/columns that you intend to highlight.

Delphi: Paint Rows of ListView

I have a ListView (vsReport): the last SubItem has a text "wait". Then I will change it to "ok" or "error". How to paint a whole row (if to use Sender.Canvas.Brush.Color in CustomDrawItem it will be gaps between columns in Windows 7) with this SubItem in green (ok) and red (error)?
Thanks!
You can do
procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if Item.Index = Sender.Items.Count - 1 then
begin
Sender.Canvas.Brush.Color := clSkyBlue;
Sender.Canvas.FillRect(Item.DisplayRect(drBounds));
end;
end;
but I advice against it, because it is buggy (and I don't know how to fix it).

Resources