为什么在这种情况下ActualWidth和ActualHeight为0.0?

时间:2009-11-08 02:04:09

标签: wpf xaml grid actualwidth actualheight

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(高度相同)。我不知道如何获取这些信息。有什么帮助吗?

观察:

  1. 我没有定义外部画布的宽度和高度,但如果我这样做,则无法解决我的问题。
  2. 在运行时,我可以看到此Canvas/Grid占据整个窗口空间,因此其中的每个矩形都有ActualWidth s和ActualHeight s
  3. 网格的宽度/高度绑定到画布,但我尝试删除此绑定,我的问题仍然存在。

4 个答案:

答案 0 :(得分:76)

在测量和排列控件之前,不会设置

ActualHeightActualWidth。通常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 :(得分:61)

Ray是正确的(+1),这是因为测量和安排传递尚未执行。但是,不要强制执行另一个布局传递(昂贵),您可以等到控件加载后再访问ActualXxx属性:

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

}

答案 2 :(得分:2)

在我们的例子中,解决方案很简单,因为每个人都说在加载完成后需要调用ActualWidth和ActualHeight, 所以我们只是将代码包装在一个调度程序中,并将优先级设置为Loaded,如下所示:

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

答案 3 :(得分:-6)

ActualWidthActualHeight仅在XAML加载完成后才可用,在加载之前如何找到这些参数?

使用已加载的事件,在其中找到ActualWidthActualHeight

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