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

And*_*ena 43 wpf grid xaml 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>
Run Code Online (Sandbox Code Playgroud)

我的问题是,在窗口的构造,后InitializeComponents()两种Grid.ColumnDefinitions[0].ActualWidth或"任何矩形".ActualWidth都被设置为0.0(高度相同).我不知道如何获取这些信息.有帮助吗?

观察:

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

Ray*_*rns 77

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));
Run Code Online (Sandbox Code Playgroud)

如果您使用明确的窗口大小:

window.Measure(new Size(Width, Height));
window.Arrange(new Rect(0, 0, window.DesiredSize.Width, window.DesiredSize.Height));
Run Code Online (Sandbox Code Playgroud)

  • 不确定"DesiredWidth"之前是否有效,但较新版本的.NET使用DesiredSize.Width和DesiredSize.Height (12认同)

Ken*_*art 65

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

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

}
Run Code Online (Sandbox Code Playgroud)

  • 等待加载是一个好主意(+1),并且在大多数情况下都可以使用.但请注意,当您从未连接到PresentationSource(即,您从未显示窗口)时,将永远不会调用Loaded.我之前遇到过这种情况,例如在决定是否在页面上包含控件时.所以我会说使用Loaded会更好,并且涵盖所有情况,否则使用Measure/Arrange会更好.也就是说,在90%的情况下,最佳做法是完全远离ActualWidth/ActualHeight.(例如,更多/更好的面板,绑定到高度/宽度,MeasureOverride) (3认同)
  • 同意.等待加载是更好的方法恕我直言. (2认同)