德尔福:Canvas.FillRect在列表视图 [英] Delphi: Canvas.FillRect in List View
问题描述
在列表视图的子项的文字我需要刷并填写一整排的变化:
On change of a text of List View's SubItem I need to brush and fill a whole row:
procedure TForm1.ListViewDrawItem(Sender: TCustomListView;
Item: TListItem; Rect: TRect; State: TOwnerDrawState);
begin
if Item.SubItems[2]='Done'
then
begin
Sender.Canvas.Font.Color := clBlack;
Sender.Canvas.Brush.Color := clGreen;
Sender.Canvas.Brush.Style := bsSolid;
Sender.Canvas.FillRect(Rect);
end;
end;
但Sender.Canvas。 FillRect(矩形)将填补只子项的矩形。如何填写一整排?
But Sender.Canvas.FillRect(Rect) will fill only a Rect of the SubItem. How to fill a whole row?
现在的问题是问<一一个底座上href=\"http://stackoverflow.com/questions/6612797/delphi-how-to-draw-small-icons-in-list-view-on-customdrawitem/6612851#6612851\">Delphi:如何绘制在列表视图小图标上CustomDrawItem
谢谢!
推荐答案
首先,如果你有三列,它们是标题
,子项目[ 0]
和子项目[1]
,还记得吗?没有子项[2]
!
First, if you have three columns, they are Caption
, SubItems[0]
, and SubItems[1]
, remember? There is no SubItems[2]
!
总之,这是很容易的。你只需要老code的一个非常非常小的修改。
Anyhow, this is very easy. You only need a very, very small modification of the old code.
procedure TForm1.ListView1DrawItem(Sender: TCustomListView; Item: TListItem;
Rect: TRect; State: TOwnerDrawState);
var
i: Integer;
x1, x2: integer;
r: TRect;
S: string;
const
DT_ALIGN: array[TAlignment] of integer = (DT_LEFT, DT_RIGHT, DT_CENTER);
begin
if SameText(Item.SubItems[1], 'done') then
begin
Sender.Canvas.Font.Color := clBlack;
Sender.Canvas.Brush.Color := clLime;
end
else
if Odd(Item.Index) then
begin
Sender.Canvas.Font.Color := clBlack;
Sender.Canvas.Brush.Color := $F6F6F6;
end
else
begin
Sender.Canvas.Font.Color := clBlack;
Sender.Canvas.Brush.Color := clWhite;
end;
Sender.Canvas.Brush.Style := bsSolid;
Sender.Canvas.FillRect(Rect);
x1 := 0;
x2 := 0;
r := Rect;
Sender.Canvas.Brush.Style := bsClear;
Sender.Canvas.Draw(3, r.Top + (r.Bottom - r.Top - bm.Height) div 2, bm);
for i := 0 to ListView1.Columns.Count - 1 do
begin
inc(x2, ListView1.Columns[i].Width);
r.Left := x1;
r.Right := x2;
if i = 0 then
begin
S := Item.Caption;
r.Left := bm.Width + 6;
end
else
S := Item.SubItems[i - 1];
DrawText(Sender.Canvas.Handle,
S,
length(S),
r,
DT_SINGLELINE or DT_ALIGN[ListView1.Columns[i].Alignment] or
DT_VCENTER or DT_END_ELLIPSIS);
x1 := x2;
end;
end;
特别注意,我用 clLime
而不是 clGreen
,因为 clBlack
在 clGreen
背景文字看起来可怕!你可能会考虑 clWhite
在 clGreen
背景文字,虽然:
Notice in particular that I use clLime
instead of clGreen
, because clBlack
text on a clGreen
background looks horrible! You might consider clWhite
text on a clGreen
background, though:
更新回应评论:
要更改列表视图的第三列,它不这样做只是做
To change the third column of the list view, it doesn't do to just do
procedure TForm1.FormClick(Sender: TObject);
begin
ListView1.Items[3].SubItems[1] := 'Done';
end;
事实上,Windows不知道,一列的数据会影响整个行的外观! 最简单的解决方法是告诉Windows重绘整个控制时,你已经改变了价值线更好的:只是告诉Windows重绘当前行:
Indeed, Windows doesn't know that the data of one column affects the appearance of the entire row! The simplest fix is to tell Windows to repaint the entire control when you have changed the value Better: just tell Windows to redraw the current row:
procedure TForm1.FormClick(Sender: TObject);
begin
ListView1.Items[3].SubItems[1] := 'Done';
ListView1.Items[3].Update;
end;
这篇关于德尔福:Canvas.FillRect在列表视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!