Panel.Dock Fill ignoriert andere Panel.Dock-Einstellungen

154

Wenn Sie ein Bedienfeld in einem Formular erstellen und es auf Dock = Oben setzen und ein anderes Bedienfeld ablegen und Dock = Füllen festlegen, wird möglicherweise das gesamte Formular ausgefüllt, wobei das erste Bedienfeld ignoriert wird. Das Ändern der Tabulatorreihenfolge führt zu nichts.

Jeff Cuscutis
quelle

Antworten:

335

Das Docking-Layout hängt von der Reihenfolge der Geschwistersteuerelemente ab. Steuerelemente werden "Button-up" angedockt, sodass das letzte Steuerelement in der Sammlung zuerst angedockt wird . Ein angedocktes Steuerelement übernimmt nur das Layout von zuvor angedockter Geschwister. Daher sollte das Steuerelement mit Dock = Fill in der Geschwisterreihenfolge an erster Stelle (oben) stehen, wenn die anderen angedockten Steuerelemente berücksichtigt werden sollen. Wenn es nicht das erste Steuerelement ist, überlappen es frühere Steuerelemente.

Dies kann verwirrend sein, da die Reihenfolge der Geschwister nicht unbedingt mit der visuellen Reihenfolge übereinstimmt und die Reihenfolge der Geschwister aus der Entwurfsansicht nicht immer ersichtlich ist.

Das Dokumentumrissfenster (Ansicht -> Andere Fenster -> Dokumentumriss) bietet eine nützliche Baumansicht über die Steuerelementhierarchie und -reihenfolge und ermöglicht es Ihnen, die Geschwisterreihenfolge von Steuerelementen zu ändern.

Sie können die Reihenfolge der Geschwister auch direkt im Designer über das Kontextmenü ändern -> Nach vorne bringen / Nach hinten senden, wodurch das Steuerelement als erstes oder letztes der Geschwister verschoben wird. Diese Menübezeichnungen können etwas verwirrend sein, da der tatsächliche Effekt vom Layoutmodell abhängt.

Bei fest positionierten Steuerelementen ist die 2D-Position unabhängig von der Reihenfolge der Geschwister. Wenn sich die Steuerelemente jedoch überlappen, befindet sich das früheste Steuerelement in der Reihenfolge "oben" und verbirgt einen Teil der Geschwister später in der Reihenfolge. In diesem Zusammenhang ist Bring to Front / Send to Back sinnvoll.

In Flow- oder Table-Layout-Panels bestimmt die Erstellungsreihenfolge die visuelle Reihenfolge der Steuerelemente. Es gibt keine überlappenden Steuerelemente. Nach vorne bringen / nach hinten senden bedeutet also, zuerst oder zuletzt in der Reihenfolge der Steuerelemente zu machen.

Bei angedocktem Layout kann das Bringen nach vorne / Senden nach hinten noch verwirrender sein, da es bestimmt, in welcher Reihenfolge das Andocken berechnet wird. Wenn Sie also bei einem angedockten Steuerelement nach vorne bringen, wird das Steuerelement in der Mitte des übergeordneten Steuerelements platziert unter Berücksichtigung aller kantengedockten Steuerelemente.

JacquesB
quelle
1
Ich habe ein Panel, eine Statusleiste und eine Menüleiste in einem Formular und es scheint, dass wenn ich die Menüleiste oben andocke, die Statusleiste unten andocke und das Panel ausfülle, das Panel nicht den Raum zwischen den Feldern ausfüllt zwei Streifen, es sei denn, es ist das erste Geschwister (oben im Fenster "Dokumentübersicht" über den beiden Streifen). Bewegen Sie das Bedienfeld nach unten (in Richtung "Letzte"), um die Streifen abzudecken. Sollte das Dock = Fill-Steuerelement tatsächlich das erste Geschwister in der Bestellung sein? Lese ich das falsch Ich benutze 3.5 (2008). Hat sich das geändert?
jrsconfitto
53
tl; dr; Klicken Sie mit der rechten Maustaste auf das Bedienfeld mit Dock = Füllen und klicken Sie auf "Nach vorne bringen".
Kristianp
20
+1 für das Dokumentumrissfenster. Ich wusste nie, dass es das gibt, aber es ist so nützlich.
Gligoran
2
Wie kann ich das programmatisch machen? Ich meine, ich füge die Steuerelemente dynamisch hinzu, damit ich den Designer nicht dazu verwenden kann.
Camilo Martin
2
@Camilo: Wenn Sie Steuerelemente dynamisch hinzufügen, sollten Sie sie in der gewünschten Reihenfolge hinzufügen.
JacquesB
110

Klicken Sie mit der rechten Maustaste auf das Bedienfeld mit Dock = Füllen und klicken Sie auf "Nach vorne bringen".

Dadurch wird dieses Steuerelement zuletzt erstellt, wobei die Dock-Einstellungen für andere Steuerelemente im selben Container berücksichtigt werden.

Jeff Cuscutis
quelle
1
Einfach, Godsend, das hatte mich wirklich geärgert
grinsender
Sinnvoll, wenn Sie darüber nachdenken.
Gary Kindel
7

Eine andere, möglicherweise sauberere Option ist die Verwendung des TableLayout-Steuerelements. Richten Sie eine Reihe mit der gewünschten Höhe für Ihr oberes Dock und eine weitere Reihe ein, um 100% für Ihr unteres Dock zu füllen. Stellen Sie beide Bedienfelder auf Füllen ein, und Sie sind fertig.

(TableLayout ist allerdings gewöhnungsbedürftig.)

