![]() |
ListView bzw. StringList sortieren...
Hi!
Dann werde ich mal austesten, ob ich hier geholfen bekomme :) Also, ich verwende folgenden Code in meinem Programm, mit dem ich eine ListView nach angeklickter Column sortiere (stört euch nicht an der Komponente SmartListView - ist eine einfache ListView Komponente, nur kann man damit schnell und einfach die Inhalte speichern):
Code:
Dann baue ich bei OnColumnClick folgenden Code ein, mit dem ich festlege, welche Column welche Art von Sortierung besitzen soll:
function CustomSortProc(Item1, Item2: TListItem; SortColumn: Integer): Integer; stdcall;
var s1, s2: string; i1, i2: Integer; r1, r2: Boolean; d1, d2: TDateTime; { Helper functions } function IsValidNumber(AString : string; var AInteger : Integer): Boolean; var Code: Integer; begin Val(AString, AInteger, Code); Result := (Code = 0); end; function IsValidDate(AString : string; var ADateTime : TDateTime): Boolean; begin Result := True; try ADateTime := StrToDateTime(AString); except ADateTime := 0; Result := False; end; end; function CompareDates(dt1, dt2: TDateTime): Integer; begin if (dt1 > dt2) then Result := 1 else if (dt1 = dt2) then Result := 0 else Result := -1; end; function CompareNumeric(AInt1, AInt2: Integer): Integer; begin if AInt1 > AInt2 then Result := 1 else if AInt1 = AInt2 then Result := 0 else Result := -1; end; begin Result := 0; if (Item1 = nil) or (Item2 = nil) then Exit; case SortColumn of -1 : { Compare Captions } begin s1 := Item1.Caption; s2 := Item2.Caption; end; else { Compare Subitems } begin s1 := ''; s2 := ''; { Check Range } if (SortColumn < Item1.SubItems.Count) then s1 := Item1.SubItems[SortColumn]; if (SortColumn < Item2.SubItems.Count) then s2 := Item2.SubItems[SortColumn] end; end; { Sort styles } case LvSortStyle of cssAlphaNum : Result := lstrcmp(PChar(s1), PChar(s2)); cssNumeric : begin r1 := IsValidNumber(s1, i1); r2 := IsValidNumber(s2, i2); Result := ord(r1 or r2); if Result <> 0 then Result := CompareNumeric(i1, i2); end; cssDateTime : begin r1 := IsValidDate(s1, d1); r2 := IsValidDate(s2, d2); Result := ord(r1 or r2); if Result <> 0 then Result := CompareDates(d1, d2); end; end; { Sort direction } if LvSortOrder[SortColumn + 1] then Result := - Result; end;
Code:
Mein Problem ist nun aber, dass ich parallel zu den Daten in der ListView noch Daten in einer StringList habe. Diese sollen natürlich mitsortiert werden, sonst werden die Daten ja durcheinander gewirbelt.
procedure TForm1.SmartListView1ColumnClick(Sender: TObject;
Column: TListColumn); begin if Column.Index = 1 then LvSortStyle := cssAlphaNum; if Column.Index = 2 then LvSortStyle := cssDateTime; if Column.Index = 3 then LvSortStyle := cssDateTime; if Column.Index = 4 then LvSortStyle := cssAlphaNum; if Column.Index = 5 then LvSortStyle := cssAlphaNum; SmartListView1.CustomSort(@CustomSortProc, Column.Index -1); end; Folgenden Code habe ich schon getestet, funktioniert aber nicht:
Code:
Ich bekomme dann einen Ausnahmefehler.
TerminList : TStringList;
begin TerminList.CustomSort(@CustomSortProc); end; Wäre echt nett, wenn mir jemand sagen könnte, worin mein Problem besteht. Gruß Yheeky |
Hallo Yheeky,
eine Antwort habe ich auch nicht, aber das:
Code:
Könnte man eleganter mit case lösen.
procedure TForm1.SmartListView1ColumnClick(Sender: TObject;
Column: TListColumn); begin if Column.Index = 1 then LvSortStyle := cssAlphaNum; if Column.Index = 2 then LvSortStyle := cssDateTime; if Column.Index = 3 then LvSortStyle := cssDateTime; if Column.Index = 4 then LvSortStyle := cssAlphaNum; if Column.Index = 5 then LvSortStyle := cssAlphaNum; SmartListView1.CustomSort(@CustomSortProc, Column.Index -1); end; |
Hi,
ich finde dein Text doch irgendwo extrem lang. Hier ist mal meiner.
Code:
Aufrufen dann damit:
procedure TForm1.ListViewsColumnClick(Sender: TObject;
Column: TListColumn); begin ColumnToSort:=Column.Index; (Sender as TCustomListView).AlphaSort; //ist extra so allgemein geschrieben end; procedure TForm1.ListViewsCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); var i:integer; begin if ColumnToSort = 0 then Compare:=CompareText(Item1.Caption,Item2.Caption) else begin i:=ColumnToSort -1; Compare:=CompareText(Item1.SubItems[i],Item2.SubItems[i]); end; end;
Code:
Statt dem Button1Click, kannst du eben auch dein ColumnClick nehmen
procedure TForm1.Button1Click(Sender: TObject);
begin ColumnToSort:=0; //Hier wird die Spalte angegeben, nachder Sortiert werden soll; 0 wäre also die erste/Caption ListViewKKLok.AlphaSort; end; Grüsse, Daniel :) |
@Daniel B:
Was Yheeky's Code so lang macht, ist wohl, dass er vorher noch verschiedene Dinge prüft usw., aber so genau habe ich mir seinen Code auch nicht angesehen, da das Sortieren des Lsutviews ja geht. Sein Problem ist, er hat auch noch ein Stringgrid, welches mit sortiert werden soll. |
Re: ListView bzw. StringList sortieren...
Zitat:
Vielleicht nicht die beste/schönste Lösung, aber auf jedenfall eine die gehen würde. :) Grüsse, Daniel :) |
Zitat:
Grüsse, Daniel :) |
Ups :oops:.
|
Das werde ich dir jetzt aber sehr übel nehmen. :twisted:
Grüsse, Daniel :) |
Moin Yheeky,
ich denke mal, dass Dein Problem nur darin besteht, dass Du für einen ListView und eine StringList nicht die gleiche CustomSortProc benutzen kannst. Für die StringList müsstest Du Dir halt eine angepasste Sortierroutine erstellen. Im Prinzip ähnelt eine CustomSortProc einer Callback Funktion. Hier ist der Name auch nur Platzhalter für die Prozedur/Funktion, die man erstellt. Die CustomSortProc kann also heissen wie auch immer man will, solange der Aufbau (Parameter, Rückgabewert) der Vorgabe entspricht. |
Zuerst mal Danke für die schnellen Antworten:
@Christian Seehase: Zitat:
@Daniel B. Zitat:
Gruß Yheeky |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz