AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls .Controls und .Components nicht als Auflistung nutzbar?

.Controls und .Components nicht als Auflistung nutzbar?

Ein Thema von freejay · begonnen am 11. Mai 2022 · letzter Beitrag vom 25. Mai 2022
Antwort Antwort
Seite 1 von 3  1 23   
freejay

Registriert seit: 26. Mai 2004
Ort: Nürnberg
243 Beiträge
 
Delphi 10.4 Sydney
 
#1

.Controls und .Components nicht als Auflistung nutzbar?

  Alt 11. Mai 2022, 12:46
Hallo zusammen,

kann es sein, dass man das Folgende immer noch nicht machen kann:

for MyControl in Panel1.Controls do

Muss man immer noch schreiben

for i := 0 to Panel1.ControlCount - 1 do

oder mache ich da bloß was falsch?

Danke im voraus!

Freejay
[Delphi 10.4.1 Sydney Enterprise; Win10; MySQL; VCL]
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
9.522 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: .Controls und .Components nicht als Auflistung nutzbar?

  Alt 11. Mai 2022, 13:54
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;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
9.522 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: .Controls und .Components nicht als Auflistung nutzbar?

  Alt 11. Mai 2022, 14:16
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;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
9.522 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: .Controls und .Components nicht als Auflistung nutzbar?

  Alt 11. Mai 2022, 14:23
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';
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
freejay

Registriert seit: 26. Mai 2004
Ort: Nürnberg
243 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: .Controls und .Components nicht als Auflistung nutzbar?

  Alt 11. Mai 2022, 15:45
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?
[Delphi 10.4.1 Sydney Enterprise; Win10; MySQL; VCL]
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
9.522 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: .Controls und .Components nicht als Auflistung nutzbar?

  Alt 11. Mai 2022, 16:04
aber es sieht wie eine Funktion aus, die man mit dem Control aufruft und das wirkt irgendwie "un-objektorientiert"
Kannst du diese Aussage etwas präzisieren?
Was am Aufruf einer function eines Objekts ist denn un-objektorientiert? (Oder allgemeiner: Was bedeutet un-objektorientiert überhaupt?)
Würde diese function ein TArray<TControl> zurückgeben, was ja problemlos mit for-in iteriert werden kann, wäre das dann auch un-objektorientiert?
Immerhin wird sowas ja bereits an vielen Stellen in Delphi gemacht, z.B. TStringList.ToStringArray .

Ich nehme an diese Helper sind (noch) nicht Bestandteil von Delphi?
Nein, die sind von mir. Wären sie in Delphi drin, wären es vermutlich keine Helper, sondern die Funktionalität wäre direkt in TComponent bzw. TWinControl implementiert.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.828 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: .Controls und .Components nicht als Auflistung nutzbar?

  Alt 11. Mai 2022, 16:06
Zitat:
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"...
Delphi-Quellcode:
for var ctrl in ControlsOf<TButton> do
    ctrl.Caption := 'Hello World';
Doch ist doch objektorientiert. Oder wie sollte es nach Deiner Meinung aussehen, wenn es objektorientiert wäre?
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
9.522 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: .Controls und .Components nicht als Auflistung nutzbar?

  Alt 11. Mai 2022, 16:09
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';
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.659 Beiträge
 
Delphi 2007 Enterprise
 
#9

AW: .Controls und .Components nicht als Auflistung nutzbar?

  Alt 11. Mai 2022, 21:47
die Funktionalität wäre direkt in TComponent bzw. TWinControl implementiert.
Stellt sich die Frage: Wieso ist es das eigentlich nicht? Das ist doch ziemlich ein Paradebeispiel für solch ein Konstrukt. Bin ich auch schon kräftig drüber gestolpert, und war doch recht verwundert ob der Tatsachen.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
39.698 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: .Controls und .Components nicht als Auflistung nutzbar?

  Alt 11. Mai 2022, 21:57
für Components gibt es bereits einen Enumerator

for var C in IrgendeineTComponentInstanz do
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:59 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf