Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Panele dynamisch erzeugen (https://www.delphipraxis.net/209714-panele-dynamisch-erzeugen.html)

Kurt Wallander 13. Jan 2022 11:10

Panele dynamisch erzeugen
 
Hi Delphianer,

auf einer Form habe ich eine Paintbox als Container platziert. Auf dieser Paintbox möchte ich nun dynamisch insgesamt 81 Panele erzeugen und benutze folgenden Code:
Delphi-Quellcode:
      ...
      j:=1;i:=1;
//      while j= 1 do
      begin
//         while i= 1 do
         begin
            n_pnl:='Feld'+IntToStr(i)+IntToStr(j)+'_pnl';
            TPanel.Create(Self).Name := n_pnl;
            with TPanel(FindComponent(n_pnl)) do
            begin
               Left := left_M+(i-1)*sw+1;
               Top := top_m+(j-1)*sw+1;
               height:=sw-2;
               width:=sw-2;
               Parent := self;
               color:=clSilver;
               visible:=true;
               Caption:=n_pnl;
            end;
//            Inc(i);
         end;
//         Inc(j);
      end;
   end;
end;
Mein Problem: Left, top, height und with sind nicht die Position des erzeugten Panels, sondern die Position/Größe des Formulars. Die Panele sollen Child-Kompnenten der Paintbox werden. Was schreibe ich bei Parent ein? Paintbox1 geht nicht, das self funktioniert auch nicht.
Die Schleifen sind im obigen Beispiel als Test für 1 Panel eingestellt. Sowohl j als auch i müßten eigentlich von 1 bis 9 laufen, also (while j<=9). Egal, ob ich for, while oder repeat benutze, das Programm arbeitet die Schleifen unendlich mal ab. Ich bekomme dann die Fehlermeldung: Feld11_pnl existiert bereits.
Im Debug-Modus springt der Ausführungs-Punkt beim Erreichen des Parent-Befehls, unabhängig ob ich self oder Form1 wähle, zum Haltepunkt (= erster Befehl des dargestellten Snippets) zurück und will ab da den Code wiederholen. Der Color-Befehl wird nicht erreicht.
Wo liegt mein Denkfehler?
Kurt Wallander

peterbelow 13. Jan 2022 11:37

AW: Panele dynamisch erzeugen
 
Zitat:

Zitat von Kurt Wallander (Beitrag 1500529)
Hi Delphianer,

auf einer Form habe ich eine Paintbox als Container platziert. Auf dieser Paintbox möchte ich nun dynamisch insgesamt 81 Panele erzeugen und benutze folgenden Code:
Delphi-Quellcode:
      ...
      j:=1;i:=1;
//      while j= 1 do
      begin
//         while i= 1 do
         begin
            n_pnl:='Feld'+IntToStr(i)+IntToStr(j)+'_pnl';
            TPanel.Create(Self).Name := n_pnl;
            with TPanel(FindComponent(n_pnl)) do

Das ist ziemlich schrecklich :?.
Füge in der Methode eine lokale Variable hinzu:

Delphi-Quellcode:
  LPanel: TPanel;

...
  LPanel := TPanel.Create(Self);
  LPanel.Name := n_pnl;
  LPanel.Parent := paintbox1.Parent;
  LPanel.Left := ....
  etc.
  LPanel.BringToFront;

Eine TPaintbox (VCL) ist kein TWinControl und kann daher nicht als Container für andere Controls dienen.

Verwende auf keinen Fall ein With-Statement, das ist pures Gift in Code mit tief gestaffelten Scopes. With ist ein altes Erbe aus Turbo-Pascal Zeiten, wo es nur auf Records angewendet werden konnte und ein Hinweis für eine Optimierung für den Compiler lieferte. Heute schadet es weit mehr als das es nutzt, vergiss es einfach.

freimatz 13. Jan 2022 12:00

AW: Panele dynamisch erzeugen
 
Ja eine TPaintBox ist nicht dafür gedacht. Wieso nimmst Du diese? Was willst Du denn ausser die Panele noch da drauf haben?
Statt der TPaintBox könntest Du ein TPanel nehmen und dort Deine TPaintBox und die anderen Panels plazieren.
Natrag: weise Parent als letztes zu.

dummzeuch 13. Jan 2022 14:17

AW: Panele dynamisch erzeugen
 
Einfachste Lösung: Als Parent das Formular nehmen und auf Top und Left des Panels jeweils Top und Left der Paintbox aufaddieren.

bernau 13. Jan 2022 14:28

AW: Panele dynamisch erzeugen
 
Zitat:

Zitat von freimatz (Beitrag 1500534)
Ja eine TPaintBox ist nicht dafür gedacht.

Vielleicht hat er TScrollbox gemeint und hat sich einfach nur vertippt. Aufklärung wäre hier sicherlich hilfreich.

himitsu 13. Jan 2022 16:01

AW: Panele dynamisch erzeugen
 
aktuell geht ja sogar auch sowas, als Ersatz für das grauenhafte WITH. :stupid:

Delphi-Quellcode:
var P := TPanel.Create(Self);
L.Name := n_pnl;
L.Parent := paintbox1.Parent;
L.Left := ....

Kurt Wallander 13. Jan 2022 18:30

AW: Panele dynamisch erzeugen
 
huch, so viele Reaktionen!
Mehrheitlich lehnt man das with als Gift ab, habe also das Programm entgiftet.
PaintBox brauche ich, um zwischen den Panelen Trennungslinien zu zeichnen. Mir ist nur Paintbox eingefallen, weil es ein Canvas hat. Das ganze soll ein Sodoku-Helper werden.
Im Snippet sind i und j lokale intergers, n_pnl ein String. Left_m und top_m sind global definiert in einer Unit Globals und beschreiben die Position von der Paintbox (beide sind gleich 25) und sw ist die Schrittweite zwischen den Trennlinien (aktuell 95).
In der Test-Version wird dieser Code genau 1-mal durchlaufe - so meine Idee. aber in der Realität weitere Male.
Beim Debuggen kann ich sehen, daß der Rücksprung an den Anfang des Programmauschnittes beim Erreichen der Parent-Anweisung passiert. Parent ist irgendwie nicht koscher.
Allen für ihren Tipp vielen Dank
Kurt

peterbelow 13. Jan 2022 19:15

AW: Panele dynamisch erzeugen
 
Zitat:

Zitat von Kurt Wallander (Beitrag 1500566)
In der Test-Version wird dieser Code genau 1-mal durchlaufe - so meine Idee. aber in der Realität weitere Male.
Beim Debuggen kann ich sehen, daß der Rücksprung an den Anfang des Programmauschnittes beim Erreichen der Parent-Anweisung passiert. Parent ist irgendwie nicht koscher.
Allen für ihren Tipp vielen Dank
Kurt

Steht der Kode eventuell in einem Eventhandler? Wenn ja, für welchen Event?

Klaus01 13. Jan 2022 19:18

AW: Panele dynamisch erzeugen
 
.. gab es das GridPanel schon in 10.4 ?

Wäre vielleicht eine Alternative.

Grüße
Klaus

himitsu 13. Jan 2022 20:14

AW: Panele dynamisch erzeugen
 
früher

TiGü 14. Jan 2022 08:27

AW: Panele dynamisch erzeugen
 
Zitat:

Zitat von Kurt Wallander (Beitrag 1500566)
huch, so viele Reaktionen!
PaintBox brauche ich, um zwischen den Panelen Trennungslinien zu zeichnen. Mir ist nur Paintbox eingefallen, weil es ein Canvas hat.

Zeichne doch auf ein großes farbiges Hintergrundpanel deine kleineren Panele mit etwas Abstand, so dass die Farbe durchschaut.

KodeZwerg 14. Jan 2022 09:46

AW: Panele dynamisch erzeugen
 
ich würde viele kleine panels in ein großes erzeugen, als "trenner" einen bevel dazwischen erzeugen, per align/margins alles auf deinen geschmack abstimmen.
(das große muss ja nicht unbedingt als ein sichtbares erzeugt werden, es soll ja nur als container dienen. also ohne sichtbare kanten...)

Blup 14. Jan 2022 13:07

AW: Panele dynamisch erzeugen
 
Wenn schon in einer Paintbox, würde ich die Panel selber zeichnen und deren Inhalt ebenso.
Die Position der einzelnen Panel ist doch bekannt.
So viele Komponenten(insbesondere WinControl) machen das Programm sonst nur unnötig langsam.

Sinspin 14. Jan 2022 14:23

AW: Panele dynamisch erzeugen
 
Sudoku... das schreit eher nach einem Grid Control, oder nach selber zeichnen.
Bei Aktionen für eine Zelle könnte man neben dem Grid oder mit einem "schwebenden" Panel in der Nähe der Zelle dann eine Eingabe relaisieren. So oder so muss man nicht "tausendmal" die gleiche Komponente auf dem Form haben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz