web-dev-qa-db-ja.com

この場合、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(高さでも同じ)に設定されることです。私はこの情報を得るために何をすべきかを考えていません。何か助け?

観察:

  1. 外側のキャンバスの幅と高さを定義していませんが、定義しても問題は解決しません。
  2. 実行時に、この_Canvas/Grid_がウィンドウスペース全体を占めるため、その中のすべての長方形にはActualWidthsとActualHeightsが含まれることがわかります。
  3. グリッドの幅/高さはキャンバスにバインドされていますが、このバインドを削除しようとしましたが、問題は解決しません。
41
André Pena

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));
76
Ray Burns

これは、測定とアレンジパスがまだ実行されていないという事実によるものです。ただし、別のレイアウトパスを強制する(高価な)のではなく、ActualXxxプロパティにアクセスする前にコントロールが読み込まれるまで待つことができます。

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

}
62
Kent Boogaart

この場合、ソリューションはシンプルで、Loadedが完了した後でもActualWidthとActualHeightを呼び出す必要があると誰もが言ったため、次のようにコードをディスパッチャにラップし、優先順位をLoadedに設定しました。

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