Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Seter und getter von TCollection überschreiben (https://www.delphipraxis.net/99910-seter-und-getter-von-tcollection-ueberschreiben.html)

Andreas L. 19. Sep 2007 14:13


Seter und getter von TCollection überschreiben
 
Hi,
ich verwende in einer Komponente zur Verwaltung von Items die TCollection. Damit nur meine eigenen TCollectionItems hinzugefügt werden können und nicht andere, habe ich einige Routinen überschrieben.

Delphi-Quellcode:
type
  TNavigationListCollection = class(TCollection)
  protected
    function GetItem(Index: Integer):TNavigationListCollectionItem;
    procedure SetItem(Index: Integer; const Value: TNavigationListCollectionItem);
  public
    function Add:TNavigationListCollectionItem;
    function Insert(Index: Integer):TNavigationListCollectionItem;
    property Items[Index: Integer]: TnavigationListCollectionItem read GetItem write SetItem; default;
  end;

...
...

procedure TNavigationListCollection.SetItem(Index: Integer; const Value: TNavigationListCollectionItem);
begin

 Items[Index].Assign(Value);

end;

function TNavigationListCollection.GetItem(Index: Integer):TNavigationListCollectionItem;
begin

 Result.Assign(Items[Index]);
// Result := Items[Index];

end;

function TNavigationListCollection.Add:TNavigationListCollectionItem;
begin

 Result := (inherited Add as TNavigationListCollectionItem);

end;

function TNavigationListCollection.Insert(Index: Integer):TNavigationListCollectionItem;
begin

 Result := (inherited Insert(Index) as TNavigationListCollectionItem);

end;
Doch wenn getItem aufgerufen wird, bekomme ich einen Stack-Überlauf. Wieso? Ich kann keinen Fehler finden...

Apollonius 19. Sep 2007 14:20

Re: Seter und getter von TCollection überschreiben
 
Du must inherited Items aufrufen, da sonst wieder dein Getter drankommt, der wieder deinen Getter aufruft...
Außerdem solltest du die auskommentierte Variante verwenden, da du sonst eine Zugriffsverletzung bekommst (weil du result nicht createt hast), und wenn die behoben ist, wirst du nicht die gewünschten Ergebnisse erhalten.

Andreas L. 19. Sep 2007 14:27

Re: Seter und getter von TCollection überschreiben
 
Ok, jetzt gehts. Jedesmal wenn sich eine Eigenschaft eines TNavigationListCollectionItems ändert, muss die Basiskomponente (TNavigationList) neugezeichnet werden. Dafür habe ich eine private Refresh procedure implementiert. Es wäre doch nun sinnvoll, diese Procedure im Setter von TNavigationListCollection aufzurufen anstatt für jede Eigenschaft einen eignen Setter zu bauen. Geht das so ohne weiteres?

Andreas L. 19. Sep 2007 15:29

Re: Seter und getter von TCollection überschreiben
 
Hab jetzt im Setter einen Aufruf der Refresh-Procedure implementiert.

Delphi-Quellcode:
procedure TNavigationListCollection.SetItem(Index: Integer; const Value: TNavigationListCollectionItem);
begin

 inherited Items[Index].Assign(Value);
 (Owner as TNavigationList).Refresh;

end;
Wenn ich jetzt in meiner Test-Anwendung folgendes aufrufe, passiert nichts:

Delphi-Quellcode:
 NavigationList1.Items.Items[0].ShowHint := False;
Muss ich evtl. noch irgendeine Methode überschreiben?

Andreas L. 20. Sep 2007 19:44

Re: Seter und getter von TCollection überschreiben
 
Keiner eine Idee?

Apollonius 20. Sep 2007 21:09

Re: Seter und getter von TCollection überschreiben
 
Ich habe eben mal nachgeschaut, es wird nur getItem aufgerufen. Das ist auch logisch, da Klassen bekanntlich Zeiger sind, und diesen Zeiger liest man ja.
Dein Problem würde ich so lösen, dass ich im Item die Setter-Methoden überschreibe und das Refresh des Parents auslöse.

Andreas L. 21. Sep 2007 23:24

Re: Seter und getter von TCollection überschreiben
 
Wie genau meinst du das? Wenn ich für jedes property des Items einen Setter anlege, habe ich abgesehen davon, dass ich mir keinerlei Arbeit spare, auch noch eine Zugriffsverletzung.

Delphi-Quellcode:
procedure TNavigationListCollectionItem.SetCaption(Value: string);
begin

 fCaption := Value;
 (Collection.Owner as TNavigationList).Refresh;

end;

Andreas L. 22. Sep 2007 11:37

Re: Seter und getter von TCollection überschreiben
 
Ich bin in der Delphi-Hilfe nun auf die procedure Changed gestoßen, diese wird immer aufgerufen wenn sich ein CollectionItem ändert. Also überschrieben und folgendes rein:

Delphi-Quellcode:
procedure TNavigationListCollection.Changed;
begin

 (Owner as TNavigationList).Refresh;
 ShowMessage('ok');

end;
Nichts passiert, nicht mal die Message wird angezeigt.

EDIT: Wenn ich die procedure Update überschreibe gehts, Problem gelöst...


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:22 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 by Thomas Breitkreuz