¿Por qué son ActualWidth y ActualHeight 0.0 en este caso?
-
18-09-2019 - |
Pregunta
Tengo un Grid
en el interior de un Canvas
definida de la siguiente forma:
<Canvas x:Name="outerCanvas">
<Grid Grid.Row="1" Name="cGrid" ShowGridLines="True" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}" Height="{Binding Path=ActualHeight, RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Rectangle Name="rectangle1" Stroke="Black" Fill="AntiqueWhite" />
<Rectangle Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="1" Grid.RowSpan="1" Name="rectangle2" Stroke="Black" Fill="AliceBlue" />
<Rectangle Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="1" Grid.RowSpan="1" Name="rectangle3" Stroke="Black" Fill="Aqua" />
<Rectangle Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Grid.RowSpan="1" Name="rectangle4" Stroke="Black" Fill="DarkViolet" />
</Grid>
</Canvas>
Mi problema es que, en la Ventana del constructor, después de InitializeComponents()
ya sea Grid.ColumnDefinitions[0].ActualWidth
o "cualquier rectángulo".ActualWidth
a 0.0 (la misma de las alturas).No estoy pensando qué hacer para obtener esta información.Alguna ayuda?
Observaciones:
- No estoy de definir el exterior de lona de la anchura y la altura, pero si lo hago, no resuelve mi problema.
- En tiempo de ejecución puedo ver que esta
Canvas/Grid
ocupa todo el espacio de la ventana, por lo que cada rectángulo dentro de ella tieneActualWidth
s yActualHeight
s - La cuadrícula de la anchura/altura está vinculado a la lona, pero he probado la eliminación de esta unión, y mi problema persiste.
Solución
ActualHeight
y ActualWidth
no se establecen hasta que se mide y dispuesto el control. Por lo general, no hay nada en InitializeComponent()
que causa una medida, por lo que cuando vuelve éstos todavía será cero.
Puede forzar a estos a ser computado anteriormente, simplemente llamando a Measure()
y Arrange()
métodos de la ventana manualmente después vuelve InitializeComponent()
de la ventana.
Si está de tamaño para el contenido:
window.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
window.Arrange(new Rect(0, 0, window.DesiredSize.Width, window.DesiredSize.Height));
Si está usando un tamaño de ventana explícito:
window.Measure(new Size(Width, Height));
window.Arrange(new Rect(0, 0, window.DesiredSize.Width, window.DesiredSize.Height));
Otros consejos
Ray es correcto (1) que esto se debe al hecho de que la medida y organizar pase no ha ejecutado todavía. Sin embargo, en lugar de obligar a otro pase diseño (caro), puede simplemente esperar hasta que su control haya cargado antes de acceder a las propiedades ActualXxx
:
public MyWindow()
{
Loaded += delegate
{
// access ActualWidth and ActualHeight here
};
}
En nuestro caso, la solución era simple, como todo el mundo dice ActualWidth y ActualHeight necesitaban ser llamado después de la cargada incluso completa, Así que acaba de terminar el código en un despachador y establecer la prioridad de carga como a continuación:
Dispatcher.Invoke(new Action(() =>
{
graphHeight = ActualHeight;
graphWidth = ActualWidth;
}), DispatcherPriority.Loaded);
ActualWidth
y ActualHeight
están disponibles sólo después de XAML carga completada, antes de cargar cómo se puede encontrar estos parámetros?
El uso Cargado evento y el interior es lo que hace encontrar el ActualWidth
y ActualHeight
.
private void me_Loaded(object sender, RoutedEventArgs e)
{
// do your stuffs here.
}