align Anordnungsproblem
-
Hallo zusammen habe ein für mich durchaus verwirrendes Problem, ich versuche eine Anzahl Panels in einem übergeordneten Panel in einer bestimmten Reihenfolge anzuzeigen und das über alTop, da noch ein weiteres Panel vorhanden ist das Standardmäßig immer am untersten Punkt liegt.
Mein Problem besteht darin das ich die Panels nicht in der richtigen Reihenfolge angeordnet bekomme. Wenn ich z.b Panels a,b,c,d habe möchte ich sie anordnen als
a,b,c,d.
Liste ist eine TWinControl liste, die die Elemente in der Reihenfolge a,b,c,d beinhaltet.{ TPanel *Parent; list<TWinControl*>::iterator tmp = Liste.begin(); if ( tmp != Liste.end()) { TWinControl *Panel = (*tmp)->Parent; Parent = dynamic_cast<TPanel*> (Panel); }else { return; } for ( tmp ; tmp != Liste.end(); tmp++){ (*tmp)->Hide(); (*tmp)->Parent = Form1 ; (*tmp)->Top = 0; (*tmp)->Align = alTop; } tmp = Liste.begin(); for ( tmp ; tmp != Liste.end(); tmp ++){ (*tmp)->Parent = Parent; (*tmp)->Show(); }
Daraus folgt dann natürlich die Reihenfolge d,c,b,a also genau umgekehrt wie es sein soll. Wenn ich den Show Teil anders rum durchlaufen lasse wie hier gezeigt
list<TWinControl*>::reverse_iterator itr = Liste.rbegin(); for ( itr ; itr != Liste.rend(); itr++) { (*itr)->Parent = Parent; (*itr)->Show(); }
bekomme ich aber die Reihenfolge a,d,b,c.
Bei zwei Elementen geht es noch: a,b
Bei drei Elementen passiert schon der Dreher: a,c,bVerzweifele langsam an diesen mistigen align Befehlen, leider wird der Align top für eine dynamische Größenanpassung benötigt, da die Panels zur Laufzeit immer ihre Größe ändern. Vielleicht kann mich ja jemand erleuchten wo mein Denkfehler liegt.
Danke schonmal im voraus
stuempi
-
Kannst du mal bitte die Code-Tags benutzen, sonst bekommt man ja Augenkrebs!
-
Wie sollen die Panels genau angeordnet sein? Eins oben, zwei nebeneinander in der mitte und eins unten?
Genereller Tip: Ich mach das bei mir immer so (für obiges Szenario), dass ich die nebeneinander liegenden Panel auf ein darunter liegendes Panel platziere. Also drei übereinander und auf das mittlere davon, die beiden, die nebeneinander liegen sollen.
Entsprechend für die horizontalen Panels alTop, alClient und alBottom verwenden und falls in einem dieser Panels, nebeneinander liegende Panels sein sollen, dann alLeft oder alRight und alClient verwenden. Hat bisher immer prima funktioniert.
Bei Bedarf setze ich noch jeweils einen Splitter zwischen die Panels, oder berechne die Größe zur Laufzeit.
-
die sollen eigentlich nur untereinander liegen, jedoch eine bestimmte Reihenfolge haben, die Objekte werden halt immer zur Laufzeit erschaffen bzw. gelöscht, sollen jedoch immer eine feste Reihenfolge haben.
-
Hallo,
Du könntest natürlich auch leere Panels als zusätzlichen Container
verwenden. Jede Komponente wird dann mit alTop eingefügt und unten
drunter jeweils eine leeres Panel mit alClient. Im Panel dann wieder
das gleiche Spiel. Hier mal ein Versuch der grafischen Veranschaulichung:+--------------------+
|+------------------+|
|| Component 1 ||
|+------------------+|
|+------------------+|
|| Dummy Panel ||
||+----------------+||
||| Component 2 |||
||+----------------+||
||+----------------+||
||| Dummy Panel |||
|||+--------------+|||
|||| Component 3 ||||
|||+--------------+|||
||+----------------+||
|+------------------+|
+--------------------+Für die letzte Komponente brauchst Du kein zusätzliches Panel, sondern
fügst sie einfach mit alClient ein.Natürlich hast Du dann zusätzliche (eigentlich unnötige) Panels, aber
dafür kannst Du wenigstens sicher sein, dass die Reihenfolge nicht von
irgendwelchen Zufällen abhängt.Gruß
Alexander
-
Ich versteh den Zweck der ganzen Übung immer noch nicht. Willst Du zur Laufzeit die Panels zu einem anderen Parent-Panel verschieben?
-
Hi,
nicht unbedingt, das kann zwar auch vorkommen dürfte aber nicht zum Problem werden. Also es geht darum, ich schreibe an einem Editor bei dem man durch Drag und Drop Objekte zusammenziehen kann die auf Panels sitzen. Diese Panels sollen untereinander beim erzeugen angeordnet werden. Jedoch können diese Panels auch jederzeit ihre Größe ändern ( da man auf diese Panels selbst wieder einwirken kann) Das Problem ist, dass die Panels häufig beim Größe ändern ihre Position mit Nachbarn tauschen, was nicht vorkommen soll. Deswegen möchte ich nach Aktionen die Liste neu anordnen damit dieses wilde hüpfen der Panels beim größe ändern aufhört.
Jedoch scheint die Align Funktion auch häufiger mal das zu tun was sie will, jedoch hab ich noch nicht ganz verstanden warum sie wenn man objekte nacheinander top aligned diese nicht in der Reihenfolge behält in der sie aligned werden. Es soll später einfach so aussehen und ich will es jederzeit wieder so anordnen können. Jedoch klappt das leider irgendwie nicht (siehe oben)übergeordnetes Panel
_______
||Pan1||
|--------|
||Pan2||
|--------|
||Pan3||
||Pan3||
|--------|
||Pan4||
|--------|
|______|stuempi
-
tschuldigung wollte keinen doppelpost
-
eventuell gehts ja so
bool cmp(const TWinControl *&a, const TWinControl *&b) { return a->Tag < b->Tag; } void __fastcall TForm1::Button1Click(TObject *Sender) { TPanel *Parent; list<TWinControl*>::iterator tmp = Liste.begin(); int top = 0; Liste.sort(cmp); for ( tmp ; tmp != Liste.end(); tmp++) { (*tmp)->Hide(); (*tmp)->Top = top; top += (*tmp)->Height; (*tmp)->Align = alTop; (*tmp)->Show(); } }
Das Problem ist der Wert für Top, wenn der immer 0 ist setzt er das Panel vor die anderen. Die Eigenschaft Tag muß beim Erstellen der Panels mit einer fortlaufenden (der Reihenfolge entsprechenden) Zahl gefüllt werden, nach dieser wird dann sortiert.
das was du in Zeile 4-7 und 19 machst versteh ich allerdings nicht, dort wird ein Element als Parent definiert und alle anderen Panels sollen darauf dargestellt werden oder wie?
-
Hi,
danke für die Antwort
in Zeile 4-7 / 19 hatte ich ne Zeitlang die Vermutung dass der seine Sortierung intern irgendwie über seine Controls macht, deswegen habe ich die dann einfach immer neu alle hinzugefügt.
Die Liste liegt immer in der richtigen Reihenfolge vor und kann aus einer beliebigen Richtung durchlaufen werden.
Das Problem ist das er eben nicht wenn Top = 0 gesetzt ist das Element vorne dranhängt, sondern ab und an einfach das irgendwo zwischenquetscht. Ich glaube das Align intern noch nach irgend einem anderen Schema handelt was ich aber bisher noch nicht finden konnte, da ich durchaus eine Reihenfolge d,c,b,a hergestellt bekomme, jedoch wenn ich die Elemente von der anderen Richtung durchlaufe keine Reihenfolge a,b,c,d bekomme (Obwohl sonst alles identisch bleibt). Das ist eigentlich mein Hauptproblem das ich nicht verstehe wonach dieses nette Align wirklich auswählt wie es etwas setzt.
Und der Quelltext einen Post drüber führt leider nur zu den gleichen Verwürfelungen wie das Rückwärtsdurchlaufen.stuempi