Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Panels lassen sich nicht wie gewünscht in einer Scrollbox erzeugen (https://www.delphipraxis.net/209779-panels-lassen-sich-nicht-wie-gewuenscht-einer-scrollbox-erzeugen.html)

Nine9 20. Jan 2022 11:48

Panels lassen sich nicht wie gewünscht in einer Scrollbox erzeugen
 
Guten Tag liebe Community,

ich verzweifele momentan etwas.
Ich möchte mehrere Panels in einer Scrollbox erzeugen.
sie sollen bis zum ende des Images erzeugt werden das auch in der Scrollbox struktur vorhanden ist.

Hier ein kleiner Code
Delphi-Quellcode:
unit Unit4;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;

type
  TForm4 = class(TForm)
    ScrollBox1: TScrollBox;
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form4: TForm4;
  FPanel : TPanel;
  ydifferenz , xdifferenz ,x1,i,Tag1,k: integer;

implementation

{$R *.dfm}

procedure TForm4.FormCreate(Sender: TObject);
begin

//Form
Form4.Width := screen.Width;
form4.Top := screen.DesktopTop;
Form4.Height := screen.Height;
form4.Left := screen.DesktopLeft;

// Ydifferenz
xdifferenz := Form4.Width div 31;
ydifferenz := form4.Height div 12 ;

 // Position Image
  with image1 do
  begin

   left := scrollbox1.Left;
   top := scrollbox1.top +(ydifferenz div 2 );
   width := form4.Width * 50;

  end;

 // Tag
 Tag1 := trunc(image1.width / 365);;
 x1 := trunc(Image1.width / 365);

    for i := 0 to 365 do
    begin

      Fpanel := TPanel.Create(self);
      with Fpanel do
      begin

        left := x1 * i;
        top := -ydifferenz div 8;
        height := ydifferenz div 2;
        width := Tag1;
        parentbackground := false;
        parent := scrollbox1;
        visible := true;
        Color := clsilver;
        caption := inttostr(k);
      end;

      k := k+1;

    end;

end;
Die Panels werden nacheinander erzeugt. doch nur bis zu einem bestimmten punkt dann bleibt er stehen und erzeugt auf einer stelle den rest.
Hat jmd eine idee?

Zum nachbauen braucht Ihr nur eine Form. Eine Scrollbox und Ein Image in der scrollbox.

stahli 20. Jan 2022 12:24

AW: Panels lassen sich nicht wie gewünscht in einer Scrollbox erzeugen
 
Ich kann mich jetzt nicht genauer damit beschäftigen, aber mal eine Frage (bzw. Tipp):

Hast Du mal einen Breakpoint (F5) gesetzt und mal den Ablauf debuggt (F9 + F8)?
Dann kannst Du die Werte der Variablen in den überwachten Ausdrücken oder mit MouseOver einsehen und prüfen.

haentschman 20. Jan 2022 12:41

AW: Panels lassen sich nicht wie gewünscht in einer Scrollbox erzeugen
 
Zitat:

Dann kannst Du die Werte der Variablen in den überwachten Ausdrücken oder mit MouseOver einsehen und prüfen.
...wie soll das mit WITH gehen? :stupid:

himitsu 20. Jan 2022 13:57

AW: Panels lassen sich nicht wie gewünscht in einer Scrollbox erzeugen
 
Warum sind die Variablen global, ob nur lokal genutzt?

Und wieso wird innerhalb von TForm4 auf Form4 zugegriffen? (da nimmt man gefälligst Self)

Rolf Frei 20. Jan 2022 14:12

AW: Panels lassen sich nicht wie gewünscht in einer Scrollbox erzeugen
 
Du hast da gerade mehere Probleme:
1. Die globalen Variabeln solltest du innerhalb als Felder deines Objekts (TForm4) erstellen oder lokal innerhalb der Funcion/Procedure, wenn diese sonst nicht verwendet werden.
2. Die globale Form Variable Form4 solltest du auf keinen Fall im Objekt direkt ansprechen!!! Wenn du innerhlab deines Objekts auf die Felder dessen zugriffen wills, kannst du die Felder direkt angeben. Unter Umständen must du mal innerhlab eines "with", das die Selben Felder enthält (z.B. Left bei TPanel und TForm), auf die Felder des Objekts zugreiffen, dann kannst du "Self.Left" schreiben. Self betrift dein Objekt in dem du dich befindest (TForm4).
3. Auf das "with" Statement solltes du besser verzichten oder nur nehmen, wenn da eindeutige namen verwendet werden. Denn Left,With,etc sind alle sowohl im TPanel als auch im TForm enthalten. Das kann zu unerwarteten Fehler führen, wenn da das Property Left von TPanel auf einmal abgeändert wird und dann neu PanelLeft heissen würde. Dein Code würde dann noch immer problemlos kompilieren, aber das setzen von Left, würde dann das Left von TForm veändern und nicht das nicht mehr vorhanden vom TPanel.

Habe deinen Code mal soweit angepasst, dass das obige nun korrekt ist. Beachte bitte auch die Kommentare inerhalb des Codes.

Delphi-Quellcode:
unit Unit4;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;

type
  TForm4 = class(TForm)
    ScrollBox1: TScrollBox;
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
    FPanel : TPanel; // Das könntest du auch lokal in der Procedure platzieren, wenn du nicht mehr an anderer Stelle darauf zugreiffen willst.
  public
    { Public-Deklarationen }
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}

