Delphi:调整 ListView 列大小时的错误(在 DrawItem 上)

标签 delphi listview resize draw

启用列的自动调整大小并为 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;

如果具有自动调整大小功能,则主动调整倒数第二列的大小。它是错误:

enter image description here enter image description here enter image description here enter image description here

如何防止这些错误?

谢谢!

最佳答案

该错误位于“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/

相关文章:

delphi - 如何在Windows Azure云平台上运行Delphi 6可执行文件(需要教程/示例)?

jquery - 动态添加列表项到 j-Query Mobile ListView

android - 使用异步任务加载图像时 Android ListView 中的奇怪行为

ios - 调整自定义 UITableViewCell 及其 subview 的大小

css - 将 Bootstrap 自定义为 960px 宽

delphi - 在单元从内存(终结部分)卸载之前不释放对象是否可以?

delphi - 在 FastReport 中创建数据集的分布图(钟形曲线)的最佳方法是什么?

delphi - 如何为 FireMonkey 组件添加设计时图标?

android - 如果对象是不同的数据类型,如何在 ArrayAdapter 列表的开头添加对象?

image - Sitecore 8 RTE 图像大小调整