【问题标题】:How can I change the background and font color of a selected item in list view?如何更改列表视图中选定项目的背景和字体颜色?
【发布时间】:2014-09-23 18:34:55
【问题描述】:

我尝试使用OnCustomDrawItem 事件更改颜色,但没有效果。

procedure TForm1.RListCustomDrawItem(Sender: TCustomListView; Item: TListItem;
 State: TCustomDrawState; var DefaultDraw: Boolean);
begin
 if cdsSelected in State then begin
  Sender.Canvas.Brush.Color:=clRed;
  Sender.Canvas.Font.Color:=clYellow;
 end;
end;

我使用带有 3 列的默认 TListView 组件,并将 ViewStyle 设置为 vsReport

【问题讨论】:

  • 您是否将 OwnerDraw 属性设置为 True ?
  • 我运行这段代码,我得到白色背景上的黄色文本。你看到了什么。
  • 我看到了 windows 默认颜色,好像CustomDraw 事件根本不存在。 (在 Delphi 2009 / Win7 / Windows Classic 主题中测试)
  • 您的应用是否有 comctl32 v6 清单?而且你有一个默认的列表视图。没有设置为非默认值的属性?除了ViewStyle 以外,假设是vsReport。我想我的目的是您应该确保我们运行的代码与您完全相同。 MCVE 会很好。
  • 我不知道什么是 comctl32 清单,但我搜索了我的计算机,发现 Windows 文件夹中有许多 comctl32-v5 文件(如果有帮助的话)。我使用默认的 TListView 组件(来自 Delphi 2009),其中 3 列 ViewStyle 设置为 vsReport

标签: delphi delphi-2009


【解决方案1】:

字体颜色仅适用于您的代码中显示的内容。 如果要更改背景颜色,则必须自己绘制项目和子项目并将 DefaultDraw 设置为 false。

这可能看起来像:

procedure TMyForm.ListView1CustomDrawItem(Sender: TCustomListView; Item: TListItem
                 ; State: TCustomDrawState; var DefaultDraw: Boolean);
var
  rt, r: TRect;
  s: String;
  i: Integer;
  c:TCanvas;

  // Fit the rect used for TextRect
  Procedure PrepareTextRect;
  begin
    rt := r;
    rt.Left := rt.Left + 5;
    rt.Top := rt.Top + 1;
  end;

begin
  c := Sender.Canvas;
  if (cdsSelected in State) then
  begin
    c.Brush.Color := clRed;
    c.Font.Color := clYellow;
    // will get the rect for Item + Subitems in ViewStyle = vsReport
    r := Item.DisplayRect(drBounds);
    c.FillRect(r);
    // set width to get fitting rt for tfEndEllipsis
    r.Right := r.Left + TListView(Sender).Columns[0].Width;
    s := Item.Caption;
    PrepareTextRect;
    c.TextRect(rt, s, [tfSingleLine, tfEndEllipsis]);

    if TListView(Sender).ViewStyle = vsReport then
    begin // Paint the Subitems if ViewStyle = vsReport
      for i := 0 to Item.SubItems.Count - 1 do
      begin
        r.Left := r.Left + TListView(Sender).Columns.Items[i].Width;
        r.Right := r.Left + TListView(Sender).Columns.Items[i + 1].Width;
        PrepareTextRect;
        s := Item.SubItems[i];
        c.TextRect(rt, s, [tfSingleLine, tfEndEllipsis]);
      end;
    end;
    DefaultDraw := false;
  end;
end;

【讨论】:

    【解决方案2】:

    如果您将 ViewStyle 设置为 vsList 则您已启动并运行。

    【讨论】:

    • -1 设置OwnerDraw 不是这里需要的。它与自定义绘制事件无关。我上面链接的文档说:指定列表视图是否接收 OnDrawItem 事件。将 OwnerDraw 设置为 True 并将 ViewStyle 设置为 vsReport 以允许列表视图接收 OnDrawItem 事件,而不是默认呈现列表项。注意:此属性独立于 OnCustomDraw、OnCustomDrawItem、OnAdvancedCustomDraw 和 OnAdvancedCustomDrawItem 事件。
    • 关于您的编辑。你已经完全改变了答案。最好删除第一个答案,然后添加一个新答案。整理选票。但提问者想使用 vsReport。
    • 关于您的评论@david 最好回答问题,而不是评论其他答案。如果你没有什么建设性的话,最好不要问。
    • 这是不正确的。您的两个答案都非常广泛,我可以发表评论。我的 cmets 旨在帮助您纠正错误。我的 cmets 很有建设性。
    猜你喜欢
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    相关资源
    最近更新 更多