J'ai un Grid
à l'intérieur d'un Canvas
défini comme ceci:
<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>
Mon problème est que, sur le constructeur Window, après InitializeComponents()
soit Grid.ColumnDefinitions[0].ActualWidth
Soit "tout rectangle" .ActualWidth
sont tous définis sur 0.0 (le même pour les hauteurs). Je ne sais pas quoi faire pour obtenir ces informations. De l'aide?
Observations:
Canvas/Grid
Occupe tout l'espace de la fenêtre, donc chaque rectangle à l'intérieur contient ActualWidth
s et ActualHeight
sActualHeight
et ActualWidth
ne sont pas définis tant que le contrôle n'est pas mesuré et arrangé. Habituellement, il n'y a rien dans InitializeComponent()
qui provoque une mesure, donc quand elle retourne, elles seront toujours nulles.
Vous pouvez forcer ces derniers à être calculés plus tôt en appelant simplement les méthodes Measure()
et Arrange()
de la fenêtre manuellement après le retour de la fenêtre InitializeComponent()
.
Si vous dimensionnez en fonction du contenu:
window.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
window.Arrange(new Rect(0, 0, window.DesiredSize.Width, window.DesiredSize.Height));
Si vous utilisez une taille de fenêtre explicite:
window.Measure(new Size(Width, Height));
window.Arrange(new Rect(0, 0, window.DesiredSize.Width, window.DesiredSize.Height));
Ray a raison (+1) que cela est dû au fait que la mesure et l'arrangement n'ont pas encore été exécutés. Cependant, plutôt que de forcer une autre passe de mise en page (coûteuse), vous pouvez simplement attendre que votre contrôle soit chargé avant d'accéder aux propriétés ActualXxx
:
public MyWindow()
{
Loaded += delegate
{
// access ActualWidth and ActualHeight here
};
}
Dans notre cas, la solution était simple, comme tout le monde a dit que ActualWidth et ActualHeight devaient être appelés après la fin de Loaded, nous avons donc simplement enveloppé le code dans un répartiteur et défini la priorité sur Loaded comme ci-dessous:
Dispatcher.Invoke(new Action(() =>
{
graphHeight = ActualHeight;
graphWidth = ActualWidth;
}), DispatcherPriority.Loaded);