I am trying to implement my own sorting feature for a Listbox. What I am wanting to do is, sort items within a listbox depending upon the chosen criteria, whether based on for example, criteria1,criteria2,criteria3... and so on.
I have these, lets call them randomObjects that act as records for the data. These random objects look like this:
type
randomObject = class(TObject)
ID,
criteria1,
criteria2,
criteria3:String;
end;
Here is the function I call when wanting to sort the randomObjects in the listbox:
procedure TmyForm.sortME(criteria: string; asc: Boolean);
var
tempList,pList:TStringList;
p:part;
i:integer;
item:TListBoxItem;
begin
tempList := TStringList.Create;
for p in AllRandomObjects do //allRandomObjects is an array of RandomObject
if criteria = 'Criteria1' then
tempList.Append(p.Criteria1)
else if criteria = 'Criteria2' then
tempList.Append(p.Criteria2)
else if criteria = 'Criteria3' then
tempList.Append(p.criteria3);
Plist:= TStringList.Create; //pList to keep track of original order to reference the RandomObjects
plist.Text := tempList.Text;
if asc then
tempList.Sorted:=true //create new order
else
tempList.CustomSort(StringListSortCompare); //create new order
listbox.BeginUpdate;
listbox.Items.Clear;
for i := 0 to tempList.Count-1 do
begin
p := AllRandomObjects[plist.IndexOf(tempList.Strings[i])];
Listbox.Items.Append('');
item := Listbox.ListItems[Listbox.Items.Count-1];
//blah-blah, create text objects to add to the item for displaying
end;
end;
listbox.EndUpdate;
end;
This takes very long however ( at least a few seconds, which seems like forever when on mobile ). Just learning, I'm sure there is a better/faster/more efficient way of doing this. Please help or give guidance!. Thanks! Developing for iOS, FMX Delphi xe6
You should sort the array itself with System.Generics.Collections.TArray.Sort
and iterate over the array to populate the data to the listbox.
uses
System.Generics.Collections,
System.Generics.Defaults,
System.StrUtils;
procedure TmyForm.sortME( criteria: string; asc: Boolean );
var
LCriteriaIndex : Integer;
LData : TList<randomObject>;
begin
LCriteriaIndex := IndexText( criteria, ['criteria1', 'criteria2', 'criteria3'] );
if LCriteriaIndex < 0 then
raise EArgumentException.Create( 'unknown criteria' );
LData := TList<randomObject>.Create( TComparer<randomObject>.Construct(
function( const L, R : randomObject ) : Integer
begin
case LCriteriaIndex of
0 :
Result := CompareText( L.criteria1, R.criteria1 );
1 :
Result := CompareText( L.criteria2, R.criteria2 );
2 :
Result := CompareText( L.criteria3, R.criteria3 );
end;
if not asc
then
Result := -Result;
end ) );
LData.AddRange( AllRandomObjects );
LData.Sort;
showData( LData.ToArray );
end;
procedure TmyForm.showData( AData : TArray<randomObject> );
var
LData : randomObject;
LItem : TListBoxItem;
begin
listbox.BeginUpdate;
try
listbox.Clear;
for LData in AData do
begin
LItem := TListBoxItem.Create( listbox );
//blah-blah, create text objects to add to the item for displaying
listbox.AddObject( LItem );
end;
finally
listbox.EndUpdate;
end;
end;