Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting ListView Groups?

In a ListView, the Items are grouped by the groups "BGroup", "CGroup" and "DGroup" (These are the group headers). Now, when I add a new Item to the ListView and assign a new group with the header "AGroup" to this Item, the group "AGroup" is always inserted at the end of the groups; so the new Groups order is: BGroup, CGroup, DGroup, AGroup. So how can I get the groups sorted in correct alphabetical order? The order should be: AGroup, BGroup, CGroup, DGroup.

like image 391
user1580348 Avatar asked Feb 23 '13 14:02

user1580348


1 Answers

You can use the ListView_SortGroups macro for this e.g. This macro expects from you to have your own comparison function, defined by the LVGroupCompare function prototype. In the following code the groups are sorted by the Header property by using the CompareText function, but now it's upon you to build your own comparison.

Forgot to note; whatever you pass to the last Pointer type parameter of the ListView_SortGroups macro you'll receive in the LVGroupCompare function in the pvData parameter, so as this is going to be a group sorting function of a certain list view, it's the best to pass directly Groups collection of that list view for easier manipulation.

Since there is no direct way to find a list view group by group ID, I'd use the following helper function for the TListGroups class:

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;

Then you can use this helper method in the LVGroupCompare function callback this way:

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;
like image 136
TLama Avatar answered Oct 23 '22 06:10

TLama