Controls in anderen Forms "klauen"

Rund um die LCL und andere Komponenten
Antworten
Nimral
Beiträge: 390
Registriert: Mi 10. Jun 2015, 11:33

Controls in anderen Forms "klauen"

Beitrag von Nimral »

Ich arbeite gerne mit einem Form und blende dort je nach Bedarf Panels ein und aus. Das wird mit der Zeit etwas voll im Forms-Designer. Kann man eigentlich ein Panel samt seinen ganzen Controils auch in einem anderen Form entwerfen und dann irgendwie im eigenen Form nützen?

Thx, Armin.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Controls in anderen Forms "klauen"

Beitrag von Winni »

Hi!

Statt solch Design-Akrobatik solltest Du Dir mal TPageControl (Reiter Common Controls) ansehen. Beliebig viele Seiten jeweils mit einem Reiter. Hervorragend geeignet für den Fall, dass die Form zu voll wird.

Winni

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Controls in anderen Forms "klauen"

Beitrag von fliegermichl »

Du brauchst nur das otherform.Panel.Parent := thisform zuweisen.
Allerdings musst du aufpassen, daß du das rückgängig machst wegen der Ownerschaft.

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Controls in anderen Forms "klauen"

Beitrag von charlytango »

Überfüllung im Fenster ist immer ein Thema.
Deswegen gibt es auch immer viele Diskussionen zur Benutzerführung.

TPageControl wie winnie empfohlen hat ist sicher die erste Anlaufstelle.
https://www.andre-winkelmann.de/lazarus ... gecontrol/

Auch andere Ordnungselemente wie TTabcontrol, TScrollBox, TFlowbox kommen in Frage, sind aber komplexer zu handhaben.
Es gibt aber auch die Möglichkeit das mit Frames (TFrame) zu lösen.
https://lazarus-ccr.sourceforge.io/docs ... frame.html
https://www.andre-winkelmann.de/lazarus ... ek/tframe/
Oder auch zB ein komplettes Form samt allen darauf befindlichen Conrols und deren Funktion direkt irgendwo einzudocken bzw einzubauen.

Code: Alles auswählen

var
  owndLeft:TfrmSettingsManager;
begin

  owndLeft := TfrmSettingsManager.Create(self);

  owndLeft.DisableAlign;
  owndLeft.Align := alClient;
  owndLeft.ManualDock(PanelXY, NIL, alClient);
  owndLeft.EnableAlign;
  owndLeft.Show; 

end;  
wobei PanelXY nur ein Beispiel für ein existierendes Panel ist in das das Fenster eingebaut wird. Du kannst es zB auch in ein TTabsheet eines Pagecontrol einbauen

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Controls in anderen Forms "klauen"

Beitrag von af0815 »

Ich verwende da konsequent Frames, die erst zur Laufzeit eingebunden werden. Damut habe ich die Funktion immer mit dem Frame zusammen gebündelt und nicht ein einem ewig langen Programm versteckt. Oft habe ich auch Frame in Frame in Frame.

Ein weiterer Vorteil ist, das ich somit ein fertiges Frame öfters verwenden kann, sogar in verschiedenen Applikationen, wenn man die Schnittstellen konsequent betreibt.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Controls in anderen Forms "klauen"

Beitrag von wp_xyz »

Die einzige praktable Lösung, die übervolle Formulare in verschiedene Dateien aufspaltet, ist mit Frames zu arbeiten. Zum Beispiel ein PageControl mit 5 verschiedenen Seiten, auf denen jeweils sehr viele unterschiedliche Controls sitzen. Das alles in ein und demselben Formular zu verwalten, bedingt eine ellenlange Komponentenliste in der Formular-Deklaration, die kreuz und quer durcheinander gewürfelt ist, und sehr sehr viele Event Handler. Erzeuge stattdessen für jede Seite des PageControl einen Frame, damit wandern die dazu gehörigen Controls und deren Event-Handler in eine eigene Datei, die des Frame. Auf dem Hauptformular bleibt ein PageControl mit fünf leeren Seiten. Widerstehe dem Drang, die Frames schon zur Designzeit in die Seiten einzufügen - das geht zwar im Prinzip, aber es kann zu leicht ein Event-Handler durch einen versehentlichen Klick ausgehängt werden, so dass man lange suchen muss, warum etwas nicht funktioniert was doch funktionieren sollte. Daher immer die Frames erst zur Laufzeit erzeugen und in ihren Parent einfügen.

