Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Ein Object in TObjectList<T> löschen mit Ereignis (https://www.delphipraxis.net/171341-ein-object-tobjectlist-t-loeschen-mit-ereignis.html)

Sir Rufo 1. Nov 2012 21:29

AW: Ein Object in TObjectList<T> löschen mit Ereignis
 
Zitat:

Zitat von RWarnecke (Beitrag 1189422)
Zitat:

Zitat von Sir Rufo (Beitrag 1189421)
Es ist sehr schön, wenn er dem Objekt Events zuweist, aber was hat das mit der Liste zu tun?

TDegree ist ein einfaches Objekt und befindet sich nachher in der Liste, ist aber nicht die Liste selber ;)

EDIT:

Im Beitrag #7 da hat er ein schönes Bild angehängt, wo man auch sehr schön sehen kann, das FOnDelete den Wert nil hat :)

Ich glaube jetzt habe ich es verstanden. Korrigiere mich, wenn ich falsch liege. Das OnChange funktioniert deshalb, weil die Methode von OnChange nur das Objekt ändert und nicht die Liste. Mein OnDelete ändert aber meine Liste und deshalb muss meine Methode für OnDelete expliziet der ObjectList zugewiesen werden. Richtig oder falsch ?

Da wir hier - du ausgenommen - nicht wissen, was sich hinter den Methoden verbirgt, geschweige denn was du vorhast, kann ich diese Frage nicht beantworten.

Aber evtl. hilft dir folgendes:

Wenn du möchtest, dass ich das Fenster schließe, dann musst du mir das sagen und nicht Erna Rübenkohl aus Recklinghausen, auch wenn die mal ein Foto von mir gesehen hat.

DeddyH 2. Nov 2012 07:04

AW: Ein Object in TObjectList<T> löschen mit Ereignis
 
Zitat:

Zitat von Sir Rufo (Beitrag 1189436)
Wenn du möchtest, dass ich das Fenster schließe, dann musst du mir das sagen und nicht Erna Rübenkohl aus Recklinghausen, auch wenn die mal ein Foto von mir gesehen hat.

Das wird die arme Erna aber traurig machen :lol:

RWarnecke 2. Nov 2012 07:15

AW: Ein Object in TObjectList<T> löschen mit Ereignis
 
Das OnChange soll dann ausgeführt werden, wenn ein Objekt hinzugefügt oder geändert wird. Das OnDelete soll dann ausgeführt werden, wenn ein Object aus der ObjectList gelöscht wird.

Sir Rufo 2. Nov 2012 07:49

AW: Ein Object in TObjectList<T> löschen mit Ereignis
 
Zitat:

Zitat von RWarnecke (Beitrag 1189455)
Das OnChange soll dann ausgeführt werden, wenn ein Objekt hinzugefügt oder geändert wird. Das OnDelete soll dann ausgeführt werden, wenn ein Object aus der ObjectList gelöscht wird.

Beide Klassen haben die Eigenschaft OnDelete und OnChange. Deine Erklärung ist da nicht präzise, von welcher Klasse du jetzt das OnDelete/OnChange meinst.

Das ist auch der Grund warum es nicht so funktioniert, wie du das erwartest. ;)

Jonas Shinaniganz 2. Nov 2012 08:30

AW: Ein Object in TObjectList<T> löschen mit Ereignis
 
Zitat:

Das OnDelete soll dann ausgeführt werden, wenn ein Object aus der ObjectList gelöscht wird.
Delphi-Quellcode:
TListe = class (TObjectList<TForm1>)
public
  procedure Delete(Index: Integer); overload;
end;

procedure TListe.Delete(Index: Integer);
begin
  inherited Delete(Index);
  ShowMessage('es wurde was gelöscht'); // oder OnDelete ??
end;
Delphi-Quellcode:
  Liste := TListe.Create;
  Liste.Add(Form1);
  Liste.Delete(0); // Es wurde was gelöscht

So hab Ich es jetzt verstanden... Also jetzt meldet die Liste was

