![]() |
.Controls und .Components nicht als Auflistung nutzbar?
Hallo zusammen,
kann es sein, dass man das Folgende immer noch nicht machen kann:
Delphi-Quellcode:
for MyControl in Panel1.Controls do
Muss man immer noch schreiben
Delphi-Quellcode:
for i := 0 to Panel1.ControlCount - 1 do
oder mache ich da bloß was falsch? Danke im voraus! Freejay |
AW: .Controls und .Components nicht als Auflistung nutzbar?
Das ist immer noch so und einfach der Tatsache geschuldet, dass Controls ein Array-Property und eben kein Array ist.
Es gibt aber Abhilfe - und die ist sogar noch besser. Mit dem Code weiter unten kann man nämlich Folgendes schreiben:
Delphi-Quellcode:
for var ctrl in ControlsOf<TButton> do
ctrl.Caption := 'Hello World';
Delphi-Quellcode:
type
TWinControlHelper = class helper for TWinControl type TControlEnumerator<T: TControl> = class private FIndex: Integer; FWinControl: TWinControl; function GetCurrent: T; public constructor Create(AWinControl: TWinControl); function MoveNext: Boolean; property Current: T read GetCurrent; end; IControls<T: TControl> = interface function GetEnumerator: TControlEnumerator<T>; end; TControls<T: TControl> = class(TInterfacedObject, IControls<T>) private FWinControl: TWinControl; public constructor Create(AWinControl: TWinControl); function GetEnumerator: TControlEnumerator<T>; end; public function ControlsOf<T: TControl>: IControls<T>; end; { TWinControlHelper } function TWinControlHelper.ControlsOf<T>: IControls<T>; begin Result := TControls<T>.Create(Self); end; { TWinControlHelper.TControls<T> } constructor TWinControlHelper.TControls<T>.Create(AWinControl: TWinControl); begin inherited Create; FWinControl := AWinControl; end; function TWinControlHelper.TControls<T>.GetEnumerator: TControlEnumerator<T>; begin Result := TControlEnumerator<T>.Create(FWinControl); end; constructor TWinControlHelper.TControlEnumerator<T>.Create(AWinControl: TWinControl); begin inherited Create; FWinControl := AWinControl; FIndex := -1; end; function TWinControlHelper.TControlEnumerator<T>.GetCurrent: T; begin Result := FWinControl.Controls[FIndex] as T; end; function TWinControlHelper.TControlEnumerator<T>.MoveNext: Boolean; begin repeat Inc(FIndex); if FIndex >= FWinControl.ControlCount then Exit(False); if FWinControl.Controls[FIndex] is T then Exit(True); until False; end; |
AW: .Controls und .Components nicht als Auflistung nutzbar?
Hier auch noch das Pendant für Components:
Delphi-Quellcode:
type
TComponentHelper = class helper for TComponent type TComponentEnumerator<T: TComponent> = class private FIndex: Integer; FComponent: TComponent; function GetCurrent: T; public constructor Create(AComponent: TComponent); function MoveNext: Boolean; property Current: T read GetCurrent; end; IComponents<T: TComponent> = interface function GetEnumerator: TComponentEnumerator<T>; end; TComponents<T: TComponent> = class(TInterfacedObject, IComponents<T>) private FComponent: TComponent; public constructor Create(AComponent: TComponent); function GetEnumerator: TComponentEnumerator<T>; end; public function ComponentsOf<T: TComponent>: IComponents<T>; end; { TComponentHelper } function TComponentHelper.ComponentsOf<T>: IComponents<T>; begin Result := TComponents<T>.Create(Self); end; { TComponentHelper.TComponents<T> } constructor TComponentHelper.TComponents<T>.Create(AComponent: TComponent); begin inherited Create; FComponent := AComponent; end; function TComponentHelper.TComponents<T>.GetEnumerator: TComponentEnumerator<T>; begin Result := TComponentEnumerator<T>.Create(FComponent); end; constructor TComponentHelper.TComponentEnumerator<T>.Create(AComponent: TComponent); begin inherited Create; FComponent := AComponent; FIndex := -1; end; function TComponentHelper.TComponentEnumerator<T>.GetCurrent: T; begin Result := FComponent.Components[FIndex] as T; end; function TComponentHelper.TComponentEnumerator<T>.MoveNext: Boolean; begin repeat Inc(FIndex); if FIndex >= FComponent.ComponentCount then Exit(False); if FComponent.Components[FIndex] is T then Exit(True); until False; end; |
AW: .Controls und .Components nicht als Auflistung nutzbar?
Interessanterweise gibt es bereits einen Enumerator für Components, allerdings nicht generisch:
Delphi-Quellcode:
for var cmp in Self do
if cmp is TButton then TButton(cmp).Caption := 'Hello World'; |
AW: .Controls und .Components nicht als Auflistung nutzbar?
Vielen Dank!
Nicht falsch verstehen jetzt (ich bin sehr dankbar für die aufgezeigte Lösung), aber: Das ist sicher besser als for i := 0 to ... aber es sieht wie eine Funktion aus, die man mit dem Control aufruft und das wirkt irgendwie "un-objektorientiert"... Ich nehme an diese Helper sind (noch) nicht Bestandteil von Delphi? |
AW: .Controls und .Components nicht als Auflistung nutzbar?
Zitat:
Was am Aufruf einer function eines Objekts ist denn un-objektorientiert? (Oder allgemeiner: Was bedeutet un-objektorientiert überhaupt?) Würde diese function ein
Delphi-Quellcode:
zurückgeben, was ja problemlos mit for-in iteriert werden kann, wäre das dann auch un-objektorientiert?
TArray<TControl>
Immerhin wird sowas ja bereits an vielen Stellen in Delphi gemacht, z.B.
Delphi-Quellcode:
.
TStringList.ToStringArray
Zitat:
|
AW: .Controls und .Components nicht als Auflistung nutzbar?
Zitat:
Delphi-Quellcode:
Doch ist doch objektorientiert. Oder wie sollte es nach Deiner Meinung aussehen, wenn es objektorientiert wäre?
for var ctrl in ControlsOf<TButton> do
ctrl.Caption := 'Hello World'; |
AW: .Controls und .Components nicht als Auflistung nutzbar?
Man sollte vielleicht erwähnen, dass das ControlsOf in diesem Fall ja das des Forms ist, in dessen Event-Handler es aufgerufen wird. Wollte man das auf ein Panel anwenden, um z.B. die Buttons auf diesem Panel zu verarbeiten, müsste man das so schreiben:
Delphi-Quellcode:
for var ctrl in Panel1.ControlsOf<TButton> do
ctrl.Caption := 'Hello World'; |
AW: .Controls und .Components nicht als Auflistung nutzbar?
Zitat:
|
AW: .Controls und .Components nicht als Auflistung nutzbar?
für Components gibt es bereits einen Enumerator
Delphi-Quellcode:
for var C in IrgendeineTComponentInstanz do
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:53 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