John Rudy
quelle
1
TableLayout ist auch langsamer als das Andocken von Steuerelementen für die Layoutleistung, insbesondere wenn Sie verschachtelte Benutzersteuerelemente haben, die TableLayout verwenden. Es ergibt jedoch ein schönes Layout, um sicher zu sein.
Nick
1
Ist diese Leistung etwas, das ein durchschnittlicher Benutzer in einem einfachen Fall von zwei Panels sehen würde, wie oben beschrieben? Oder ist es etwas, das sie bemerken, wenn Sie Dutzende von UCs haben, alle mit Layouts, alle in einem Layout? (Ironischerweise ist die App, an der ich gerade arbeite, so und die Leistung scheint in Ordnung zu sein ...)
John Rudy
TableLayout ist ziemlich leicht. Sie werden keine Leistungsprobleme sehen, wenn Sie nur ein paar Steuerelemente anlegen.
Tim
7

Ich hatte das gleiche Problem und konnte es lösen.
Wenn Sie einen Container mit DockStyle.Fillden anderen haben, sollten Sie auch DockStyle aber Top oder was auch immer Sie wollen haben.
Das Wichtigste ist, das Steuerelement DockStyle.Fillzuerst mit den Steuerelementen und dann mit den anderen hinzuzufügen .

Beispiel:

ComboBox cb = new ComboBox();
cb.Dock =  DockStyle.Top;

GridView gv = new GridView();
gv.Dock =  DockStyle.Fill;

Controls.Add(gv); // this is okay
Controls.Add(cb);

aber wenn wir cb zuerst setzen

Controls.Add(cb);
Controls.Add(gv); // gv will overlap the combo box.
Pandichie Anton-Valentin
quelle
2

Wenn Sie die Reihenfolge der Elemente im Code nicht ändern möchten, können Sie die Methode Container.Controls.SetChildIndex () verwenden, wobei Container das z. B. Formular, Bedienfeld usw. ist, zu dem Sie Ihre Steuerelemente hinzufügen möchten.

Beispiel:

     //Container ------------------------------------
     Panel Container = new Panel();

     //Top-Docked Element ---------------------------
     ButtonArea = new FlowLayoutPanel();
     Container.Controls.Add(ButtonArea);
     Container.Controls.SetChildIndex(ButtonArea, 1);
     ButtonArea.Dock = DockStyle.Top;

     //Fill-Docked Element --------------------------
     box = new RichTextBox();
     Container.Controls.Add(box);
     Container.Controls.SetChildIndex(box, 0); //setting this to 0 does the trick
     box.Dock = DockStyle.Fill;
Marcus
quelle
1

JacquesB hatte die Idee mit der Dokumentskizze, aber die Hierarchie löste mein Problem nicht. Meine Steuerelemente hatten keinen hierarchischen Stil, sondern wurden nur mit demselben übergeordneten Element aufgelistet.

Ich habe erfahren, dass wenn Sie die Reihenfolge ändern, die Art und Weise festgelegt wird, wie sie aussehen soll.

Die Steuerelemente am unteren Rand der Liste überlappen die Steuerelemente oben im Fenster "Dokumentübersicht". In Ihrem Fall würden Sie sicherstellen, dass sich das erste Feld unter dem zweiten Feld befindet und so weiter.

RANONO
quelle
0

Hier ist ein Trick, der für mich funktioniert hat ..

Platzieren Sie das oberste Element und docken Sie es oben an.

Platzieren Sie einen Splitter, docken Sie ihn oben an und deaktivieren Sie ihn (es sei denn, Sie möchten die Größe des Oberteils ändern).

Platzieren Sie dann das Füllobjekt und setzen Sie Docking auf Füllen. Das Objekt bleibt unter dem Splitter.

John Christman
quelle
0

Ich bin auf das gleiche Problem gestoßen. Meins war das Hinzufügen neuer / benutzerdefinierter Steuerelemente unterhalb der Menüleiste zur Laufzeit. Das Problem war, dass die Steuerelemente beim Andocken beschlossen, vom oberen Rand des Formulars aus anzudocken und die Menüleiste vollständig zu ignorieren. Sehr ärgerlich, wenn Sie mich fragen. Da dies dynamisch mit Code und nicht im Entwurfsmodus erfolgen musste, wurde dies äußerst frustrierend. Der einfachste Weg, den ich gefunden habe, besteht darin, im Entwurfsmodus ein Bedienfeld zu erstellen und unter der Menüleiste anzudocken. Von dort aus können Sie einfach die Steuerelemente zum Bedienfeld hinzufügen / daraus entfernen und es zur Laufzeit andocken. Sie müssen sich nicht mit all Ihren Steuerelementen in Ihrem Formular herumschlagen, die sich nicht wirklich ändern müssen. Je nachdem, was Sie wirklich tun müssen, ist zu viel Arbeit erforderlich.

object.dock = Fill
Panel.Controls.Add(object)
Robert S.
quelle
0

Ich weiß, dass dies ein alter Beitrag ist, aber ich habe etwas Nützliches entdeckt. Um die Reihenfolge der Geschwistersteuerung programmgesteuert für dynamisch erstellte Steuerelemente anzupassen, können Sie Folgendes tun:

parentForm.Controls.SetChildIndex (myPanel, 0) 

In meinem Fall habe ich dies getan, um ein Dock / Fill-Bedienfeld als erstes Steuerelement in meinem Formular zu verschieben, damit es sich nicht mit einem anderen angedockten Steuerelement überschneidet, das auf Dock / Top (eine Menüleiste) eingestellt ist.

DrLechter
quelle