Panel.Dock Fill ignorando otras configuraciones de Panel.Dock

154

Si crea un panel en un formulario y lo configura en Dock = Top y suelta otro panel y establece su Dock = Fill, puede llenar todo el formulario, ignorando el primer panel. Cambiar el orden de tabulación no hace nada.

Jeff Cuscutis
fuente

Respuestas:

335

El diseño de acoplamiento depende del orden de los controles hermanos. Los controles están acoplados "botón arriba", por lo que el último control de la colección se acopla primero . Un control acoplado solo tiene en cuenta el diseño de los hermanos acoplados previamente . Por lo tanto, el control con Dock = Fill debe ser el primero (arriba) en el orden de hermanos, si desea que tenga en cuenta los otros controles acoplados. Si no es el primer control, los controles anteriores lo superpondrán.

Esto puede ser confuso porque el orden entre hermanos no es necesariamente el mismo que el orden visual, y el orden entre hermanos no siempre es evidente en la vista de diseño.

La ventana Esquema del documento (Ver -> Otras ventanas -> Esquema del documento) ofrece una vista de árbol útil sobre la jerarquía y el orden de los controles, y le permite cambiar el orden de los controles entre hermanos.

También puede cambiar el orden de los hermanos directamente en el diseñador mediante el menú contextual -> Traer al frente / Enviar al fondo, que mueve el control para que sea el primero o el último de los hermanos. Estas etiquetas de menú pueden ser algo confusas ya que el efecto real depende del modelo de diseño.

Con los controles de posición fija, la posición 2D es independiente del orden de los hermanos, pero cuando los controles se superponen, el control más temprano en el orden estará "arriba", ocultando parte de los hermanos más adelante en el orden. En este contexto, traer al frente / Enviar al fondo tiene sentido.

Dentro de los paneles de diseño de flujo o tabla, el orden de creación determina el orden visual de los controles. No hay controles superpuestos. Por lo tanto, traer al frente / enviar hacia atrás realmente significa hacer primero o último en el orden de los controles.

Con el diseño acoplado, traer al frente / enviar hacia atrás puede ser aún más confuso ya que determina en qué orden se calcula el acoplamiento, por lo que "traer al frente" en un control de relleno colocado colocará el control en el medio del padre , teniendo en cuenta todos los controles acoplados al borde.

JacquesB
fuente
1
Tengo un panel, una tira de estado y una tira de menú en un formulario, y parece que cuando acople la tira de menú en la parte superior, la tira de estado en la parte inferior y llene el panel, el panel no llena el espacio entre dos tiras a menos que sea el primer hermano (en la parte superior de la ventana Esquema del documento encima de las dos tiras). Mover el panel hacia abajo (hacia "último") cubre las tiras. Entonces, ¿el control Dock = Fill debería ser el primer hermano en el orden? ¿Estoy leyendo esto mal? Estoy usando 3.5 (2008). ¿Cambió esto?
jrsconfitto
53
tl; dr; Haga clic derecho en el panel con Dock = Fill y haga clic en 'Traer al frente'.
kristianp
20
+1 para la ventana del esquema del documento. Nunca supe que esto existía, pero es muy útil.
gligoran
2
¿Cómo puedo hacer esto programáticamente? Quiero decir, estoy agregando los controles dinámicamente para que no pueda usar el diseñador para hacer esto.
Camilo Martin
2
@Camilo: Si agrega controles dinámicamente, debe agregarlos en el orden que desee.
JacquesB
110

Haga clic derecho en el panel con Dock = Fill y haga clic en 'Traer al frente'.

Esto hace que este control se cree en último lugar, lo que tiene en cuenta la configuración de Dock en otros controles en el mismo contenedor.

Jeff Cuscutis
fuente
1
Simple, Dios mío, esto realmente me había estado molestando
smirkingman
Tiene sentido una vez que lo piensas.
Gary Kindel
7

Otra opción potencialmente más limpia es utilizar el control TableLayout. Configure una fila de la altura deseada para su muelle superior y otra fila para llenar el 100% de su fondo. Establezca ambos paneles en el interior para Rellenar, y listo.

(Sin embargo, a TableLayout le cuesta acostumbrarse).

John Rudy
fuente
1
TableLayout también es más lento que los controles de acoplamiento para el rendimiento del diseño, especialmente si tiene controles de usuario anidados que usan TableLayout. Sin embargo, produce un buen diseño para estar seguro.
Nick
1
¿Es este rendimiento algo que un usuario promedio vería en un caso simple de dos paneles, como se describió anteriormente? ¿O es algo que notan cuando tienes docenas de UC, todas con diseños, todo en un diseño? (Irónicamente, la aplicación en la que estoy trabajando actualmente es así, y el rendimiento parece estar bien ...)
John Rudy
TableLayout es bastante ligero. No verá problemas de rendimiento si solo presenta algunos controles.
Tim
7

Tuve el mismo problema y logré resolverlo.
Si tiene un contenedor con DockStyle.Filllos demás, también debe tener DockStyle pero Top o lo que desee.
Lo importante es agregar el control DockStyle.Fillprimero en Controles y luego en los demás.

Ejemplo:

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

pero si ponemos cb primero

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

Si no desea cambiar el orden de los elementos dentro del código, puede usar el método Container.Controls.SetChildIndex () con Container como, por ejemplo, Formulario, Panel, etc. al que desea agregar sus controles.

Ejemplo:

     //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
fuente
1

JacquesB tuvo la idea con el esquema del documento, pero la jerarquía no resolvió mi problema. Mis controles no estaban en un estilo jerárquico, solo se enumeraron con el mismo padre.

Aprendí que si cambiaste el orden, se solucionará la forma en que quieres que se vea.

Los controles en la parte inferior de la lista se superpondrán a los controles en la parte superior de la ventana Esquema del documento. En su caso, debe asegurarse de que el primer panel esté debajo del segundo panel y así sucesivamente.

RANONO
fuente
0

Aquí hay un truco que funcionó para mí ...

Coloque el elemento superior y acóplelo en la parte superior.

Coloque un divisor, y también acóplelo en la parte superior, luego configúrelo deshabilitado (a menos que desee cambiar el tamaño de la parte superior).

Luego, coloque el objeto Relleno y establezca Acoplamiento en Relleno. El objeto permanecerá debajo del divisor.

John Christman
fuente
0

Me encontré con el mismo problema. El mío fue agregar controles nuevos / personalizados debajo de la tira del menú durante el tiempo de ejecución. El problema era que los controles cuando se acoplaban, decidían acoplarse desde la parte superior del formulario e ignoraban por completo la tira del menú, muy molesto si me preguntas. Como esto tenía que hacerse dinámicamente con código y no durante el modo de diseño, esto se volvió extremadamente frustrante. La forma más simple que encontré es crear un panel durante el modo de diseño y acoplarlo debajo de la tira del menú. Desde allí, solo puede agregar / quitar los controles al panel y puede acoplarlo durante el tiempo de ejecución. No es necesario meterse con todos los controles en su formulario que realmente no necesitan cambiar, demasiado trabajo dependiendo de lo que realmente necesita hacer.

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

Sé que esta es una publicación antigua pero descubrí algo útil. Para ajustar el orden de control entre hermanos mediante programación para los controles creados dinámicamente, puede hacer algo como:

parentForm.Controls.SetChildIndex (myPanel, 0) 

En mi caso, hice esto para mover un panel Dock / Fill para que sea el primer control en mi formulario para que no se superponga con otro control dock configurado en Dock / Top (una tira de menú).

DrLechter
fuente