如何为ListView.Item.Caption设置字体颜色、样式及背景色?
解决ListView子项自定义绘制不生效的问题
你的代码有两个核心问题导致自定义样式不生效,我来帮你修正并解释原因:
问题分析
- 字体样式拼写错误:你写的
[FsBOld]是无效枚举值,正确的应该是fsBold(小写开头,拼写准确),这个笔误会直接导致字体加粗效果不生效。 - 未阻止默认绘制+未手动绘制内容:仅仅设置Canvas属性后,系统会继续执行默认绘制流程,直接覆盖你做的样式设置。必须手动绘制背景和文本,并将
DefaultDraw设为False来跳过默认绘制逻辑。
修正后的代码
procedure TFMainForm.ListView1CustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean); var ItemRect: TRect; Text: string; begin // 阻止默认绘制,改用自定义逻辑控制显示 DefaultDraw := False; // 获取当前子项的准确显示区域 Sender.GetSubItemRect(Item.Index, SubItem, srBounds, ItemRect); // 根据子项索引设置样式并绘制内容 case SubItem of 0, 1: begin // 设置并填充背景色 Sender.Canvas.Brush.Color := clLime; Sender.Canvas.FillRect(ItemRect); // 设置字体样式 Sender.Canvas.Font.Color := clBlack; Sender.Canvas.Font.Style := [fsBold]; // SubItem=0对应列表项的Caption Text := Item.Caption; end; 2, 3, 4: begin // 保留ListView默认背景色(也可自行替换为其他颜色) Sender.Canvas.Brush.Color := Sender.Color; Sender.Canvas.FillRect(ItemRect); // 设置字体样式 Sender.Canvas.Font.Color := clBlack; Sender.Canvas.Font.Style := [fsBold]; // SubItem≥1对应SubItems数组,注意索引要减1(SubItems从0开始) Text := Item.SubItems[SubItem - 1]; end; end; // 绘制文本,保持和默认绘制一致的垂直居中效果 Sender.Canvas.TextOut( ItemRect.Left + 2, ItemRect.Top + (ItemRect.Bottom - ItemRect.Top - Sender.Canvas.TextHeight(Text)) div 2, Text ); end;
关键细节说明
DefaultDraw := False:这是核心操作,告诉ListView不要使用默认方式绘制当前子项,完全交由我们的代码控制显示效果。GetSubItemRect:准确获取每个子项的矩形区域,确保背景填充和文本绘制的位置完全匹配默认布局,避免错位。- 文本对齐处理:通过计算文本高度与矩形高度的差值,让文本在垂直方向上居中,和默认绘制的视觉效果保持一致。
- 注意OwnerDraw属性:确保你的ListView的
OwnerDraw属性设为False,CustomDraw系列事件仅在该属性关闭时生效;如果开启了OwnerDraw,需要改用OnDrawSubItem事件实现自定义绘制。
内容的提问来源于stack exchange,提问作者user9210291
相关产品推荐
相关产品推荐

