对 ListView 分组进行排序?

5

在ListView中,Items按照"BGroup"、"CGroup"和"DGroup"分组(这些是组标题)。现在,当我向ListView添加一个新的Item并将一个新组与标题"AGroup"分配给该Item时,组"AGroup"总是插入到组的末尾;因此新组的顺序是:BGroup、CGroup、DGroup、AGroup。那么如何按正确的字母顺序对组进行排序呢?顺序应该是:AGroup、BGroup、CGroup、DGroup。

1个回答

8
您可以使用ListView_SortGroups宏来排序,此宏需要您自己定义一个比较函数,并通过LVGroupCompare函数原型进行定义。在下面的代码中,使用Header属性和CompareText函数对组进行排序,但现在您需要构建自己的比较函数。
注意:不管您将什么内容传递给ListView_SortGroups宏的最后一个Pointer类型参数,您都将在LVGroupCompare函数的pvData参数中接收到,因此,作为某个列表视图的组排序函数,最好直接传递该列表视图的Groups集合以便更容易地进行操作。
由于没有直接查找列表视图组ID的方法,因此我会使用以下辅助函数来处理TListGroups类:
type
  TListGroups = class(ComCtrls.TListGroups)
  public
    function FindItemByGroupID(GroupID: Integer): TListGroup;
  end;

implementation

function TListGroups.FindItemByGroupID(GroupID: Integer): TListGroup;
var
  I: Integer;
begin
  for I := 0 to Count - 1 do
  begin
    Result := Items[I];
    if Result.GroupID = GroupID then 
      Exit;
  end;
  Result := nil;
end;

然后,您可以在LVGroupCompare函数回调中使用此辅助方法:

function LVGroupCompare(Group1_ID, Group2_ID: Integer;
  pvData: Pointer): Integer; stdcall;
var
  Item1: TListGroup;
  Item2: TListGroup;
  Groups: TListGroups;
begin
  Result := 0;
  Groups := TListGroups(pvData);
  Item1 := Groups.FindItemByGroupID(Group1_ID);
  Item2 := Groups.FindItemByGroupID(Group2_ID);
  if Assigned(Item1) and Assigned(Item2) then
    Result := CompareText(Item1.Header, Item2.Header);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Item: TListItem;
  Group: TListGroup;
begin
  Group := ListView1.Groups.Add;
  Group.Header := 'AGroup';

  Item := ListView1.Items.Add;
  Item.Caption := 'Item X';
  Item.GroupID := Group.ID;

  ListView_SortGroups(ListView1.Handle, LVGroupCompare, ListView1.Groups);
end;

谢谢。然而,编译器在ListView_SortGroups这一行显示错误:E2009 不兼容的类型:'常规过程和方法指针但是当我在“the LVGroupCompare”之前添加“@”时:@LVGroupCompare,编译器在同一行显示错误:E2036 需要变量 - user1580348
我对你所做的事情感到很困惑。使用我发布的代码,如果调用ListView_SortGroups函数,则会(重复地)调用LVGroupCompare函数来比较两个现有项,即通过Group1_IDGroup2_ID参数传递的两个项。因此,我不相信你可以通过上述代码越界。 - TLama
我在自己的程序中使用了你的宏,希望它能"开箱即用",但显然它没有正常工作,所以我现在看到错误一定是出现在我的程序中。 我接受你的答案。当我找到要添加的内容时,我会写下评论。谢谢。 - user1580348
你写的代码是: ListView_SortGroups(ListView1.Handle, LVGroupCompare, ListView1.Groups); 没有在 LVGroupCompare 前面加上 @。 两种写法(带或不带 @)都可以编译通过。哪一种是正确的? - user1580348
1
抱歉,我犯了一个错误。我没有意识到TListView.Groups中的集合ID和列表视图组项的ID之间没有关系。请查看更新以进行修复... - TLama
显示剩余3条评论

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