如何在TListView列上显示排序箭头?

6

在Windows资源管理器的报表视图中,有一个箭头指示列表视图按哪一列排序以及排序的方向(升序还是降序)。

在Delphi中,是否可以在TListView上显示这样的排序指示箭头?

2个回答

17

这是一些简单的代码,用于将标题列标记为按升序排序:

uses
  Winapi.CommCtrl;

var
  Header: HWND;
  Item: THDItem;
begin
  Header := ListView_GetHeader(ListView1.Handle);
  ZeroMemory(@Item, SizeOf(Item));
  Item.Mask := HDI_FORMAT;
  Header_GetItem(Header, 0, Item);
  Item.fmt := Item.fmt and not (HDF_SORTUP or HDF_SORTDOWN);//remove both flags
  Item.fmt := Item.fmt or HDF_SORTUP;//include the sort ascending flag
  Header_SetItem(Header, 0, Item);
end;

出于简洁起见,我已省略错误检查。如果你想让箭头指向相反方向,我相信你可以想办法交换逻辑。

关键的 MSDN 主题是针对 HDITEM 结构。


我在你的示例中添加了Winapi.CommCtrl使用条款,谢谢。 - Jens Mühlenhoff
有没有一种方法可以用于网格? - No'am Newman
1
@No Grids是自定义控件,完全由VCL代码实现。如果VCL没有提供这样的功能,则必须在您的代码中自定义绘图。 - David Heffernan
当ListView调整大小时,箭头会立即隐藏。 - user1580348

3
您可以轻松地扩展此代码,使其适用于ListView中的所有列;在Form的私有部分声明两个变量:

ColumnToSort:整数; Ascending:布尔值;

在FormCreate过程中将它们初始化为0和True。

procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: ListColumn);
var
  Header: HWND;
  Item: THDItem;
begin
  Header := ListView_GetHeader(ListView1.Handle);
  ZeroMemory(@Item, SizeOf(Item));
  Item.Mask := HDI_FORMAT;

  // Clear the previous arrow
  Header_GetItem(Header, ColumnToSort, Item);
  Item.fmt := Item.fmt and not (HDF_SORTUP or HDF_SORTDOWN);//remove both flags
  Header_SetItem(Header, ColumnToSort, Item);

  if Column.Index = ColumnToSort then
    Ascending := not Ascending
  else
    ColumnToSort := Column.Index;

  // Get the new column
  Header_GetItem(Header, ColumnToSort, Item);
  Item.fmt := Item.fmt and not (HDF_SORTUP or HDF_SORTDOWN);//remove both flags

  if Ascending then
    Item.fmt := Item.fmt or HDF_SORTUP//include the sort ascending flag
  else
    Item.fmt := Item.fmt or HDF_SORTDOWN;//include the sort descending flag
  Header_SetItem(Header, ColumnToSort, Item);

  with ListView1 do
    begin
      Items.BeginUpdate;
      AlphaSort;
      Items.EndUpdate;
    end;
end;

当然,您需要提供自己的OnCompare函数来实际排序列。此代码仅在单击的列标题中显示排序箭头。


欢迎来到stackoverflow。严格来说,这不是我的问题的答案。但我仍会点赞,因为你的回答很有用。 - Jens Mühlenhoff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接