Pourquoi ActualWidth et ActualHeight 0.0 dans ce cas?

j'ai un Grid dans un Canvas définit 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 de Fenêtre, après InitializeComponents()Grid.ColumnDefinitions[0].ActualWidth ou "tout rectangle".ActualWidth 0.0 (même pour des hauteurs). Je ne suis pas déterminer ce qu'il faut faire pour obtenir cette information. Toute aide?

Observations:

  1. Je ne définit pas la largeur et la hauteur de la toile extérieure, mais si je le fais, cela ne résout pas mon problème.
  2. à l'exécution je peux voir que ce Canvas/Grid occupe tout l'espace de la fenêtre, donc chaque rectangle à l'intérieur a ActualWidthet ActualHeight s
  3. la largeur/hauteur de la grille est liée à la toile mais j'ai essayé d'enlever cette reliure et mon problème persiste toujours.
36
demandé sur Sibbo 2009-11-08 05:04:09

4 réponses

ActualHeight et ActualWidth ne sont pas réglés tant que la commande n'est pas mesurée et réglée. Habituellement, il n'y a rien dans InitializeComponent() qui provoque une mesure, donc quand elle retourne celles-ci seront toujours zéro.

vous pouvez les forcer à être calculés plus tôt en appelant simplement la fenêtre Measure() et Arrange() méthodes manuellement après la fenêtre InitializeComponent() retourne.

Si vous êtes dimensionnement de 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));
71
répondu Ray Burns 2018-01-04 04:59:33

Ray a raison (+1) que ceci est dû au fait que la mesure et arranger passer n'a pas encore exécuté. Cependant, plutôt que de forcer un autre pass de mise en page (cher), vous pouvez simplement attendre jusqu'à ce que votre contrôle soit chargé avant d'accéder au ActualXxx propriétés:

public MyWindow()
{
    Loaded += delegate
    {
        // access ActualWidth and ActualHeight here
    };

}
57
répondu Kent Boogaart 2011-09-27 15:17:28

dans notre cas, la solution était simple, car tout le monde a dit Qu'ActualWidth et ActualHeight devaient être appelés après que le chargé ait même terminé, Donc nous avons juste enveloppé le code dans un répartiteur et placé la priorité à Chargé comme ci-dessous:

Dispatcher.Invoke(new Action(() =>
{
   graphHeight = ActualHeight;
   graphWidth = ActualWidth;
}), DispatcherPriority.Loaded);
1
répondu Gabriel 2017-03-21 15:24:12

ActualWidth et ActualHeight sont disponibles seulement après le chargement XAML terminé, avant le chargement Comment Pouvez-vous trouver ces paramètres?

utilisez L'événement chargé et à l'intérieur de celui-ci trouvez le ActualWidth et ActualHeight.

private void me_Loaded(object sender, RoutedEventArgs e)
{
  // do your stuffs here.
}
-6
répondu Rahul Saksule 2013-06-13 15:35:18