procedure TForm4.FormCreate(Sender: TObject);
var
  ydifferenz , xdifferenz ,x1,i,Tag1,k: integer;
  { Wenn diese Variabeln auch an anderen Stellen verwendet werden sollen,
    kannst du sie auch ins Objekt TForm4 verschieben, analog zu FPanel. }
  // FPanel:TPanel; Das ist im TForm4 als Feld definiert, könnte da aber auch weg und dafür hier stehen.
begin

  //Form
  Width := screen.Width;
  Top := screen.DesktopTop;
  Height := screen.Height;
  Left := screen.DesktopLeft;

  // Ydifferenz
  xdifferenz := Width div 31;
  ydifferenz := Height div 12 ;

 // Position Image
  { Ich denke du hast Image1 innerhalb des Scrollbox platziert oder? 
    Die Scrollbox ist also der Parent des Image? Bei deinem folgenden Code ist mir nähmlich nicht klar, ob das wirklich das ist was du willst.
  with image1 do
  begin

   left := scrollbox1.Left;
   top := scrollbox1.top +(ydifferenz div 2 );
   width := form4.Width * 50;

  end;
  Das with wie folgt ersetzt:}
  image1.Left := Scrollbox.Left; // Ist das wirklch das was du willst? Du platzierst hiermit, das Image im gleichen Abtands zum linken Rahmen innerhalb der Scrollbox, wie die Scrollbox den Abstand zum Form Rahmen hat.
  image1.top := scrollbox1.top +(ydifferenz div 2 );
  image1.width := Width * 50; // With ist vom aktuellen Objekt in dem du dich befindest, als der TForm


  // Tag
  Tag1 := trunc(image1.width / 365);;
  x1 := trunc(Image1.width / 365);

  for i := 0 to 365 do
  begin

    Fpanel := TPanel.Create(self);
    Fpanel.left := x1 * i;
    Fpanel.top := -ydifferenz div 8;  
    Fpanel.height := ydifferenz div 2;
    Fpanel.width := Tag1;
    Fpanel.parentbackground := false;
    Fpanel.parent := scrollbox1;
    Fpanel.visible := true;
    Fpanel.Color := clsilver; // Möchtest du hier nicht besser die Systemfarben nutzen, zB. clBtnFace?
    Fpanel.caption := inttostr(k);

    k := k+1; // hier könntest du auch einfach "Inc(k)" schreiben

  end;

end;
Mir ist aber nicht recht klar, was du da genau machen willst. Die Positionierung des TPanels scheint mir da etwas "komisch". Das Top des Panels ist ja immer die gleiche, weil du "ydifferenz" innerhalb der for Schlaufe nicht änderst. Müsstest du da nicht für die Berechung von Top auch noch eine weiteres "for j := 1 to 12" haben?

Nine9 20. Jan 2022 17:11

AW: Panels lassen sich nicht wie gewünscht in einer Scrollbox erzeugen
 
Erstmal vielen dank an alle :) ich werde in zukunft anderst coden.

Den top soll es nie verändern. Nur left soll geändert werden sodass ein panel nach dem anderen neben den vorherigen panel erzeugt werden soll. :)

Rolf Frei 21. Jan 2022 15:24

AW: Panels lassen sich nicht wie gewünscht in einer Scrollbox erzeugen
 
Was ich noch gesehen habe ist, dass du die Variable k niergends initialisierst. Mach das spätestns vor der "For"-Schlaufe mit k := 1.

EDIT:
Habe übrigens nun mal alles selber so getestet und kann dein Problem nun sehen. Sobald Left grösser 32'767 ist, was ab dem 95. Panel der Fall ist, werden alle folgenden Panel auch mit dieser maximalen Left Position platziert. Das Problem hier ist Windows selber, da die Position im Windowsm API als "int" deklariert ist und somit 32767 der Maximalwert für Left bei einem Window darstellt.

Müssen denn die Panel wirklich ein TWinControl sein oder würde auch eine TGraphicControl gehen (z.B. TPaintBox)? Mit einem TBevel (ein TGraphicControl) anstelle des TPanel geht es nämlich problemlos. Mit eine TPanel, also einem TWinControl, wirst du das nicht lösen können.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:06 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