如何在列表视图中省略空单元格的网格线?

发布于 2024-10-19 11:43:22 字数 182 浏览 7 评论 0原文

如何隐藏 TListView 控件中将空单元格与相邻单元格分隔开的网格线?它类似于 HTML colspan 表格属性,或 Excel 的“合并单元格”命令。我希望其中包含文本的单元格保留其正常边框。

示例

How can I hide the grid lines separating empty cells from the adjacent cells in a TListView control? It would be like the HTML colspan table attribute, or Excel's "merge cells" command. I would like for cells with text in them to retain their normal borders.

Example

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

递刀给你 2024-10-26 11:43:22

您可以使用 TVirtualStringTree。它有 AutoSpanColumns 选项,它将自动跨越空列。

You could use TVirtualStringTree. It has option toAutoSpanColumns which will automatically span empty columns.

眼眸里的那抹悲凉 2024-10-26 11:43:22

对于这个问题似乎不存在任何可靠的解决方案。

然而,一个糟糕的解决方案是

procedure TForm4.FormShow(Sender: TObject);
var
  i: integer;
begin
  ListView1.ViewStyle := vsReport;
  ListView1.Columns.Add.Caption := 'Col 1';
  ListView1.Columns.Add.Caption := 'Col 2';
  ListView1.Columns.Add.Caption := 'Col 3';
  ListView1.GridLines := false; // You cannot have grid lines...
  for i := 0 to 10 do
    with ListView1.Items.Add do
    begin
      if i <> 5 then
      begin
        Caption := 'Test';
        SubItems.Add('test');
        SubItems.Add('test');
      end
      else
        Caption := 'This is a very, very long caption';
    end;
end;

var
  ColWidths: array of integer;

procedure TForm4.ListView1AdvancedCustomDraw(Sender: TCustomListView;
  const ARect: TRect; Stage: TCustomDrawStage; var DefaultDraw: Boolean);
var
  i, j: Integer;
begin
  if Stage <> cdPrePaint then Exit;
  if length(ColWidths) <> TListView(Sender).Columns.Count then
  begin
    SetLength(ColWidths, TListView(Sender).Columns.Count);
    Exit;
  end;
  for i := 0 to length(ColWidths) - 1 do
    if ColWidths[i] <> Sender.Column[i].Width then
    begin
      Sender.Invalidate;
      for j := 0 to length(ColWidths) - 1 do
        ColWidths[i] := Sender.Column[i].Width;
    end;
end;

procedure TForm4.ListView1AdvancedCustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
  var DefaultDraw: Boolean);
var
  r: TRect;
begin
  DefaultDraw := (Item.SubItems.Count <> 0);
  if not DefaultDraw then
  begin
    FillRect(Sender.Canvas.Handle, Item.DisplayRect(drBounds), GetStockObject(WHITE_BRUSH));
    r := Item.DisplayRect(drBounds);
    DrawText(Sender.Canvas.Handle, Item.Caption, length(Item.Caption), r, DT_SINGLELINE or DT_LEFT or DT_VCENTER)
  end;
end;

Listview colspan is很难得到正确的。不要这样做。

这很糟糕,因为它不稳健。它会闪烁,有问题,而且很“hacky”。它在 Windows 的未来版本中可能无法正常工作。基本上,我认为 Windows 列表视图控件不应该执行类似 HTML 的 colspan 操作。

There seems not to exist any robust solution to this problem.

A bad solution, however, is

procedure TForm4.FormShow(Sender: TObject);
var
  i: integer;
begin
  ListView1.ViewStyle := vsReport;
  ListView1.Columns.Add.Caption := 'Col 1';
  ListView1.Columns.Add.Caption := 'Col 2';
  ListView1.Columns.Add.Caption := 'Col 3';
  ListView1.GridLines := false; // You cannot have grid lines...
  for i := 0 to 10 do
    with ListView1.Items.Add do
    begin
      if i <> 5 then
      begin
        Caption := 'Test';
        SubItems.Add('test');
        SubItems.Add('test');
      end
      else
        Caption := 'This is a very, very long caption';
    end;
end;

var
  ColWidths: array of integer;

procedure TForm4.ListView1AdvancedCustomDraw(Sender: TCustomListView;
  const ARect: TRect; Stage: TCustomDrawStage; var DefaultDraw: Boolean);
var
  i, j: Integer;
begin
  if Stage <> cdPrePaint then Exit;
  if length(ColWidths) <> TListView(Sender).Columns.Count then
  begin
    SetLength(ColWidths, TListView(Sender).Columns.Count);
    Exit;
  end;
  for i := 0 to length(ColWidths) - 1 do
    if ColWidths[i] <> Sender.Column[i].Width then
    begin
      Sender.Invalidate;
      for j := 0 to length(ColWidths) - 1 do
        ColWidths[i] := Sender.Column[i].Width;
    end;
end;

procedure TForm4.ListView1AdvancedCustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
  var DefaultDraw: Boolean);
var
  r: TRect;
begin
  DefaultDraw := (Item.SubItems.Count <> 0);
  if not DefaultDraw then
  begin
    FillRect(Sender.Canvas.Handle, Item.DisplayRect(drBounds), GetStockObject(WHITE_BRUSH));
    r := Item.DisplayRect(drBounds);
    DrawText(Sender.Canvas.Handle, Item.Caption, length(Item.Caption), r, DT_SINGLELINE or DT_LEFT or DT_VCENTER)
  end;
end;

Listview colspan is hard to get right. Don't do it.

This is bad because it is not robust. It flickers, it's buggy, and it is "hacky". It might not work well in future versions of Windows. Basically, the Windows list view control isn't supposed to do HTML-like colspan, I think.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文