Подтвердить что ты не робот

Почему ActualWidth и ActualHeight 0.0 в этом случае?

У меня есть Grid внутри a Canvas, как это:

<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>

Моя проблема заключается в том, что в конструкторе Window после InitializeComponents() либо Grid.ColumnDefinitions[0].ActualWidth, либо "любой прямоугольник". ActualWidth все установлены на 0.0 (то же самое для высот). Я не понимаю, что делать, чтобы получить эту информацию. любая помощь?

замечания:

  • Я не определяю ширину и высоту внешнего холста, но если да, это не решает мою проблему.
  • Во время выполнения я вижу, что это Canvas/Grid занимает все пространство окна, поэтому каждый прямоугольник внутри него имеет ActualWidth и ActualHeight s
  • Ширина/высота сетки привязана к холсту, но я попытался удалить эту привязку, и моя проблема сохранилась.
4b9b3361

Ответ 1

ActualHeight и ActualWidth не устанавливаются до тех пор, пока элемент управления не будет измерен и не будет установлен. Обычно в InitializeComponent() нет ничего, что вызывает меру, поэтому, когда она вернет их, все равно будет 0.

Вы можете заставить их быть вычисленными ранее, просто вызвав методы окна Measure() и Arrange() вручную после возврата окна InitializeComponent().

Если вы определяете размер содержимого:

window.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
window.Arrange(new Rect(0, 0, window.DesiredWidth, window.DesiredHeight));

Если вы используете явный размер окна:

window.Measure(new Size(Width, Height));
window.Arrange(new Rect(0, 0, window.DesiredWidth, window.DesiredHeight));

Ответ 2

Рэй правильный (+1), что это связано с тем, что мера измерения и аранжировки еще не выполнена. Однако вместо того, чтобы принудительно переносить другой макет (дорогой), вы можете просто дождаться загрузки вашего элемента управления до доступа к свойствам ActualXxx:

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

}

Ответ 3

В нашем случае решение было простым, так как все сказали, что ActualWidth и ActualHeight необходимо вызвать после завершения Loaded, Поэтому мы просто завернули код в диспетчере и установили приоритет Loaded, как показано ниже:

Dispatcher.Invoke(new Action(() =>
{
   graphHeight = ActualHeight;
   graphWidth = ActualWidth;
}), DispatcherPriority.Loaded);

Ответ 4

ActualWidth и ActualHeight доступны только после завершения загрузки XAML перед загрузкой, как вы можете найти эти параметры?

Используйте Loaded event и внутри него найдите ActualWidth и ActualHeight.

private void me_Loaded(object sender, RoutedEventArgs e)
{
  // do your stuffs here.
}