2008-08-30 18 views
256

Algunos controles WPF (como el Button) parecen consumir alegremente todo el espacio disponible en su contenedor si no especifica la altura que debe tener.¿Cómo obtener controles en WPF para llenar el espacio disponible?

Y algunos, como los que necesito usar en este momento, el (multilínea) TextBox y el ListBox parecen más preocupados por solo tomar el espacio necesario para ajustar sus contenidos, y nada más.

Si coloca estos tipos en una celda en un UniformGrid, se expandirán para ajustarse al espacio disponible. Sin embargo, las instancias UniformGrid no son adecuadas para todas las situaciones. ¿Qué sucede si tiene una cuadrícula con algunas filas establecidas a * altura para dividir la altura entre ella y otras * filas? ¿Qué sucede si tiene un StackPanel y tiene un Label, un List y un Button, cómo puede hacer que la lista ocupe todo el espacio que no se come con la etiqueta y el botón?

Creo que esto sería realmente un requisito de diseño básico, pero no puedo encontrar la manera de conseguir que llenen el espacio que podrían (ponerlos en un DockPanel y configurarlo para que no funcione también , parece, ya que el DockPanel solo ocupa el espacio que necesitan sus 'subcontroles'.

Una interfaz gráfica de usuario de tamaño variable sería bastante horrible si había que jugar con Height, Width, MinHeight, etc. MinWidth

Se puede obligar a sus Height y Width propiedades a la celda de la cuadrícula que ocupan? ¿O hay otra manera de hacer esto?

+1

UniformGrid es increíble, Mi nueva etiqueta goto predeterminada. Me gustó la simplicidad de Stackpanels (me recuerda a un div) pero Uniform Grid hace exactamente lo que necesito. – Terrance

Respuesta

134

Cada control derivada de Panel implementa la lógica de diseño distinto realiza en Measure() y Arrange():

  • Measure() determina el tamaño del panel y cada uno de sus hijos
  • Arrange() determina el rectángulo donde hace cada control

El último hijo de DockPanel llena el espacio restante. Puede deshabilitar este comportamiento estableciendo la propiedad LastChild en false.

StackPanel pregunta a cada niño por el tamaño deseado y luego los apila. El panel de pila llama al Measure() en cada niño, con un tamaño disponible de Infinity y luego utiliza el tamaño deseado del niño.

Un Grid ocupa todo el espacio disponible, sin embargo, se fijará cada niño a su tamaño deseado y centrarlos en la célula.

Puede implementar su propia lógica de disposición derivando de Panel y luego anulando MeasureOverride() y ArrangeOverride().

Vea this article para un ejemplo simple.

+4

El enlace está ahora muerto – user3690202

+3

@ user3690202 Archive.org es tu amigo. Enlace reanimado. – ruffin

+0

El tema todavía existe en MSDN, pero el enlace cambió a esto: https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/how-to-create-a-custom-panel-element –

14

Bueno, me di cuenta, justo después de la publicación, que es la forma más vergonzosa. :)

Parece que cada miembro de un StackPanel simplemente completará su tamaño mínimo requerido.

En el DockPanel, había atracado las cosas en el orden incorrecto. Si el TextBox o ListBox es el único elemento acoplado sin una alineación, o si son los últimos agregados, LLEGARÁN el espacio restante como se desee.

Me encantaría ver un método más elegante para manejar esto, pero servirá.

+0

Solo quiero señalar (sobre esta vieja pregunta!) Que "sin una alineación" es una frase clave aquí, al menos fue para mí. –

188

También hay algunas propiedades que puede configurar para forzar un control para llenar su espacio disponible cuando de otro modo no lo haría. Por ejemplo, puede decir:

HorizontalContentAlignment="Stretch" 

... forzar el contenido de un control para estirar horizontalmente. O puede decir:

HorizontalAlignment="Stretch" 

... forzar el control a sí mismo para estirar horizontalmente para llenar su elemento primario.

+63

El panel más notorio mencionado en todos estos casos es el StackPanel. No contiene propiedades de ContentAlignment y configurar sus hijos en Stretch no tendrá ningún efecto dentro de una cuadrícula de tamaño de estrella. Muy frustrante. Es casi como si el StackPanel fuera el primer contenedor que el equipo de WPF escribió y sufre que ese sea el caso. –

+3

@Brent - ahh! Me he quedado atrapado intentando que los contenidos de mi stackpanel se llenen correctamente. ¡Gracias! Pensé que era algo que estaba haciendo muy mal. –

+6

@townsean El panel de pila es muy limitado, puede obtener un comportamiento similar con el estiramiento usando un UniformGrid y establecer Filas o Columnas en 0 – ForbesLindesay

0

Utilice HorizontalAlignment y VerticalAlignment propiedades de diseño. Controlan cómo un elemento usa el espacio que tiene dentro de su elemento primario cuando hay más espacio disponible del requerido por el elemento.

El ancho de un StackPanel, por ejemplo, será tan ancho como el elemento más ancho que contenga. Entonces, todos los elementos más estrechos tienen un poco de exceso de espacio. Las propiedades de alineación controlan qué hace el elemento secundario con el espacio adicional.

El valor predeterminado para ambas propiedades es Estirar, por lo que el elemento secundario se estira para llenar todo el espacio disponible. Las opciones adicionales incluyen Left, Center y Right para HorizontalAlignment y Top, Center and Bottom para VerticalAlignment.

+24

Si esto siempre fue cierto, la pregunta original no se habría formulado. Tomemos, por ejemplo, un StackPanel horizontal con una etiqueta y un TextBox. Hay espacio adicional a la derecha del TextBox. TextBox está establecido en Ancho automático. Establecer Stretch para HorizontalAlignment no hará que TextBox llene el espacio restante. –

Cuestiones relacionadas