Der Konfigurationsdialog der IDE ist ein wunderschönes Beispiel, wie man einen extrem komplexen Dialog durch Frames entzerren und handhabbar machen kann.

Nimral
Beiträge: 390
Registriert: Mi 10. Jun 2015, 11:33

Re: Controls in anderen Forms "klauen"

Beitrag von Nimral »

fliegermichl hat geschrieben:
Fr 30. Apr 2021, 14:05
Du brauchst nur das otherform.Panel.Parent := thisform zuweisen.
Allerdings musst du aufpassen, daß du das rückgängig machst wegen der Ownerschaft.
Der Tipp scheint wirklich Gold wert zu sein, ich überlege jetzt mein komplettes Programm so zu strukturieren, als Testaufbau klappt es wunderbar. Es mag ein wenig hacky sein, aber für mich ist es bisher die einfachste Alternative zu Windows TAB Controls, die kann ich nicht einsetzen, weil deren Optik nicht den Vorstellungen des Auftraggebers entspricht. Er stellt sich - was leider in letzter Zeit Standard ist - eine an die recht primitive Web-Oberfläche seines Prortals (Bootstrap) angelehnte Optik vor.

Nicht verstanden habe ich das mit dem "rückgängig"? Owner und Parent sind doch verschiedene Properties? Ich sehe keinen Grund, am Owner etwas zu ändern.

Jedenfalls funktioniert mein Testaufbau mit folgender Struktur:

- alle Forms werden - was Lazarus per Default macht, und was mich nicht stört - in der lpr Datei geladen.

Code: Alles auswählen

begin
  RequireDerivedFormResource:=True;
  Application.Scaled:=True;
  Application.Initialize;
  Application.CreateForm(TMainFormForm, MainForm);
  Application.CreateForm(TSubForm1, SubForm1);
  Application.CreateForm(TSubform2, Subform2);
  Application.Run;
end.
Um das Panel zu wechseln, verwende ich derzeit folgenden Test-Code:

Code: Alles auswählen

procedure TMainFormForm.SpeedButton1Click(Sender: TObject);

begin
  SubForm2.PanelMain.Parent := nil;
  SubForm1.PanelMain.Parent := self;
end;

procedure TMainFormForm.SpeedButton2Click(Sender: TObject);
begin
  SubForm1.PanelMain.Parent := nil;
  SubForm2.PanelMain.Parent := self;
end;
In der produktiven Version mache ich das natürlich etwas geschickter mit einer Property "CurrentPanel" und einer Prozedur "SwapToPanel(newPanel)", die das letzte dargestellte Panel kennt und ausknipst, und dann zum newPanel wechselt. Eventuell hänge ich da auch einen Stack von Panels ein, dann kann ich sogar einen "Back" Button anbieten wenn man das auch noch für wichtig hält.

Die Akrobatik hielt sich also in Grenzen, und ist genau genommen weniger als wie wenn ich Tab oder Page Controls einsetze und versuche, denen eine bestimmte Optik aufzuzwingen.

Mein Testprogramm macht jedenfalls keine Zicken, ich habe ein paar Controls auf die Panels gesetzt, sie funktionieren alle, dehnen sich mit alClient auch brav in den freien Bereich des Hauptformulars aus, wo ich als Schaltzentrale ein mit alTop oben verankerten Streifen mit ein paar Buttons gesetzt habe, und das Programm beendet sauber ohne Leaks, es sollte also alles OK sein.

Bevor ich jetzt mein ganzes Programm umstricke (mir geht die Zeit aus - übermorgen Schlag 11 ist Abgabetermin) die Frage an euch, ob da noch jemand Bedenken hat. Es ist leider zu oft vorgekommen dass ein Ansatz abseits der Standardpfade im Testaufbau gut aussah, und nachdem ich dann Tage versenkt hatte kamen plötzlich unerwartete "Nebenwirkungen" ums Eck. Ich hab jetzt keine Tage mehr.

Armin.
Zuletzt geändert von Nimral am Mo 17. Mai 2021, 12:52, insgesamt 2-mal geändert.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Controls in anderen Forms "klauen"

Beitrag von af0815 »

Ich mache ähnliches mit Frames. Damit brauche ich nichts klauen, sondern das Frame kommt dorthin wo es Sinn macht, aber immer dynamisch einbinden, das erspart Ärger. Zusätzlich hat man die Logik und Design schön vom Rest getrennt und es lässt sich normalerweise sehr gut testen oder als Vorlage verwenden.

Jaja am Ende der Deadline bleibt immer soviel Projekt über :mrgreen:
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten