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 Bei TList, Record auf Datenänderung reagieren (https://www.delphipraxis.net/145234-bei-tlist-record-auf-datenaenderung-reagieren.html)

RWarnecke 26. Jan 2010 19:57

Re: Bei TList, Record auf Datenänderung reagieren
 
So sieht mein Versuch aus. Nur leider schaffe ich es nicht,
Delphi-Quellcode:
  TGesellschafterChangeEvent = procedure(Sender: TObject; Obj: TGesellschaftsname) of object;

  TGesellschafterObjListe = class(TObjectList)
  private
    FOnChange : TGesellschafterChangeEvent;
  protected
    function getItem(Index: Integer): TGesellschaftsname; virtual;
    procedure setItem(Index: Integer; Objekt: TGesellschaftsname); virtual;
  public
    function Add(Objekt: TGesellschaftsname): Integer; virtual;
    function NewRecord(Objekt: TGesellschaftsname): Integer; virtual;
    function Remove(Objekt: TGesellschaftsname): Integer; virtual;
    function IndexOf(Objekt: TGesellschaftsname): Integer; virtual;
    procedure Insert(Index: Integer; Objekt: TGesellschaftsname); virtual;
    property Items[index: Integer]: TGesellschaftsname read getItem write setItem; default;
    property OnChange: TGesellschafterChangeEvent read FOnChange write FOnChange;
  end;

{...}

procedure TMainForm.GesellschafterListeChange(Sender: TObject; Obj: TGesellschaftsname);
begin
  with DM_Main.UniQuery_Temp do
  begin
    SQL.Text := 'EXECUTE PROCEDURE SP_NEW_GESELLSCHAFTER (:stammnr, :name, :B1, :B2, :D2);';
    ParamByName('StammNr').AsInteger := Obj.StammNr;
    ParamByName('Name').AsString := Obj.Gesellschaftername;
    ParamByName('B1').AsFloat := Obj.Zeichnungskapital;
    ParamByName('B2').AsFloat := Obj.ZahlenderBetrag;
    ParamByName('D2').AsDateTime := Obj.ZweiteZahlung;
    Execute;
  end;
end;

{...}

function TGesellschafterObjListe.Add(Objekt: TGesellschaftsname): Integer;
begin
  Result := inherited Add(Objekt);
end;

function TGesellschafterObjListe.getItem(Index: Integer): TGesellschaftsname;
begin
  Result := TGesellschaftsname(inherited Items[Index]);
end;

function TGesellschafterObjListe.IndexOf(Objekt: TGesellschaftsname): Integer;
begin
  Result := inherited IndexOf(Objekt);
end;

procedure TGesellschafterObjListe.Insert(Index: Integer; Objekt: TGesellschaftsname);
begin
  inherited Insert(Index, Objekt);
end;

function TGesellschafterObjListe.NewRecord(Objekt: TGesellschaftsname): Integer;
begin
  Result := inherited Add(Objekt);
  if Assigned(FOnChange) then
    FOnChange(Self, Objekt);
end;

function TGesellschafterObjListe.Remove(Objekt: TGesellschaftsname): Integer;
begin
  Result := inherited Remove(Objekt);
end;

procedure TGesellschafterObjListe.setItem(Index: Integer; Objekt: TGesellschaftsname);
begin
  inherited Items[Index] := Objekt;
  if Assigned(FOnChange) then
    FOnChange(Self, Objekt);
end;
Das ChangeEvent wird nicht ausgeführt, wenn ich einen Wert ändere. Wenn ich NewRecord ausführe, dann wird das Change-Event ausgeführt, aber in Obj stehen keine Werte aus der Klasse. Kann mir da jemand bitte weiterhelfen, denn ich weiß nichtmehr weiter.

himitsu 26. Jan 2010 20:56

Re: Bei TList, Record auf Datenänderung reagieren
 
Wozu ist denn alles als virtual deklariert?
Bringt zu diesem Zeitpunkt eh nix mehr.

Wird auch überall TGesellschafterObjListe verwendet und nicht TObjectList/TList?
TList kennt deine Änderungen ja nicht.

Ich würde eher Notify über schreiben und dort das OnChange-Event auslösen, da kommen alle Meldungen (hinzugefügt/gelöscht) vorbei.
Delphi-Quellcode:
protected
  procedure Notify(Ptr: Pointer; Action: TListNotification); override;

RWarnecke 26. Jan 2010 21:06

Re: Bei TList, Record auf Datenänderung reagieren
 
Zitat:

Zitat von himitsu
Wozu ist denn alles als virtual deklariert?
Bringt zu diesem Zeitpunkt eh nix mehr.

Wird auch überall TGesellschafterObjListe verwendet und nicht TObjectList/TList?
TList kennt deine Änderungen ja nicht.

Ich würde eher Notify über schreiben und dort das OnChange-Event auslösen, da kommen alle Meldungen (hinzugefügt/gelöscht) vorbei.
Delphi-Quellcode:
protected
  procedure Notify(Ptr: Pointer; Action: TListNotification); override;

Hallo himitsu,

ich kann Dir leider nicht ganz folgen mit dem Notify. Kannst Du mir das bitte mal an einem praktischen Beispiel erklären ?

himitsu 26. Jan 2010 21:34

Re: Bei TList, Record auf Datenänderung reagieren
 
TObjectList nutzt dieses z.B. um Objekte freizugeben
Delphi-Quellcode:
procedure TObjectList.Notify(Ptr: Pointer; Action: TListNotification);
begin
  if OwnsObjects then
    if Action = lnDeleted then
      TObject(Ptr).Free;
  inherited;
end;
du überschreibst es und macht z.B. sowas
Delphi-Quellcode:
procedure TGesellschafterObjListe.Notify(Ptr: Pointer; Action: TListNotification);
begin
  if (Action = lnAddted) and Assigned(FOnChange) then
    FOnChange(Self, TGesellschaftsname(Ptr));
  inherited;
end;
PS: OnChange reagiert so nur auf Änderungen der Liste,
wenn auch z.B. auf Änderungen/Zuweisungen in/an .Zeichnungskapital reagert werden soll,
dann muß dieses in TGesellschaftsname abgefangen und an die TGesellschafterObjListe weitergereicht werden.

RWarnecke 26. Jan 2010 21:44

Re: Bei TList, Record auf Datenänderung reagieren
 
Zitat:

Zitat von himitsu
TObjectList nutzt dieses z.B. um Objekte freizugeben
Delphi-Quellcode:
procedure TObjectList.Notify(Ptr: Pointer; Action: TListNotification);
begin
  if OwnsObjects then
    if Action = lnDeleted then
      TObject(Ptr).Free;
  inherited;
end;
du überschreibst es und macht z.B. sowas
Delphi-Quellcode:
procedure TGesellschafterObjListe.Notify(Ptr: Pointer; Action: TListNotification);
begin
  if (Action = lnAddted) and Assigned(FOnChange) then
    FOnChange(Self, TGesellschaftsname(Ptr));
  inherited;
end;

Ok, den Teil mit dem Notify habe ich kapiert, hoffe ich. :?

Zitat:

Zitat von himitsu
PS: OnChange reagiert so nur auf Änderungen der Liste,
wenn auch z.B. auf Änderungen/Zuweisungen in/an .Zeichnungskapital reagert werden soll,
dann muß dieses in TGesellschaftsname abgefangen und an die TGesellschafterObjListe weitergereicht werden.

Wäre das sowas wie in Beitrag #16 von wicht ?

himitsu 26. Jan 2010 22:00

Re: Bei TList, Record auf Datenänderung reagieren
 
Zitat:

Zitat von RWarnecke
Wäre das sowas wie in Beitrag #16 von wicht ?

Ja, nur würde ich, bezüglich einer besseren Trennung, eine Protected-Methode "DoChange" in TGesellschafterObjListe einfügen und dann bei Veränderungen in TGesellschaftsname dieses aufrufen
Delphi-Quellcode:
if Assigned(FList) then
  FList.DoChange(Self);
Delphi-Quellcode:
procedure TGesellschafterObjListe.DoChange(Sender: TGesellschaftsname);
begin
  if Assigned(FOnChange) then
    FOnChange(Self, Sender);
end;

procedure TGesellschafterObjListe.Notify(Ptr: Pointer; Action: TListNotification);
begin
  if Action = lnAddted then
    DoChange(TGesellschaftsname(Ptr));
  inherited;
end;

RWarnecke 26. Jan 2010 22:09

Re: Bei TList, Record auf Datenänderung reagieren
 
Ich habe doch nochmal eine Frage zu Notify. Ich habe die Procedure genau so geschrieben wie Du in Deinem Beitrag. Wenn ich jetzt in dem ChangeEvent die Werte mitprotokollieren, sind alle Werte aus der Klasse leer. Entferne ich die Abfrage auf die Action, dann bekomme ich in dem Protokoll erst die leeren Werte angezeigt und danach dann die Werte die ich eingefügt habe in umgekehrter Reihenfolge. Also den letzten zuerst u.s.w. Kann man das noch irgendwie bereinigen ?

Zitat:

Zitat von mit Action = lnAdded
Wert 1: 0 - Wert 2:
Wert 1: 0 - Wert 2:
Wert 1: 0 - Wert 2:
Wert 1: 0 - Wert 2:

Zitat:

Zitat von ohne Action = lnAdded
Wert 1: 0 - Wert 2:
Wert 1: 0 - Wert 2:
Wert 1: 0 - Wert 2:
Wert 1: 0 - Wert 2:
Wert 1: 40 - Wert 2: Test 4
Wert 1: 30 - Wert 2: Test 3
Wert 1: 20 - Wert 2: Test 2
Wert 1: 10 - Wert 2: Test 1



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

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