Почему 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
- Ширина/высота сетки привязана к холсту, но я попытался удалить эту привязку, и моя проблема сохранилась.
Ответы
Ответ 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.
}