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;