Hallo allerseits.
Ich verwende eine ListView-Komponente zum Anzeigen der Daten von Personen in einer Tabelle (mit ViewStyle = vsReport). Diese Daten können auch nach den einzelnen Kategorien sortiert werden, indem man auf die Spalten-Header klickt (wenn man ein zweites Mal klickt, werden die Daten umgekehrt geordnet, wie auch im Windows-Explorer). Dabei kommt es aber zu zweierlei Problemen:
Zum einen tue ich mich schwer, bei einem Klick auf einen Tabelleneintrag darauf zu schließen, um welchen Eintrag es sich handelt. Denn "Selected.Index" richtet sich ja nach der Position des Eintrags in der Tabelle und das bringt mir nichts, weil durch das Sortieren theoretisch jeder Eintrag an jeder Position sein kann. Natürlich habe ich die Caption des jeweils ausgewählten Eintrages und könnte dann in dem Array, in dem die Daten gespeichert sind, nach der Person suchen, die diesen Namen hat, allerdings finde ich das sehr unschön, weil schließlich auch zwei Personen den selben Namen haben könnten (selbst wenn das in der Praxis praktisch nicht vorkommen sollte). Woher also kann ich wissen, um welchen Eintrag es sich bei dem ausgewählten handelt? Geht das vielleicht mit der "Data"-Eigenschaft der einzelnen Items, die auf eine Datenstruktur zeigen kann (die dann vielleicht die Kennnummern der Einträge enthält)?
Ein weiteres Problem habe ich beim Sortieren. Das normale Sortieren (beim ersten Klick auf einen Spalten-Header) funktioniert ohne Probleme, aber das umgekehrte Sortieren (beim zweiten Klick) nur zum Teil. Um das umzusetzen hab ich hier im Forum mal ein bisschen rumgesucht und bin fündig geworden, warum der Code bei mir nicht hunderprozentig funktioniert, ist mir jetzt aber nicht klar.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
| var Sortier_Spalte: Integer;
procedure TfoMain.lvSpielerlisteCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); var i: Integer; Wert1, Wert2: String; begin If Sortier_Spalte = 0 then Compare := CompareText(Item1.Caption,Item2.Caption) Else begin i := Sortier_Spalte - 1; If lvSpielerliste.Columns[i+1].Tag >= 1 then begin Wert1 := Item1.SubItems[i]; Wert2 := Item2.SubItems[i]; try Compare := StrToInt(Wert1) - StrToInt(Wert2); except Compare := 0; end; end Else Compare := CompareText(Item1.SubItems[i],Item2.SubItems[i]); end; If Sortierung_Invers = True then Compare := not Compare; end;
procedure TfoMain.lvSpielerlisteColumnClick(Sender: TObject; Column: TListColumn); begin If Sortier_Spalte <> column.Index then Sortierung_Invers := False Else Sortierung_Invers := not Sortierung_Invers; Sortier_Spalte := Column.Index; (Sender as TCustomListView).AlphaSort; end; |
Und so funktioniert der Code:
Ich habe zu Testzwecken einige Einträge mit den Nachnamen Ahrens, Becker, Mayer, Müller, Schmidt, Schneider und Werner eingefügt (Caption = Nachname). Beim normalen Sortieren sind sie genau in dieser Reihenfolge, wie es sein soll, wenn man ein zweites Mal auf den Spalten-Header klickt und damit "Sortierung_Invers" = True ist, sieht es jedoch so aus:
Werner, Schmidt, Schneider, Müller, Mayer, Ahrens, Becker
Wie man sieht ist das Ergebnis im großen und ganzen richtig, nur sind der 2. und 3. Wert sowie der vorletzte und letzte komischerweise vertauscht. Findet jemand den Fehler?