Search code examples
listviewdelphidelphi-2009

How to change the group order in a TListGroups?


I have a TListView in vsReport style with groups visible. The groups are shown in the order in which they were created. But I want to make two buttons (up and down) and move the selected group on another position (at runtime). Is it possible ?


Solution

  • You can do this by changing the Index property of the group item. The following code demonstrates the usage:

    procedure TForm1.btnMoveUpClick(Sender: TObject);
    var
      itm: TListItem;
      i: Integer;
    begin
      itm := ListView1.Selected;
      if Assigned(itm) then
        for i := 0 to ListView1.Groups.Count - 1 do
          if ListView1.Groups[i].GroupID = itm.GroupID then
          begin
            if ListView1.Groups[i].Index > 0 then
              ListView1.Groups[i].Index := ListView1.Groups[i].Index - 1;
            break;
          end;
    end;
    
    procedure TForm1.btnMoveDownClick(Sender: TObject);
    var
      itm: TListItem;
      i: Integer;
    begin
      itm := ListView1.Selected;
      if Assigned(itm) then
        for i := 0 to ListView1.Groups.Count - 1 do
          if ListView1.Groups[i].GroupID = itm.GroupID then
          begin
            if ListView1.Groups[i].Index < ListView1.Groups.Count - 1 then
              ListView1.Groups[i].Index := ListView1.Groups[i].Index + 1;
            break;
          end;
    end;
    

    Footnote: Of course, this can (should) be refactored like this:

    function GetGroupFromGroupID(AListView: TListView; AGroupID: integer): TListGroup;
    var
      i: Integer;
    begin
      for i := 0 to AListView.Groups.Count - 1 do
        if AListView.Groups[i].GroupID = AGroupID then
          Exit(AListView.Groups[i]);
      result := nil;
    end;
    
    procedure TForm1.btnMoveUpClick(Sender: TObject);
    var
      itm: TListItem;
      grp: TListGroup;
    begin
      itm := ListView1.Selected;
      if Assigned(itm) then
      begin
        grp := GetGroupFromGroupID(ListView1, itm.GroupID);
        if Assigned(grp) and (grp.Index > 0) then
          grp.Index := grp.Index - 1;
      end;
    end;
    
    procedure TForm1.btnMoveDownClick(Sender: TObject);
    var
      itm: TListItem;
      grp: TListGroup;
    begin
      itm := ListView1.Selected;
      if Assigned(itm) then
      begin
        grp := GetGroupFromGroupID(ListView1, itm.GroupID);
        if Assigned(grp) and (grp.Index < ListView1.Groups.Count - 1) then
          grp.Index := grp.Index + 1;
      end;
    end;