wpf - multi - Stackpanel: Altura frente a ActualHeight frente a ExtentHeight frente a ViewportHeight frente a DesiredSize frente a RenderSize
view uwp (2)
Como sabe, StackPanel
es un objeto [Panel]. Cada panel se comunica con sus hijos mediante dos métodos para determinar los tamaños y posiciones finales. El primer método es MeasureOverride
y el segundo es ArrangeOverride
.
MeasureOveride
pregunta a cada niño el tamaño deseado con una cantidad determinada de espacio disponible. ArrangeOverride
organiza los niños una vez que se ha completado la medición.
Vamos a crear un panel de distribución:
public class AnotherStackPanel : Panel
{
public static readonly DependencyProperty OrientationProperty =
DependencyProperty.Register(“Orientation”, typeof(Orientation),
typeof(SimpleStackPanel), new FrameworkPropertyMetadata(
Orientation.Vertical, FrameworkPropertyMetadataOptions.AffectsMeasure));
public Orientation Orientation
{
get { return (Orientation)GetValue(OrientationProperty); }
set { SetValue(OrientationProperty, value); }
}
protected override Size MeasureOverride(Size availableSize)
{
Size desiredSize = new Size();
if (Orientation == Orientation.Vertical)
availableSize.Height = Double.PositiveInfinity;
else
availableSize.Width = Double.PositiveInfinity;
foreach (UIElement child in this.Children)
{
if (child != null)
{
child.Measure(availableSize);
if (Orientation == Orientation.Vertical)
{
desiredSize.Width = Math.Max(desiredSize.Width,
child.DesiredSize.Width);
desiredSize.Height += child.DesiredSize.Height;
}
else
{
desiredSize.Height = Math.Max(desiredSize.Height,
child.DesiredSize.Height);
desiredSize.Width += child.DesiredSize.Width;
}
}
}
return desiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
double offset = 0;
foreach (UIElement child in this.Children)
{
if (child != null)
{
if (Orientation == Orientation.Vertical)
{
child.Arrange(new Rect(0, offset, finalSize.Width,
child.DesiredSize.Height));
offset += child.DesiredSize.Height;
}
else
{
child.Arrange(new Rect(offset, 0, child.DesiredSize.Width,
finalSize.Height));
offset += child.DesiredSize.Width;
}
}
}
return finalSize;
}
}
El
DesiredSize
(el tamaño devuelto porMeasureOverride
) es la suma de los tamaños secundarios en la dirección de StackPanel y el tamaño del elemento secundario más grande en la otra dirección.RenderSize
representa el tamaño final deStackPanel
vez que se completa el diseño.-
ActualHeight
es exactamente igual aRenderSize.Height
.
Para confiar en estas propiedades, debe acceder a ellas solo dentro de un controlador de eventos para el evento LayoutUpdated .
Quiero saber la altura de todos los elementos de mi StackPanel
.
Cuál es la diferencia entre:
-
Height
: obtiene o establece la altura sugerida del elemento. -
ActualHeight
- Obtiene la altura renderizada de este elemento. ( solo lectura ) -
ExtentHeight
: Obtiene un valor que contiene el tamaño vertical de la extensión. ( solo lectura ) -
ViewportHeight
: obtiene un valor que contiene el tamaño vertical de la ventana gráfica del contenido. ( solo lectura ) -
DesiredSize
- Obtiene el tamaño que este elemento calculó durante el paso de medición del proceso de diseño. ( solo lectura ) -
RenderSize
- Obtiene (o establece, pero ve Comentarios) el tamaño de renderización final de este elemento.
Desde MSDN:
Height
Obtiene o establece la altura sugerida del elemento.Valor de la propiedad:
Double
: la altura del elemento, en unidades independientes del dispositivo (1/96 de pulgada por unidad).La altura del elemento, en unidades independientes del dispositivo (1/96 de pulgada por unidad).
ActualHeight ( solo lectura )
Obtiene la altura renderizada de este elemento.Valor de la propiedad:
Double
: la altura del elemento, como un valor en unidades independientes del dispositivo (1/96 de pulgada por unidad).Esta propiedad es un valor calculado basado en otras entradas de altura, y el sistema de disposición. El valor es establecido por el propio sistema de disposición, basado en un pase de renderizado real, y por lo tanto puede quedar ligeramente por detrás del valor establecido de propiedades tales como Height que son la base del cambio de entrada.
Debido a que ActualHeight es un valor calculado, debe tener en cuenta que podría haber cambios informados múltiples o incrementales como resultado de varias operaciones realizadas por el sistema de diseño. El sistema de disposición puede calcular el espacio de medida requerido para elementos secundarios, las restricciones del elemento principal, etc.
ExtentHeight ( solo lectura )
Obtiene un valor que contiene el tamaño vertical de la extensión.Altura de la propiedad:
Double
: un doble que representa el tamaño vertical de la extensión.El valor devuelto se describe en Píxeles independientes del dispositivo.
ViewportHeight ( solo lectura )
Obtiene un valor que contiene el tamaño vertical de la ventana gráfica del contenido.Valor de la propiedad:
Double
: el doble que representa el tamaño vertical de la ventana gráfica del contenido.El valor devuelto se describe en Píxeles independientes del dispositivo.
DesiredSize ( solo lectura )
Obtiene el tamaño que este elemento calculó durante el paso de medición del proceso de diseño.Valor de propiedad:
Size
: elSize
calculado, que se convierte en el tamaño deseado para el pase de organización.El valor devuelto por esta propiedad solo será una medida válida si el valor de la propiedad IsMeasureValid es verdadero.
Normalmente, DesiredSize se comprueba como uno de los factores de medición cuando implementa anulaciones de comportamiento de diseño como ArrangeOverride, MeasureOverride o OnRender (en el caso de OnRender, puede ver RenderSize en su lugar, pero esto depende de su implementación). Dependiendo de la situación, su lógica de implementación podría respetar DesiredSize, se podrían aplicar restricciones en DesiredSize, y tales restricciones también podrían cambiar otras características del elemento padre o elemento hijo. Por ejemplo, un control que admite regiones desplazables (pero elige no derivar de los controles de nivel de marco de WPF que ya habilitan las regiones desplazables) podría comparar el tamaño disponible con el Tamaño deseado. El control podría establecer un estado interno que habilite las barras de desplazamiento en la interfaz de usuario para ese control. O, DesiredSize también podría ser ignorado en ciertos escenarios.
RenderSize Obtiene el tamaño de renderizado final de este elemento.
Valor de propiedad:
Size
: elSize
representado para este elemento.Esta propiedad se puede usar para verificar el tamaño de renderizado aplicable dentro de las anulaciones del sistema de disposición como OnRender o GetLayoutClip.
Un escenario más común es manejar el evento SizeChanged con la anulación del controlador de clase o el evento OnRenderSizeChanged.
En mi caso, quiero saber la altura deseada de todos los artículos en el StackPanel
.
En otras palabras: quiero saber la altura de todos los elementos en el StackPanel (antes del dibujo), y si se desbordaran en el panel, lo haré
- borrar
- encogimiento
- escala
- ajustar
elementos para asegurar que encajan en el StackPanel .
Lo que significa que probablemente quiera obtener la altura deseada (ExtentHeight? DesiredSize?) Durante un evento de cambio de tamaño ( SizeChanged ? LayoutUpdated ?) - antes de que ocurra un dibujo (por lo que es más rápido).
La mayoría de estas propiedades devuelven cero; así que obviamente hay una cierta comprensión de lo que significan estas propiedades que no sé y no se explican en la documentación.
La respuesta anterior es correcta, excepto que RenderSize y ActualHeight pueden tener valores temporalmente diferentes. RenderSize se establece antes de OnRender, mientras que ActualHeight se establece una vez que WPF ha terminado el diseño y procesa el procesamiento para ese control. Al final, LayoutUpdated se levanta.
Por lo tanto, RenderSize se puede usar dentro de OnRender, pero ActualHeight seguirá teniendo el valor anterior antes de que se inicie el diseño.
La secuencia se ve así:
MeasureOverride() => sets DesiredSize
ArrangeOverride() => sets RenderSize
OnRender()
WPF podría ejecutar esta secuencia varias veces (recursividad). Una vez que todo se resuelve, se ejecuta lo siguiente:
ActualHeight = RenderSize.Height
Se puede tener acceso a ActualHeight en cualquier momento (!) Después de completar el primer diseño, excepto durante el propio proceso de disposición de medida, organización y renderización. WPF garantiza que cualquier código se complete antes de que se ejecute el procesamiento de disposición.