Delphi-Quellcode:
type
TComponentList<T: TComponent> = class(TObjectList<T>)
private type
TNotify = class(TComponent)
FParent: TComponentList<T>;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
end;
private
FNotify: TNotify;
protected
procedure Notify(const Value: T; Action: TCollectionNotification); override;
public
destructor Destroy; override;
end;
destructor TComponentList<T>.Destroy;
begin
FNotify.Free;
inherited;
end;
procedure TComponentList<T>.Notify(const Value: T; Action: TCollectionNotification);
begin
inherited;
if not Assigned(FNotify) then begin
FNotify := TNotify.Create(nil);
FNotify.FParent := Self;
end;
if Action = cnAdded then
FNotify.FreeNotification(Value)
else if not Contains(Value) then
FNotify.RemoveFreeNotification(Value);
end;
procedure TComponentList<T>.TNotify.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;
if (Operation = opRemove) and not FParent.Contains(AComponent) then
while FParent.Extract(AComponent) <> nil do ;
end;
Aber wenn man sowieso schon eine Owner- oder Parent-Beziehung hat, dann kann man sich eigentlich auch die zusätzliche Liste sparen, indem man die bereits existierenden Parent.Components- oder Parent.Controls-Listen mit benutzt.
Das Einzige, was ich mich bei Entwicklung dieser Liste gefragt hatte ..... wer zum Teufel war so wirklich saudämlich und hat vergessen das TList<T>.Create(), oder besser schon TEnumerable<T>.Create(), als virtual zu deklarieren, so daß man in Nachfahren ständig
immer alle Konstrutoren überschreiben
muß, wenn man da drin irgendwas initialisieren wöllte.
Ach ja, und wer bei den FreeNotifications keine Registrierungszählung implementierte ... mehrere Verbindungen zwischen den selben Komponenten und man muß mit dem RemoveFreeNotification aufpassen.
Genau deswegen setzte ich gern eine gekapselte Notify-Komponente ein, wenn ich nicht kontrollieren kann, ob zwischen referenzierenden Komponenten eventuell noch andere Referenzen, wie z.B. die Parent- oder Owner-Beziehungen existieren könnten.
Alternativ könnte man nur registrieren (FreeNotification) und dürfte nie deregistrieren (RemoveFreeNotification), außer mal selber wird freigegeben, aber dann räumt sich das eh von selber auf.