¿Cómo usar DockStyle.Fill para controles estándar en WPF?

92

Estoy acostumbrado a los formularios de Windows, que creo un panel, coloco controles dentro de él y les doy el DockStyle.Fillmáximo de tamaño al panel circundante.

En WPF quiero tener lo mismo. Tengo un TabControl y quiero que su tamaño llene la mayor parte del formulario posible. Tengo un control de cinta (RibbonControlsLibrary) y quiero que el resto del formulario se complete con TabControl en el tamaño máximo.

(No quiero acoplar controles como el acoplamiento en Visual Studio, solo viejos mecanismos de acoplamiento)

citronas
fuente

Respuestas:

181

El equivalente de WPF de DockStyle.Fill de WinForms es:

HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

Este es el valor predeterminado para casi los controles, por lo que, en general, no tiene que hacer nada para que un control WPF llene su contenedor principal : lo hacen automáticamente. Esto es cierto para todos los recipientes que no aprietan a sus hijos al tamaño mínimo.

Errores comunes

Ahora explicaré varios errores comunes que impiden que HorizontalAlignment="Stretch" VerticalAlignment="Stretch"funcione como se esperaba.

1. Alto o ancho explícito

Un error común es especificar explícitamente un Ancho o Alto para un control. Entonces, si tienes esto:

<Grid>
  <Button Content="Why am I not filling the window?" Width="200" Height="20" />
  ...
</Grid>

Simplemente elimine los atributos Ancho y Alto:

<Grid>
  <Button Content="Ahhh... problem solved" />
  ...
</Grid>

2. El panel de contención reduce el control al tamaño mínimo

Otro error común es hacer que el panel de contención apriete su control tanto como sea posible. Por ejemplo, un StackPanel vertical siempre exprimirá su contenido verticalmente tan pequeño como sea posible:

<StackPanel>
  <Button Content="Why am I squished flat?" />
</StackPanel>

Cambie a otro Panel y estará listo para comenzar:

<DockPanel>
  <Button Content="I am no longer squished." />
</DockPanel>

Además, cualquier fila o columna de la cuadrícula cuya altura sea "Auto" exprimirá de manera similar su contenido en esa dirección.

Algunos ejemplos de recipientes que no aprietan a sus hijos son:

  • ContentControls nunca aprieta a sus hijos (esto incluye Border, Button, CheckBox, ScrollViewer y muchos otros)
  • Cuadrícula con una sola fila y columna
  • Cuadrícula con filas y columnas de tamaño "*"
  • DockPanel no aprieta a su último hijo
  • TabControl no aprieta su contenido

Algunos ejemplos de recipientes que sí exprimen a sus hijos son:

  • StackPanel aprieta en su dirección de orientación
  • La cuadrícula con una fila o columna de tamaño "automático" se aprieta en esa dirección
  • DockPanel aprieta a todos menos a su último hijo en la dirección de su muelle
  • TabControl aprieta su encabezado (lo que se muestra en la pestaña)

3. Alto o ancho explícito más lejos

Es asombroso cuántas veces veo Grid o DockPanel con una altura y un ancho explícitos, como este:

<Grid Width="200" Height="100">
  <Button Content="I am unnecessarily constrainted by my containing panel" />
</Grid>

En general, nunca querrá darle a ningún Panel una Altura o Anchura explícita. Mi primer paso al diagnosticar problemas de diseño es eliminar cada Alto o Ancho explícito que pueda encontrar.

4. La ventana es SizeToContent cuando no debería ser

Cuando usa SizeToContent, su contenido se reducirá al tamaño mínimo. En muchas aplicaciones esto es muy útil y es la elección correcta. Pero si su contenido no tiene un tamaño "natural", probablemente querrá omitir SizeToContent.

Ray Burns
fuente
Dejé una pregunta relacionada con el diseño nuevo bastante compleja aquí . Después de leer su respuesta aquí, estoy pensando que puede resolverlo. Saludos
Berryl
7
¡Excelente respuesta! Ojalá pudiera darte puntos de bonificación de alguna manera. :)
Jim Raden
@Jim Raden: Puede agregar una recompensa a esta pregunta y asignar los puntos a Ray Burns;)
citronas
1
Nota al margen para futuros lectores: no se actualizará en la vista de diseño hasta que vuelva a compilar.
David
"<Button Content =" ¿Por qué no estoy llenando la ventana? "Width =" 200 "Height =" 20 "/>" ¡me hizo reír! XD
Jack Frost
7

¡Puede hacer lo que quiera con solo decir DockPanel LastChildFill="True"y luego asegurarse de que lo que quiere que sea el relleno sea en realidad el último hijo!

La cuadrícula es la bestia de un diseño que puede hacer que haga casi cualquier cosa, pero DockPanel suele ser la elección correcta para su panel de diseño más externo. Aquí hay un ejemplo de psuedocode:

<DockPanel LastChildFill="True">
    <MyMenuBar DockPanel.Dock="Top"/>
    <MyStatus DockPanel.Dock="Bottom"/>

    <MyFillingTabControl />
</DockPanel>
Berryl
fuente
5

simplemente envuelva sus controles en una cuadrícula con dos filas. La cuadrícula utilizará automáticamente todo el espacio que se le haya asignado y puede definir las filas para que ocupen todo el espacio restante dándoles una altura de "*". La primera fila en mi ejemplo (Altura = "Auto") ocupará tanto espacio como necesite la cinta. Espero que ayude.

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>

  <Ribbon Grid.Row="0" />

  <TabPage Grid.Row="1" />
</Grid>

Al agregar el atributo "Grid.Row = .." a los controles secundarios de la cuadrícula, se asignan a filas de la cuadrícula. Luego, la cuadrícula tendrá el tamaño de sus hijos según lo definido por las definiciones de fila.

andyp
fuente
Va en la dirección correcta, gracias. Logré insertar el Grid, pero ahora necesito decirle al TabControl que debe usar todo el tamaño que todavía está disponible. ¿Cómo puedo lograrlo?
citronas
Debe agregar el atributo "Grid.Row" para el TabControl y dar a la definición de fila correspondiente una altura de "*", tal como se muestra en el ejemplo.
andyp
0

Intenté muchos métodos aquí pero no puedo resolver mi problema. (Llene otro control en control)

Hasta que encontré que

<Name_Control Height="auto" Width="auto"/>
//default
//HorizontalAlignment="Stretch" 
//VerticalAlignment="Stretch"

Ejemplo:

//UserControl:
<UserControl Name="UC_Test" Height="auto" Width="auto" />
//Grid: 
<Grid Name="Grid_test" Grid.ColumnSpan="2" Grid.Row="2" />
//Code: 
Grid_test.Children.Add(UC_Test);

Para un diseño sencillo

<UserControl Name="UC_Test" Height="100" Width="100" />
//Code
Grid_test.Children.Add(UC_Test);
UC_Test.Width = Double.NaN;
UC_Test.Height = Double.NaN;
Trương Quốc Khánh
fuente