Sir Rufo 2. Nov 2012 08:39

AW: Ein Object in TObjectList<T> löschen mit Ereignis
 
Zitat:

Zitat von Jonas Shinaniganz (Beitrag 1189459)
Zitat:

Das OnDelete soll dann ausgeführt werden, wenn ein Object aus der ObjectList gelöscht wird.
[...]
So hab Ich es jetzt verstanden... Also jetzt meldet die Liste was

Es ist aber nicht eindeutig, da sowohl TDegree und TCustomObjectList OnDelete haben. Ja welches denn jetzt?

Zumal die Begrifflichkeiten streng genommen falsch sind:

TDegree.OnDelete = Wenn die Instanz (TDegree) aus dem Speicher entfernt wird

TCustomObjectList.OnDelete = Wenn die Instanz (TCustomObjectList) aus dem Speicher entfernt wird
... ach nee, wenn ein Item aus der Liste geworfen wird ... aber für die Liste ist es doch nur eine Änderung an sich selber ;)

Jonas Shinaniganz 2. Nov 2012 09:01

AW: Ein Object in TObjectList<T> löschen mit Ereignis
 
Ein OnDelete welches so gedacht ist, dass es vom Objekt selbst kommt.. quasi ein OnDestroy.. naja das könnte dann höchstens ein "OnBeforeDelete" werden...

destructor Destroy;
begin
OnDelete;
//kram...
inherited;
end;

Aber du willst ja ein "OnItemDelete" um der Sache mal ein eindeutigeres Wort zu geben.

Oder?

Edit:

Die Liste soll ja deine Objekte verwalten... je nachdem wie du arbeitest brauchen dann deine Objekte garkein OnDelete AKA OnDestroy. Außer deine Objekte sind wiederum von einer Klasse die vielleicht eine Liste oder etwas mit einem sinnigen Delete hat...

stahli 2. Nov 2012 09:05

AW: Ein Object in TObjectList<T> löschen mit Ereignis
 
Vielleicht sollte die Ereignisbehandlung der Liste über "OnItemDelete" laufen...

EDIT: Oups, überholt ohne einzuholen... ;-)

RWarnecke 2. Nov 2012 17:23

AW: Ein Object in TObjectList<T> löschen mit Ereignis
 
So sehen jetzt meine beiden Klassen aus und funktionierten so wie Sie sollen :
Delphi-Quellcode:
  TModifyActionList = (lnNone, lnChange, lnDelete);

  TDegree = class
  private
    FOnChange     : TNotifyEvent;
    FModifyAction : TModifyActionList;
    FID           : Integer;
    FDegree       : string;
    procedure SetID(const Value: Integer);
    procedure SetDegree(const Value: string);
    procedure SetOnChange(const Value: TNotifyEvent);
  public
    property ID           : Integer          read FID           write SetID;
    property Degree       : string           read FDegree       write SetDegree;
    property ModifyAction : TModifyActionList read FModifyAction write FModifyAction;
    property OnChange     : TNotifyEvent     read FOnChange     write SetOnChange;
  end;

  TCustomObjectList<T: class> = class(TObjectList<T>)
  private
    FOnChange    : TNotifyEvent;
    FOnItemDelete : TNotifyEvent;
    FModifyAction : TModifyActionList;
    FNewRecord   : Boolean;
    procedure SetOnItemDelete(const Value: TNotifyEvent);
    procedure SetOnChange(const Value: TNotifyEvent);
  protected
    function getItem(Index: Integer): T; virtual;
    procedure setItem(Index: Integer; Objekt: T); virtual;
    procedure Notify(const Item: T; Action: TCollectionNotification); override;
  public
    function Add(Objekt: T): Integer; virtual;
    function NewRecord(Objekt: T): Integer; virtual;
    function Remove(Objekt: T): Integer; virtual;
    function IndexOf(Objekt: T): Integer; virtual;
    procedure Insert(Index: Integer; Objekt: T); virtual;
    property Items[index: Integer]: T        read getItem      write setItem; default;
    property ModifyAction : TModifyActionList read FModifyAction write FModifyAction;
    property OnChange    : TNotifyEvent     read FOnChange    write SetOnChange;
    property OnItemDelete : TNotifyEvent     read FOnItemDelete write SetOnItemDelete;
  end;

