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

为什么ListView会忽略自定义图形中的字体和笔刷设置?,listview,delphi,delphi-2010,Listview,Delphi,Delphi 2010,我正在尝试使用自定义字体样式和背景色在listview中绘制项目。表单上有一个默认的listview。我已将ViewStyle更改为vsReport,OwnerDraw更改为True。添加了3列和3项。并分配OnCustomDrawItem事件: procedure TForm1.lv1CustomDrawItem(Sender: TCustomListView; Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boole

我正在尝试使用自定义字体样式和背景色在listview中绘制项目。表单上有一个默认的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;

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

第二列中的文本应为斜体,但不应为粗体,并带有绿色背景。 第三列中的文本应加下划线,但不能加粗,并带有蓝色背景

  • 使用
    TextOut
    而不是
    TextRect
    进行文本绘制会得到相同的结果
  • 我曾尝试在delphi-xe5中运行这个测试项目,但结果是一样的
  • 所有列中文本背景的颜色始终与第一列中的颜色相同

有谁能解释一下发生了什么事吗?

我也试过,但确实不起作用。画布不是你想要的。因此,我尝试使用自己的控件画布,希望它能做得更好,事实上,它确实做到了。(我以后可能会贴一张照片)

请尝试以下代码:

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
作为替代方案,尽管这会绑定更多的资源。

标记的dupe提供了答案。我没有看到有dupe。我当时正忙着试代码@J无论如何,使用
TControlCanvas
是另一种选择,尤其是对于更复杂的设置。