Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Collapsible Margins (https://www.delphipraxis.net/201208-collapsible-margins.html)

mael 2. Jul 2019 05:32

Collapsible Margins
 
Hallo,

Es gibt seit einiger Zeit die Margins-Eigenschaft für jedes Steuerelement, aber zwei benachbarte Steuerelement werden ihre Margins nicht verschmelzen, sondern addieren.

Bei CSS gibt es collapsible margins, zumindest für vertikal angeordnete Block-Element.

Auf Delphi übertragen:

Nun möchte ich horizontal z.B. 3 Steuerelemente ausrichten die alle den gleichen Abstand zueinander haben. Dafür setze ich Margins.Left und Margins.Right auf jeweils 10 und aktiviere AlignWithMargins. Das funktioniert gut für die Ränder, also dort wo die Steuerelemente auf die Fensterränder treffen. Der Leerraum zwischen zwei benachbarten Steuerelementen (A und B) wird nun aber 20, da sich A.Margins.Right und B.Margins.Left addieren, anstatt zu 10 zu verschmelzen.

Man kann natürlich rumpfuschen, und nur Margins.Left auf 10 setzten (Margins.Right aber auf 0), und dann beim letzten Steuerelement in der Liste Margins.Right auf 10 setzen. Aber der Punkt ist dass die Ausrichtung automatisch funktionieren soll, auch wenn die Reihenfolge der Steuerelemente sich ändert.

Hat jemand einen Weg gefunden dass in der VCL zu erreichen?

Mein Ansatz war TMargins zu überschreiben (und dann den Steuerelementen zuzuweisen).

Aber wie findet man heraus was das benachbarte Steuerelement sein wird, während des Alignments?

peterbelow 2. Jul 2019 12:37

AW: Collapsible Margins
 
Zitat:

Zitat von mael (Beitrag 1435775)
Hallo,

Es gibt seit einiger Zeit die Margins-Eigenschaft für jedes Steuerelement, aber zwei benachbarte Steuerelement werden ihre Margins nicht verschmelzen, sondern addieren.

Bei CSS gibt es collapsible margins, zumindest für vertikal angeordnete Block-Element.

Auf Delphi übertragen:

Nun möchte ich horizontal z.B. 3 Steuerelemente ausrichten die alle den gleichen Abstand zueinander haben. Dafür setze ich Margins.Left und Margins.Right auf jeweils 10 und aktiviere AlignWithMargins. Das funktioniert gut für die Ränder, also dort wo die Steuerelemente auf die Fensterränder treffen. Der Leerraum zwischen zwei benachbarten Steuerelementen (A und B) wird nun aber 20, da sich A.Margins.Right und B.Margins.Left addieren, anstatt zu 10 zu verschmelzen.

Man kann natürlich rumpfuschen, und nur Margins.Left auf 10 setzten (Margins.Right aber auf 0), und dann beim letzten Steuerelement in der Liste Margins.Right auf 10 setzen. Aber der Punkt ist dass die Ausrichtung automatisch funktionieren soll, auch wenn die Reihenfolge der Steuerelemente sich ändert.

Hat jemand einen Weg gefunden dass in der VCL zu erreichen?

Mein Ansatz war TMargins zu überschreiben (und dann den Steuerelementen zuzuweisen).

Aber wie findet man heraus was das benachbarte Steuerelement sein wird, während des Alignments?

Ich mach das so: Margins.Left = 5, Margins.Right = 5, Padding.Left und Padding.Right des Parents = 5. Wenn man es nur mit den Margins macht muss man das erste oder letzte Control gesondert behandeln, oder sich eine custom Parent (panel oder so) schnitzen, der das Alignment per Kode übernimmt. Für ein Control selbst sehe ich keine (einfache) Möglichkeit, herauszufinden, wo in der Positionierungssequenz es sich befindet.

dataspider 4. Jul 2019 08:10

AW: Collapsible Margins
 
Zitat:

Zitat von mael (Beitrag 1435775)

Man kann natürlich rumpfuschen, und nur Margins.Left auf 10 setzten (Margins.Right aber auf 0), und dann beim letzten Steuerelement in der Liste Margins.Right auf 10 setzen.

Und alle Steuerelemente in ein Panel packen mit Margins.Right := 10; ?

Frank

mael 6. Jul 2019 16:14

AW: Collapsible Margins
 
Zitat:

Zitat von dataspider (Beitrag 1435962)
Und alle Steuerelemente in ein Panel packen mit Margins.Right := 10; ?

Zum Beispiel. Aber der linke Abstand würde dann fehlen.

Zitat:

Zitat von peterbelow (Beitrag 1435811)
Für ein Control selbst sehe ich keine (einfache) Möglichkeit, herauszufinden, wo in der Positionierungssequenz es sich befindet.

Nach längerem Studium vom Delphi-Quelltext, ist mir aufgefallen dass alle Layout-Panel sich auf die CM_CONTROLLISTCHANGING Message verlassen und dann intern eine Liste verwalten.
Für ein Grid-Panel wäre dann z.B. die Zuordnung von Listen-Index zu Spalte/Zeile mit einer Art mod/div-Rechnung erledigt, als Pseudocode:
Code:
Row = Index div ColsPerRow;
Col = Index mod ColsPerRow;
Danke für die Antworten.

Ich habe mich entschieden in einem Descendant von TCustomControl das Layout zu übernehmen, analog zu TGridPanel und ähnlichen Steuerelementen.

Ist für meinem konkreten Fall wohl das Einfachste. Etwas schade dass die VCL das nicht einfacher macht. Aber WPF und CSS sind da auch umständlich, auch wenn es da zumindest "dirty hacks" gibt.

Uwe Raabe 6. Jul 2019 23:40

AW: Collapsible Margins
 
Peter hatte doch schon die Lösung beschrieben:
Zitat:

Zitat von peterbelow (Beitrag 1435811)
Margins.Left = 5, Margins.Right = 5, Padding.Left und Padding.Right des Parents = 5.

Damit haben die Controls einen Abstand von 10 zueinander und auch zu den Rändern. Notfalls kann man auch noch ein TPanel als Parent dazwischen legen.

mael 7. Jul 2019 18:30

AW: Collapsible Margins
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1436199)
Peter hatte doch schon die Lösung beschrieben:
Zitat:

Zitat von peterbelow (Beitrag 1435811)
Margins.Left = 5, Margins.Right = 5, Padding.Left und Padding.Right des Parents = 5.

Damit haben die Controls einen Abstand von 10 zueinander und auch zu den Rändern. Notfalls kann man auch noch ein TPanel als Parent dazwischen legen.

Das Problem ist dass ich für jedes Control die Abstände eigenständig ausdrücken will, und nicht den Parent einbeziehen will um Ausgleichsrechnungen manuell vorzunehmen, sonst muss ich wieder eine globale Routine schreiben die alles miteinander abgleicht.

Für das Beispiel würde es funktionieren, aber es sind nicht immer 10 Pixel zwischen allen Controls und dem Fensterrand. Es kann im allgemeinen Fall variieren, und dann muss man wieder wissen welches Control wohinkommt, damit man das Parent.Padding richtig anpasst. Man muss also immer abgleichen mit allen anderen Controls/Parent um zu sehen was man korrigieren muss.

Uwe Raabe 7. Jul 2019 20:22

AW: Collapsible Margins
 
Ist XE3 deine aktuelle Delphi-Version?

In neueren gibt es das TRelativePanel mit ein paar interessanten Möglichkeiten zur Positionierung der Controls.


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