wpf xaml autolayout autoresize dockpanel

wpf - ¿Cómo hacer que los hijos de StackPanel ocupen el máximo espacio hacia abajo?



xaml autolayout (5)

Simplemente quiero un texto fluido a la izquierda y un cuadro de ayuda a la derecha.

La caja de ayuda debe extenderse hasta el fondo.

Si sacas el StackPanel exterior a continuación, funciona bien.

Pero por razones de diseño (estoy insertando UserControls dinámicamente) necesito tener el StackPanel de ajuste.

¿Cómo puedo hacer que el GroupBox se extienda hasta la parte inferior del StackPanel, como puedes ver?

  • VerticalAlignment = "Stretch"
  • VerticalContentAlignment = "Stretch"
  • Altura = "Auto"

XAML:

<Window x:Class="TestDynamic033.Test3" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Test3" Height="300" Width="600"> <StackPanel VerticalAlignment="Stretch" Height="Auto"> <DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="Auto" Margin="10"> <GroupBox DockPanel.Dock="Right" Header="Help" Width="100" Background="Beige" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch" Height="Auto"> <TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap" /> </GroupBox> <StackPanel DockPanel.Dock="Left" Margin="10" Width="Auto" HorizontalAlignment="Stretch"> <TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/> </StackPanel> </DockPanel> </StackPanel> </Window>

Responder:

Gracias Mark, usar DockPanel en lugar de StackPanel lo ha solucionado. En general, me encuentro usando DockPanel más y más ahora para el diseño de WPF, aquí está el XAML corregido:

<Window x:Class="TestDynamic033.Test3" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Test3" Height="300" Width="600" MinWidth="500" MinHeight="200"> <DockPanel VerticalAlignment="Stretch" Height="Auto"> <DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="Auto" MinWidth="400" Margin="10"> <GroupBox DockPanel.Dock="Right" Header="Help" Width="100" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch" Height="Auto"> <Border CornerRadius="3" Background="Beige"> <TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap" Padding="5"/> </Border> </GroupBox> <StackPanel DockPanel.Dock="Left" Margin="10" Width="Auto" HorizontalAlignment="Stretch"> <TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/> </StackPanel> </DockPanel> </DockPanel> </Window>


La razón por la que esto está sucediendo es porque el panel de la pila mide todos los elementos secundarios con infinito positivo como la restricción para el eje sobre el que está apilando los elementos. Los controles secundarios deben devolver el tamaño que desean (el infinito positivo no es un retorno válido de MeasureOverride en ninguno de los ejes), por lo que devuelven el tamaño más pequeño donde todo encaja. No tienen forma de saber cuánto espacio realmente tienen que llenar.

Si su vista no necesita tener una función de desplazamiento y la respuesta anterior no satisface sus necesidades, sugeriría que implemente su propio panel. Probablemente pueda derivar directamente de StackPanel y luego todo lo que tendrá que hacer es cambiar el método ArrangeOverride para que divida el espacio restante entre sus elementos secundarios (dándoles a cada uno la misma cantidad de espacio adicional). Los elementos deberían quedar bien si se les da más espacio del que querían, pero si les das menos, comenzarás a ver fallos.

Si quieres poder desplazarte por completo, me temo que las cosas serán un poco más difíciles, ya que el ScrollViewer te brinda una cantidad infinita de espacio para trabajar, lo que te pondrá en la misma posición que los elementos secundarios. originalmente. En esta situación, es posible que desee crear una nueva propiedad en su nuevo panel que le permita especificar el tamaño de la ventana gráfica, debe poder vincular esto al tamaño del ScrollViewer. Lo ideal sería implementar IScrollInfo , pero eso comienza a complicarse si se va a implementar todo correctamente.


Parece que quieres un StackPanel donde el elemento final utiliza todo el espacio restante. Pero, ¿por qué no usar un DockPanel ? Decora los otros elementos en el DockPanel con DockPanel.Dock="Top" , y luego tu control de ayuda puede llenar el espacio restante.

XAML:

<DockPanel Width="200" Height="200" Background="PowderBlue"> <TextBlock DockPanel.Dock="Top">Something</TextBlock> <TextBlock DockPanel.Dock="Top">Something else</TextBlock> <DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="Auto" Margin="10"> <GroupBox DockPanel.Dock="Right" Header="Help" Width="100" Background="Beige" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch" Height="Auto"> <TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap" /> </GroupBox> <StackPanel DockPanel.Dock="Left" Margin="10" Width="Auto" HorizontalAlignment="Stretch"> <TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/> </StackPanel> </DockPanel> </DockPanel>

Si está en una plataforma sin DockPanel disponible (por ejemplo, WindowsStore), puede crear el mismo efecto con una cuadrícula. Aquí está el ejemplo anterior realizado utilizando grillas en su lugar:

<Grid Width="200" Height="200" Background="PowderBlue"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel Grid.Row="0"> <TextBlock>Something</TextBlock> <TextBlock>Something else</TextBlock> </StackPanel> <Grid Height="Auto" Grid.Row="1" Margin="10"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="100"/> </Grid.ColumnDefinitions> <GroupBox Width="100" Height="Auto" Grid.Column="1" Background="Beige" Header="Help"> <TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap"/> </GroupBox> <StackPanel Width="Auto" Margin="10" DockPanel.Dock="Left"> <TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/> </StackPanel> </Grid> </Grid>


Puedes usar la versión modificada de StackPanel:

<st:StackPanel Orientation="Horizontal" MarginBetweenChildren="10" Margin="10"> <Button Content="Info" HorizontalAlignment="Left" st:StackPanel.Fill="Fill"/> <Button Content="Cancel"/> <Button Content="Save"/> </st:StackPanel>

El primer botón se llenará.

Puedes instalarlo a través de Nuget:

Install-Package SpicyTaco.AutoGrid

También recomiendo echar un vistazo a wpf-autogrid . Es muy útil para formularios en WPF en lugar de DockPanel, StackPanel y Grid y resuelve problemas con estiramientos muy fácil y con gracia. Basta con mirar léame en github.

<st:AutoGrid Columns="160,*" ChildMargin="3"> <Label Content="Name:"/> <TextBox/> <Label Content="E-Mail:"/> <TextBox/> <Label Content="Comment:"/> <TextBox/> </st:AutoGrid>


Un método alternativo es usar una cuadrícula con una columna y n filas. Establezca todas las alturas de las filas en Auto y la altura de la fila más baja en 1* .

Prefiero este método porque he encontrado que Grids tiene mejor rendimiento de diseño que DockPanels, StackPanels y WrapPanels. Pero a menos que los esté utilizando en una plantilla de artículo (donde el diseño se está realizando para una gran cantidad de artículos), probablemente nunca lo notará.


Un par de cosas que podrías hacer:

1: Establecer la Orientation en vertical :

<StackPanel Orientation="Vertical"></StackPanel>

  1. Establezca la Height del StackPanel en la misma ventana que:

Y, por supuesto, puedes combinar esas propiedades :

<StackPanel Orientation="Vertical" Height="600"></StackPanel>

No necesita hacer un montón de trabajo adicional con la instalación de NuGets y todo eso ...

EDITAR

También puede colocar el StackPanel dentro de un ScrollViewer. Esto le permitirá controlar la altura del cuadro de grupo sin sacrificar la visibilidad del contenido.

<GroupBox> <ScrollViewer> <StackPanel Orientation="Vertical> <!-- Place Children Objects here--> <StackPanel> <ScrollViewer> <GroupBox>