为什么ListView会忽略自定义绘图中的字体和画笔设置?

时间:2016-09-20 11:34:37

标签: listview delphi delphi-2010

我尝试使用自定义字体样式和背景颜色在listview中绘制项目。表单上有一个默认的列表视图。我已将ViewStyle更改为vsReport,将OwnerDraw更改为True。添加了3列和3个项目。并指定OnCustomDrawItem事件:

procedure TForm1.lv1CustomDrawItem(Sender: TCustomListView; Item: TListItem;
  State: TCustomDrawState; var DefaultDraw: Boolean);
var
  lvCanvas: TCanvas;
  R: TRect;
  S: string;
begin
  DefaultDraw := False;

  lvCanvas := Sender.Canvas;

  // column 1
  R := Item.DisplayRect(drBounds);
  R.Right := Sender.Column[0].Width;

  lvCanvas.Brush.Color := clRed;
  lvCanvas.Font.Style := [fsBold];
  S := 'Bold with red background';

  lvCanvas.FillRect(R);
  lvCanvas.TextRect(R, S, [tfSingleLine, tfEndEllipsis, tfCenter, tfVerticalCenter]);

  // column 2
  R.Left := R.Right;
  R.Right := R.Left + Sender.Column[1].Width;

  lvCanvas.Brush.Color := clGreen;
  lvCanvas.Font.Style := [fsItalic];
  S := 'Italic with green background';

  lvCanvas.FillRect(R);
  lvCanvas.TextRect(R, S, [tfSingleLine, tfEndEllipsis, tfCenter, tfVerticalCenter]);

  // column 3
  R.Left := R.Right;
  R.Right := R.Left + Sender.Column[2].Width;

  lvCanvas.Brush.Color := clBlue;
  lvCanvas.Font.Style := [fsUnderline];
  S := 'Underline with blue background';

  lvCanvas.FillRect(R);
  lvCanvas.TextRect(R, S, [tfSingleLine, tfEndEllipsis, tfCenter, tfVerticalCenter]);
end;

但结果并不像预期的那样:

enter image description here

第二列中的文字应为斜体,但不能为粗体且背景为绿色。 第三列中的文本应该是下划线,但不是粗体和蓝色背景。

  • 使用TextOut代替TextRect进行文字绘制会产生相同的结果。
  • 我试图在delphi-xe5中运行此测试项目,但结果是一样的。
  • 所有列中文本背景的颜色始终与第一列中的颜色相同。

任何人都可以向我解释发生了什么吗?

1 个答案:

答案 0 :(得分:1)

我尝试过同样的事情,事实上,它并没有奏效。画布没有你想要的。所以我试着使用一个自己的控制画布,希望它会做得更好,事实上,确实如此。 (我可能会在稍后发布一张图片。)

请尝试以下代码:

var
  lvCanvas: TCanvas;
  R: TRect;
  S: string;
begin
  DefaultDraw := False;

  lvCanvas := TControlCanvas.Create;

  { Try-finally-end is needed, because this Canvas is under our control. }
  try
    TControlCanvas(lvCanvas).Control := lv1;

    { ... Start of original drawing code ... }
    // column 1
    R := Item.DisplayRect(drBounds);

    { ... Drawing code is same as in question; snipped for brevity. ... }

    lvCanvas.TextRect(R, S, [tfSingleLine, tfEndEllipsis, tfCenter, tfVerticalCenter]);
    { ... End of original drawing code ... }

  finally
    lvCanvas.Free;
  end;
end;

这就是你想要做的。只有第一列显示粗体文本,第二列显示斜体文本等,第二列和第三列中没有红色背景。

更新

如副本所示,使用原始Sender.Canvas并在每次更改字体设置时执行lvCanvas.Refresh;,也可以。 TControlCanvas显然不需要这样做。因此,您可以使用TControlCanvas作为替代方案,尽管这会绑定更多资源。