Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi ListView Einträge und Objecte löschen (https://www.delphipraxis.net/94111-listview-eintraege-und-objecte-loeschen.html)

Chemiker 16. Jun 2007 12:37


ListView Einträge und Objecte löschen
 
Hallo,

ich möchte eigentlich nur von euch prüfen lassen, ob der Weg wie ich einzelne Einträge und Objecte aus einer ListView lösche, richtig ist.

Delphi-Quellcode:
{------------------------------------------------------------------------------}
procedure TFormMSEinrichten.LoeschenBitBtn4Click(Sender: TObject);
var i: integer;
begin
  // Aus der Liste einen Eintrag löschen.
  if MSAnzeigenListView.Selected <> NIL then
  begin
    // Löschen des angehängten Objectes und den Listen-Eintrag.
    TMSV1(MSAnzeigenListView.Selected.Data).Free; // Object Löschen
    MSAnzeigenListView.Selected.Data:= NIL;      // Zeiger in der List löschen
    MSAnzeigenListView.Selected.Delete;          // Listeneintrag löschen
  end;
end;
{------------------------------------------------------------------------------}
Und nun die Procedure, wenn das Form geschlossen wird.

Delphi-Quellcode:
{------------------------------------------------------------------------------}
procedure TFormMSEinrichten.FormDestroy(Sender: TObject);
var i: integer;
begin
  // Speicher aufräumen
  for i := MSAnzeigenListView.Items.Count-1 downto 0 do
  begin
    TMSV1(MSAnzeigenListView.items[i].Data).free; // Alle Objecte löschen
    MSAnzeigenListView.items[i].Data:= NIL;       // Zeiger der Liste Löschen
    MSAnzeigenListView.items[i].Delete;           // Einträge Löschen.
  end;
end;
{------------------------------------------------------------------------------}
Bis bald Chemiker

marabu 16. Jun 2007 13:42

Re: ListView Einträge und Objecte löschen
 
Hallo Chemiker,

wenn du die Ereignisse OnDeletion() und OnInsert() der ListView benutzt um eine Referenz an den Universal-Pointer Data eines Items zu binden, dann wird dein Code klarer strukturiert.

Zur Verdeutlichung des Prinzips:

Delphi-Quellcode:
procedure TDemoForm.ListViewDeletion(Sender: TObject; Item: TListItem);
begin
  with Item do
    TObject(Data).Free;
end;

procedure TDemoForm.DeleteItemActionExecute(Sender: TObject);
begin
  ListView.DeleteSelected;
end;

procedure TDemoForm.DeleteItemActionUpdate(Sender: TObject);
begin
  with Sender as TAction do
    Enabled := Assigned(ListView.Selected);
end;
Dabei bitte nicht übersehen, dass ich die eigentliche Aktion in eine TAction ausgelagert habe.

Grüße vom marabu

Sharky 17. Jun 2007 06:02

Re: ListView Einträge und Objecte löschen
 
Hai,

eventuell sollte man vor dem .Free mit Delphi-Referenz durchsuchenAssigned noch prüfen ob wirklich ein Object an den Eintrag gebunden ist.

Chemiker 17. Jun 2007 11:21

Re: ListView Einträge und Objecte löschen
 
Hallo marabu u. Sharky,

vorab danke für die Tipps.

@marabu mit dem Auslagern der Aktion in eine TAction habe ich noch nicht ganz verstanden. Muss mir das noch mal genauer in der Hilfe ansehen.

Ich habe nun die beiden Tipps aufgenommen und die Proceduren noch einmal neu geschrieben bzw. geändert.

Vielleicht könnt Ihr noch mal ein kritischer Blick draufwerfen, ob es so nun in Ordnung ist.

Die Einträge werden einzeln gelöscht:
Delphi-Quellcode:
{------------------------------------------------------------------------------}
procedure TFormMSEinrichten.LoeschenBitBtn4Click(Sender: TObject);
begin
  // Aus der Liste einen Eintrag löschen.
  if MSAnzeigenListView.Selected <> NIL then
  begin
    // Löschen des angehängten Objectes und den Listen-Eintrag.
//    TMSV1(MSAnzeigenListView.Selected.Data).Free; // Object Löschen
//    MSAnzeigenListView.Selected.Data:= NIL;      // Zeiger in der List löschen
    MSAnzeigenListView.Selected.Delete;          // Listeneintrag löschen
  end;
end;
{------------------------------------------------------------------------------}
Das Formular wird geschlossen.

Delphi-Quellcode:
procedure TFormMSEinrichten.FormDestroy(Sender: TObject);
var i: integer;
begin
  // Speicher aufräumen
  for i := MSAnzeigenListView.Items.Count-1 downto 0 do
  begin
//    TMSV1(MSAnzeigenListView.items[i].Data).free; // Alle Objecte löschen
//    MSAnzeigenListView.items[i].Data:= NIL;       // Zeiger der Liste Löschen
    MSAnzeigenListView.items[i].Delete;           // Einträge Löschen.
  end;
end;
Hier wird nun das Object gelöscht und der Speicher wieder freigeben.

Delphi-Quellcode:
{-------------------------------------------------------------------------------
Procedure: TFormMSEinrichten.MSAnzeigenListViewDeletion(Sender: TObject;
Function: Die Procedure wird von Delete angesprungen, kurz bevor der Eintrag
           aus der Liste gelöscht wird.
           Hier wird geprüft ob das Object auf NIL zeigt, ist das nicht der Fall
           so wird das Object gelöscht und der Speicher wieder freigeben.
           Anschliessend wird der Zeiger gelöscht.
Parameter: Item  //Ist der Eintrag der gerade gelöscht werden soll.
letz.Änd.: 17.06.2007
-------------------------------------------------------------------------------}
procedure TFormMSEinrichten.MSAnzeigenListViewDeletion(Sender: TObject;
  Item: TListItem);
begin
  If Assigned(Item.Data) then  // Prüfen ob das Objcet <> NIL ist
  begin
    TMSV1(Item.Data).Free;     // Object löschen u. Speicher wieder freigeben
    Item.Data:= NIL;           // Zeiger löschen
  end;
end;
{------------------------------------------------------------------------------}
Bis bald Chemiker

marabu 17. Jun 2007 12:13

Re: ListView Einträge und Objecte löschen
 
Hallo Chemiker,

deine Ereignisbehandlungsroutine FormDestroy() ist absolut überflüssig, solange die Form der Eigentümer der ListView ist. Entferne einfach den Code und setze einen Haltepunkt in ListViewDeletion(). Du wirst bemerken, dass das Ereignis OnDeletion() für jedes ListItem gefeuert wird, wenn die Form zerstört wird. Die Prüfung auf Assigned(Item.Data) macht nur Sinn, wenn überhaupt Items existieren können, mit denen keine Objekte verknüpft wurden. Andernfalls spricht man vom Gürtel-und-Hosenträger-Syndrom. Das Zurücksetzen von Item.Data zeigt mir deinen Sinn für Ordnung, ist aber an dieser Stelle ebenfalls überflüssig, da das Item ja gerade zerstört wird.

Zum Arbeiten mit Actions hat Sharky in diesem Thread etwas hilfreiches gepostet.

Freundliche Grüße

Muetze1 17. Jun 2007 12:41

Re: ListView Einträge und Objecte löschen
 
Zitat:

Zitat von Sharky
eventuell sollte man vor dem .Free mit Delphi-Referenz durchsuchenAssigned noch prüfen ob wirklich ein Object an den Eintrag gebunden ist.

Kann man sich sparen, da .Free dies intern schon macht.

Chemiker 17. Jun 2007 13:59

Re: ListView Einträge und Objecte löschen
 
Hallo marabu u. Muetze1,

ich habe das Assigned wieder herausgenommen, ist eigentlich auch klar dass es für das Programm nicht erforderlich ist, denn wenn kein Object vorhanden wäre, liegt schon ein Fehler bei der Eingabe vor.
@marabu
Habe das ganze mit den Haltepunkt durchgeführt und kann Deine Angaben bestätigen, beim zerstören der Formulars wird für jeden Item-Eintrag die Procedure OnDeletion aufgerufen,
damit ist es nicht mehr erforderlich, das Ganze noch mal durchzuführen. Habe also die Procedure: FormDestroy gelöscht.

Wenn das so weiter geht, ist von meinem Quelltext bald nicht mehr übrig und das Programm funktioniert besser als zuvor.

Einzelne Einträge löschen:

Delphi-Quellcode:
procedure TFormMSEinrichten.LoeschenBitBtn4Click(Sender: TObject);
begin
  // Aus der Liste einen Eintrag löschen.
  if MSAnzeigenListView.Selected <> NIL then
  begin
    MSAnzeigenListView.Selected.Delete;          // Listeneintrag löschen
  end;
end;
Object wieder löschen und Speicher wieder freigeben:
Delphi-Quellcode:
{-------------------------------------------------------------------------------
Procedure: TFormMSEinrichten.MSAnzeigenListViewDeletion(Sender: TObject;
Function: Die Procedure wird von Delete angesprungen, kurz bevor der Eintrag
           aus der Liste gelöscht wird.
           Wenn das Form zerstört wird, wird die Routine für jeden Eintrag ange-
           sprungen und das Object gelöscht und der Speicher wieder freigeben.
Parameter: Item  //Ist der Eintrag der gerade gelöscht werden soll.
letz.Änd.: 17.06.2007  // 14:00
-------------------------------------------------------------------------------}
procedure TFormMSEinrichten.MSAnzeigenListViewDeletion(Sender: TObject;
  Item: TListItem);
begin
  TMSV1(Item.Data).Free;     // Object löschen u. Speicher wieder freigeben
end;
{------------------------------------------------------------------------------}
TAction:
Das Demo von Sharky kann ich leider jetzt nicht herunterladen, weil die Sicherheitseinstellung dies nicht erlauben. Muss ich mir später auf einem anderen Computer ansehen.


Bis bald Chemiker


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:43 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