1

WPF で興味深いことに出くわしましたが、これを自分で説明することはできません。

その奇妙な振る舞い。

タイトルは基本的にすべてを説明しています。

これは、Grid.Visibility を Collapsed に設定し、その Grid 内のコントロールのメジャーを無効にする例です。wpfでは表示されないコントロールは測定されていないため、コントロールは再測定されるべきではないと考えられていました。

public class MyControl : Button
{
    public MyAnotherControl AnotherControl
    {
        get;
        set;
    }

    public Grid Grid
    {
        get;
        set;
    }

    protected override Size MeasureOverride(Size constraint)
    {
        base.MeasureOverride(constraint);
        return new Size(100, 20);
    }

    protected override Size ArrangeOverride(Size arrangeBounds)
    {
        base.ArrangeOverride(arrangeBounds);
        return arrangeBounds;
    }

    protected override void OnClick()
    {
        Grid.Visibility = Visibility.Collapsed;
        AnotherControl.InvalidateMeasure();
        base.OnClick();
    }
}

これは、グリッド内にある別のコントロールです。

public class MyAnotherControl : Button
{
    protected override Size MeasureOverride(Size constraint)
    {
        base.MeasureOverride(constraint);
        Console.WriteLine("Measure called");
        return new Size(100, 10);
    }

    protected override Size ArrangeOverride(Size arrangeBounds)
    {
        base.ArrangeOverride(arrangeBounds);
        return arrangeBounds;
    }
}

これは XAML です。

    <Grid>
        <StackPanel>
            <local:MyControl Background="Blue" Grid="{x:Reference grid}" AnotherControl="{x:Reference anotherControl}"/>
            <Grid x:Name="grid">
                <local:MyAnotherControl Content="{Binding}" Background="Red" x:Name="anotherControl"/>
            </Grid>
        </StackPanel>
    </Grid>

ご覧のとおり、OnClick で Grid.Visibility を変更し、グリッドの内部コントロールの測定値を無効にします。

MSDNによると:

Visibility が Visible でない要素は、入力イベント (またはコマンド) に関与せず、レイアウトの測定または配置パスに影響を与えず、タブ シーケンスにも含まれず、ヒット テストで報告されません。

http://msdn.microsoft.com/en-us/library/system.windows.uielement.visibility.aspx

問題は、MyAnotherControl が測定されるべきではないのになぜ測定されているのかということです。

最初から折りたたまれているグリッドにコードを変更すると、測定を無効にするときに MyAnotherControl が再測定されなくなります。これは正しい wpf 動作を表します。

    <Grid>
        <StackPanel>
            <local:MyControl Background="Blue" Grid="{x:Reference grid}" AnotherControl="{x:Reference anotherControl}"/>
            <Grid x:Name="grid" Visibility="Collapsed">
                <local:MyAnotherControl Content="{Binding}" Background="Red" x:Name="anotherControl"/>
            </Grid>
        </StackPanel>
    </Grid>

Visibility を最初から設定するかどうかで違いが生じるようです。

何か案は?皆さんの提案やアイデアに感謝します。

4

1 に答える 1