{...}

{ TCustomObjectList<T> }

function TCustomObjectList<T>.Add(Objekt: T): Integer;
begin
  FNewRecord := False;
  Result := inherited Add(Objekt);
end;

function TCustomObjectList<T>.getItem(Index: Integer): T;
begin
  Result := T(inherited Items[Index]);
end;

function TCustomObjectList<T>.IndexOf(Objekt: T): Integer;
begin
  Result := inherited IndexOf(Objekt);
end;

procedure TCustomObjectList<T>.Insert(Index: Integer; Objekt: T);
begin
  inherited Insert(Index, Objekt);
end;

function TCustomObjectList<T>.NewRecord(Objekt: T): Integer;
begin
  FNewRecord := True;
  Result := inherited Add(Objekt);
end;

procedure TCustomObjectList<T>.Notify(const Item: T;
  Action: TCollectionNotification);
begin
  if (Assigned(FOnChange)) and (FNewRecord) and (Action <> cnRemoved) then
  begin
    FNewRecord := False;
    FOnChange(Self);
  end;
  if Action = cnRemoved then
  begin
    FOnItemDelete(Item);
  end;
  inherited Notify(Item, Action);
end;

function TCustomObjectList<T>.Remove(Objekt: T): Integer;
begin
  Result := inherited Remove(Objekt);
end;

procedure TCustomObjectList<T>.setItem(Index: Integer; Objekt: T);
begin
  inherited Items[Index] := Objekt;
end;

procedure TCustomObjectList<T>.SetOnChange(const Value: TNotifyEvent);
begin
  FOnChange := Value;
end;

procedure TCustomObjectList<T>.SetOnItemDelete(const Value: TNotifyEvent);
begin
  FOnItemDelete := Value;
end;

{ TDegree }

procedure TDegree.SetDegree(const Value: string);
begin
  FDegree := Value;
  if (Assigned(FOnChange)) and (FModifyAction = lnChange) then
    FOnChange(Self);
end;

procedure TDegree.SetID(const Value: Integer);
begin
  FID := Value;
  if (Assigned(FOnChange)) and (FModifyAction = lnChange) then
    FOnChange(Self);
end;

procedure TDegree.SetOnChange(const Value: TNotifyEvent);
begin
  FOnChange := Value;
end;
So wird jetzt die ObjectList erstellt und die Liste befüllt :
Delphi-Quellcode:
  DegreeList := TCustomObjectList<TDegree>.Create;
  DegreeList.OnItemDelete := TableEntryDelete;

  { Dieser Teil wird in einer Schleife ein paar Mal wiederholt }
  Degree := TDegree.Create;
  Degree.OnChange := TableEntryChange;
  Degree.ID := FieldByName('ID').AsInteger;
  Degree.Degree := FieldByName('Degree').AsString;
  DegreeList.Add(Degree);
Jetzt ist es so, wenn ein Object aus der Liste gelöscht wird, also mit
Delphi-Quellcode:
DegreeList.Delete(0)
, dann wird das OnItemDelete zusätzlich mit ausgeführt. Wird jetzt der Inhalt eines Objectes geändert mit
Delphi-Quellcode:
DegreeList.Items[0].Degree := AdvEdt_12.Text;
so wird über die Variable ModifyAction=lnChange das OnChange-Ereignis der Klasse aufgerufen. Somit funktioniert das Konstrukt so wie ich es haben möchte.

Ich hoffe es ist jetzt ein bisschen klarer, was ich erreichen wollte. Wenn es noch Verbesserungsvorschläge gibt, dann nur her damit. Ich bin immer bereit noch etwas zu lernen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:11 Uhr.
Seite 3 von 3     123   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz