Panel.Dock Fill ignorant les autres paramètres de Panel.Dock

154

Si vous créez un panneau sur un formulaire et le définissez sur Dock = Top et déposez un autre panneau et définissez son Dock = Fill, il peut remplir tout le formulaire, en ignorant le premier panneau. La modification de l'ordre de tabulation ne fait rien.

Jeff Cuscutis
la source

Réponses:

335

La disposition d'ancrage dépend de l' ordre des contrôles frères. Les contrôles sont ancrés «bouton vers le haut», de sorte que le dernier contrôle de la collection est ancré en premier . Un contrôle ancré ne prend en compte que la disposition des frères précédemment ancrés. Par conséquent, le contrôle avec Dock = Fill doit être le premier (en haut) dans l'ordre des frères, si vous voulez qu'il prenne en compte les autres contrôles ancrés. S'il ne s'agit pas du premier contrôle, les contrôles précédents le chevaucheront.

Cela peut prêter à confusion car l'ordre des frères et sœurs n'est pas nécessairement le même que l'ordre visuel, et l'ordre des frères n'est pas toujours apparent dans la vue de conception.

La fenêtre Structure du document (Affichage -> Autres fenêtres -> Structure du document) donne une arborescence utile sur la hiérarchie et l'ordre des contrôles, et vous permet de modifier l'ordre des frères et sœurs des contrôles.

Vous pouvez également modifier l'ordre des frères et sœurs directement dans le concepteur par le menu contextuel -> Mettre au premier plan / Envoyer en arrière, ce qui déplace le contrôle pour qu'il soit le premier ou le dernier des frères. Ces étiquettes de menu peuvent être quelque peu déroutantes, car l'effet réel dépend du modèle de disposition.

Avec les contrôles positionnés fixes, la position 2D est indépendante de l'ordre des frères, mais lorsque les contrôles se chevauchent, le contrôle le plus tôt dans l'ordre sera "en haut", cachant une partie des frères plus tard dans l'ordre. Dans ce contexte, Mettre au premier plan / Envoyer en arrière a du sens.

Dans les panneaux de disposition de flux ou de tableau, l'ordre de création détermine l'ordre visuel des contrôles. Il n'y a pas de contrôles qui se chevauchent. Donc, mettre au premier plan / envoyer à l'arrière signifie vraiment faire le premier ou le dernier dans l'ordre des commandes.

Avec la disposition ancrée, le ramener au premier plan / envoyer à l'arrière peut être encore plus déroutant car il détermine dans quel ordre l'ancrage est calculé, donc "ramener au premier plan" sur un contrôle ancré au remplissage placera le contrôle au milieu du parent , en tenant compte de tous les contrôles ancrés aux bords.

JacquesB
la source
1
J'ai un panneau, une bande d'état et une bande de menus tous sur un formulaire et il semble que lorsque j'ancre la bande de menu en haut, la bande d'état en bas et remplit le panneau, le panneau ne remplit pas l'espace entre les deux bandes sauf s'il s'agit du premier frère (en haut de la fenêtre Contour du document au-dessus des deux bandes). Déplacer le panneau vers le bas (vers le «dernier») couvre les bandes. Le contrôle Dock = Fill devrait-il donc être le premier frère de la commande? Est-ce que je lis mal? J'utilise 3.5 (2008). Cela a-t-il changé?
jrsconfitto
53
tl; dr; Faites un clic droit sur le panneau avec Dock = Remplir et cliquez sur «Mettre au premier plan».
kristianp
20
+1 pour la fenêtre Plan du document. Je n'ai jamais su que cela existait, mais c'est si utile.
gligoran le
2
Comment puis-je faire cela par programme? Je veux dire, j'ajoute les contrôles de manière dynamique, donc je ne peux pas utiliser le concepteur pour faire cela.
Camilo Martin
2
@Camilo: Si vous ajoutez des contrôles dynamiquement, vous devez les ajouter dans l'ordre souhaité.
JacquesB
110

Faites un clic droit sur le panneau avec Dock = Remplir et cliquez sur «Mettre au premier plan».

Cela rend ce contrôle créé en dernier, ce qui prend en compte les paramètres du Dock sur d'autres contrôles dans le même conteneur.

Jeff Cuscutis
la source
1
Simple, aubaine, cela m'avait vraiment ennuyé
sourire narquois
Cela a du sens une fois que vous y pensez.
Gary Kindel
7

Une autre option potentiellement plus propre consiste à utiliser le contrôle TableLayout. Configurez une rangée de la hauteur souhaitée pour votre quai supérieur et une autre rangée pour remplir 100% pour votre bas. Réglez les deux panneaux à l'intérieur sur Remplir et vous avez terminé.

(TableLayout prend cependant un certain temps pour s'y habituer.)

John Rudy
la source
1
TableLayout est également plus lent que les contrôles d'ancrage pour les performances de mise en page, en particulier si vous avez des contrôles utilisateur imbriqués qui utilisent TableLayout. Cependant, cela donne une belle mise en page pour être sûr.
Nick
1
Cette performance est-elle quelque chose qu'un utilisateur moyen verrait dans un cas simple de deux panneaux, comme décrit ci-dessus? Ou est-ce quelque chose qu'ils remarquent lorsque vous avez des dizaines d'UC, tous avec des mises en page, le tout dans une seule mise en page? (Ironiquement, l'application sur laquelle je travaille actuellement est comme ça, et les performances semblent bonnes ...)
John Rudy
TableLayout est assez léger. Vous ne verrez pas de problèmes de performances si vous ne disposez que de quelques commandes.
Tim
7

J'ai eu le même problème et j'ai réussi à le résoudre.
Si vous avez un conteneur avec DockStyle.Fillles autres, vous devez également avoir DockStyle mais Top ou ce que vous voulez.
L'important est d'ajouter le contrôle avec d' DockStyle.Fillabord dans les contrôles puis les autres.

Exemple:

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);

mais si on met cb en premier

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

Si vous ne voulez pas changer l'ordre des éléments à l'intérieur du code, vous pouvez utiliser la méthode Container.Controls.SetChildIndex () avec Container étant par exemple Form, Panel, etc. auquel vous voulez ajouter vos contrôles.

Exemple:

     //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
la source
1

JacquesB a eu l'idée avec le plan du document mais la hiérarchie n'a pas résolu mon problème. Mes contrôles n'étaient pas dans un style hiérarchique, ils étaient simplement répertoriés avec le même parent.

J'ai appris que si vous modifiez l'ordre, cela corrigera l'apparence que vous souhaitez.

Les contrôles en bas de la liste chevaucheront les contrôles en haut de celle-ci dans la fenêtre Structure du document. Dans votre cas, vous vous assureriez que le premier panneau est en dessous du deuxième panneau et ainsi de suite.

RANONO
la source
0

Voici une astuce qui a fonctionné pour moi.

Placez l'élément supérieur et ancrez-le sur le dessus.

Placez un séparateur et ancrez-le également en haut, puis désactivez-le (sauf si vous souhaitez redimensionner le haut).

Placez ensuite l'objet Fill et définissez Docking sur Fill. L'objet restera sous le séparateur.

John Christman
la source
0

J'ai rencontré le même problème. Le mien était d'ajouter de nouveaux contrôles / personnalisés sous la bande de menu pendant l'exécution. Le problème était que les contrôles une fois ancrés, ont décidé de s'ancrer du haut du formulaire et d'ignorer complètement la bande de menu, très ennuyeux si vous me le demandez. Comme cela devait être fait de manière dynamique avec du code et non en mode conception, cela devenait extrêmement frustrant. Le moyen le plus simple que j'ai trouvé est de créer un panneau en mode conception et de l'ancrer sous la bande de menu. De là, vous pouvez simplement ajouter / supprimer les contrôles au panneau et vous pouvez l'ancrer pendant l'exécution. Pas besoin de jouer avec tous vos contrôles sur votre formulaire qui n'ont pas vraiment besoin de changer, trop de travail en fonction de ce que vous devez vraiment faire.

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

Je sais que c'est un vieux post mais j'ai découvert quelque chose d'utile. Pour ajuster l'ordre des contrôles frères par programme pour les contrôles créés dynamiquement, vous pouvez faire quelque chose comme:

parentForm.Controls.SetChildIndex (myPanel, 0) 

Dans mon cas, j'ai fait cela pour déplacer un panneau Dock / Fill pour qu'il soit le premier contrôle de mon formulaire afin qu'il ne se chevauche pas avec un autre contrôle ancré défini sur Dock / Top (une bande de menu).

DrLechter
la source