Почему ActualWidth и ActualHeight 0.0 в этом случае?
У меня есть Grid
внутри 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 - Ширина / высота сетки привязана к холсту, но я попытался удалить эту привязку, и моя проблема все еще сохраняется.
4 ответа
ActualHeight
а также ActualWidth
не устанавливаются до тех пор, пока контроль не будет измерен и установлен. Обычно там ничего нет InitializeComponent()
это вызывает меру, поэтому, когда он возвращает, они все равно будут равны нулю.
Вы можете заставить их вычисляться раньше, просто вызывая окно Measure()
а также Arrange()
методы вручную после окна InitializeComponent()
возвращается.
Если вы оцениваете содержание:
window.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
window.Arrange(new Rect(0, 0, window.DesiredSize.Width, window.DesiredSize.Height));
Если вы используете явный размер окна:
window.Measure(new Size(Width, Height));
window.Arrange(new Rect(0, 0, window.DesiredSize.Width, window.DesiredSize.Height));
Рэй прав (+1), что это связано с тем, что мера и аранжировка еще не выполнены. Однако вместо принудительного выполнения другого прохода макета (дорого) вы можете просто подождать, пока ваш элемент управления загрузится, прежде чем получить доступ к ActualXxx
свойства:
public MyWindow()
{
Loaded += delegate
{
// access ActualWidth and ActualHeight here
};
}
В нашем случае решение было простым, поскольку все говорили, что ActualWidth и ActualHeight необходимо вызывать после завершения Loaded, поэтому мы просто обернули код в диспетчер и установили приоритет Loaded, как показано ниже:
Dispatcher.Invoke(new Action(() =>
{
graphHeight = ActualHeight;
graphWidth = ActualWidth;
}), DispatcherPriority.Loaded);
ActualWidth
а также ActualHeight
доступны только после завершения загрузки XAML, до загрузки, как вы можете найти эти параметры?
Используйте событие Loaded и внутри него найдите ActualWidth
а также ActualHeight
,
private void me_Loaded(object sender, RoutedEventArgs e)
{
// do your stuffs here.
}