启用列的自动调整大小并为 ListView 启用OwnerDraw。然后在下面添加代码from HERE :
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 := clWhite;
Sender.Canvas.Brush.Color := clGreen;
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;
if odSelected in State then // NEW!
begin // NEW!
Sender.Canvas.Font.Color := clWhite; // NEW!
Sender.Canvas.Brush.Color := clNavy; // NEW!
end; // NEW!
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;
if odFocused in State then // NEW!
DrawFocusRect(Sender.Canvas.Handle, Rect); // NEW!
end;
如果具有自动调整大小功能,则主动调整倒数第二列的大小。它是错误:
如何防止这些错误?
谢谢!
最佳答案
该错误位于“comctrls.pas”的 TListColumn.GetWidth
中。当设置列上的“AutoSize”时,VCL 在调整列大小时检索错误的列宽,因此您在整个列上绘制项目文本。
我看了几分钟 VCL 代码,无法弄清楚出了什么问题,但在 getter 中设置值就足够可疑了。
无论如何,为了解决方法,而不是
inc(x2, ListView1.Columns[i].Width);
使用这个:
inc(x2, ListView_GetColumnWidth(ListView1.Handle, ListView1.Columns[i].Index));
关于Delphi:调整 ListView 列大小时的错误(在 DrawItem 上),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6630354/