德尔福:Canvas.FillRect在列表视图 [英] Delphi: Canvas.FillRect in List View

查看:382
本文介绍了德尔福:Canvas.FillRect在列表视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在列表视图的子项的文字我需要刷并填写一整排的变化:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