![]() |
2 Einträge in einem TListeView tauschen
Hallo alle zusammen!
Ich stelle gerade meine Delphi-Kenntnisse mächtig in Frage und hoffe das mir irgendjemand helfen kann! Folgendes Problem: Ich benutze ein TListView um meine Daten darzustellen. Die Reihenfolge der Items ist dabei für mich von großer Bedeutung. Nun wollte ich eine Funktionalität implementieren, bei der das aktuell gewählte Item auf Buttonclick eine Position nach oben "wandert" (sprich mit dem darüberstehenden seinen Platz tauscht) und habe mir gedacht, das sollte wie folgt fuinktionieren:
Delphi-Quellcode:
Leider führt dieser Quelltext nur dazu, dass mein gewähltes Elemnt immer nur das davor stehende Element überschreibt.
procedure TForm1.Button1Click(Sender: TObject);
var i: Integer; temp: TListItem; begin if (ListView1.SelCount > 0) then begin i := ListView1.Selected.Index; if (i > 0) then begin temp := ListView1.Items[i-1]); ListView1.Items[i-1] := ListView1.Items[i]; ListView1.Items[i] := temp; ListView1.Selected := ListView1.Items[i-1]; ListView1.Invalidate; end; end; end; MfG -jryan |
Re: 2 Einträge in einem TListeView tauschen
Hi,
schau Dir mal ![]() PS: temp erstmal erzeugen und dann wieder freigeben, nach dem Verschieben evtl. wieder Focus etc. korrekt setzen ;) Gruß Stephan |
Re: 2 Einträge in einem TListeView tauschen
Hi jryan,
du weißt der Variablen temp nicht das Element selbst zu, sondern nur den Pointer auf das Element. Nun überschreibst du das obere Element, und versuchst anschließend die Sicherungskopie zuzuweisen. Da diese aber weiterhin auf das (nun überschriebene) obere Element zeigt, wird der gleiche Wert nochmal zugewiesen. Du musst deshalb ein Element löschen und anschließend mit Insert eine Stelle höher wieder einfügen. Weiters: anstatt der zwei if-Abfragen kannst du auch eine verwenden:
Delphi-Quellcode:
Greetz
i := ListView1.ItemIndex;
if (i > 0) then ... alcaeus |
Re: 2 Einträge in einem TListeView tauschen
Danke für die Hinweise!
Jetzt habe ich erstmal eine Version die funktioniert:
Delphi-Quellcode:
Wobei ich natürlich sagen muß, sehr ellegant ist das auf den ersten Blick nicht, da man ja die Daten zweimal im Rechner hin- und herschaufelt und dafür zusätzlichen Speicher braucht.
procedure TForm1.Button1Click(Sender: TObject);
var i: Integer; temp: TListItem; begin i := ListView1.ItemIndex; if (i > 0) then begin try temp := TListItem.Create(ListView1.Items); temp.Assign(ListView1.Items[i-1]); ListView1.Items[i-1].Assign(ListView1.Items[i]); ListView1.Items[i].Assign(temp); ListView1.Selected := ListView1.Items[i-1]; finally temp.Free; end; ListView1.Invalidate; end; end; Gibt es eigentlich eine Alternative (Zeiger/Adressen) womit man das umgehen kann? (Ich hatte ja eigentlich bei meinen Ansatz gehofft, das er bei der ersten Zuweisung praktisch nur den Verweis auf das [i-1]. TListItem-Objekt in Temp speichert, bei der zweiten Zuweisung dann diesen Verweis aus [i-1] mit den Verweis auf [i] überschreibt und letzendlich dann den in temp gespeicherten Verweis auf das vormals [i-1] Objekt in [i] speichert. Habe dazu bei meiner Ausgangsversion auch schon mit ^ und @ rumgespielt, aber irgendwie ist es immer an Compilerfehlern gescheitert.) MfG -jryan |
Re: 2 Einträge in einem TListeView tauschen
Das kann so nicht klappen. Das Problem dabei ist, das der Index nicht vom Container sondern von den Elementen selber verwaltet wird. ISt ein wenig komplex, aber schau Dir vielleicht mal den Source von TList und TListItem an um Dir das zu gemüte zu führen.
Ich löse das so:
Delphi-Quellcode:
// exchange entries
// procedure TForm1.exchangeEntries(const i, j: integer); var l_Item: TListItem; begin // do not exchange if a item does not exist if not checkItems(i,j) then // hier wird nur geprüft ob die items i und j der liste auch assigned sind... exit; lstListView.Items.BeginUpdate; l_Item := TListItem.Create(lstListView.Items); try // store item l_Item.Assign(lstListView.Items.Item[i]); // exchange items lstListView.Items.Item[i].Assign( lstListView.Items.Item[j] ); lstListView.Items.Item[j].Assign( l_Item ); finally l_item.Free; lstListView.Items.EndUpdate end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:52 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