Einzelnen Beitrag anzeigen

Benutzerbild von RWarnecke
RWarnecke

Registriert seit: 31. Dez 2004
Ort: Stuttgart
4.408 Beiträge
 
Delphi XE8 Enterprise
 
#29

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

  Alt 2. Nov 2012, 18:23
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 DegreeList.Delete(0) , dann wird das OnItemDelete zusätzlich mit ausgeführt. Wird jetzt der Inhalt eines Objectes geändert mit 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.
Rolf Warnecke
App4Mission
  Mit Zitat antworten Zitat