3

正方形のボタンの単純なグリッドが必要な XAML/C# で WinRT アプリを作成しています。ボタンの数は現在固定ですが、今後コンテンツを作成するにつれて、ボタンの数を増やしていく予定です。

すべてのUIのサイズ変更(スナップ、塗りつぶし、ポートレートなど)と解像度を処理する必要があり、アスペクトを制約する方法がわからないため、UIContainer(を使用してGridから切り替えた)でボタンのサイズを自動的に変更するだけで問題が発生しましたWrapGrid比率と正方形のボタンを持つことは、私の UI にとって重要です。

ボタン コントロールの幅と高さの縦横比/比率を制限する方法はありますか? もしそうなら、カスタム コントロールを作成することになると思いますが、スタイルとデータ テンプレートを作成すること以外は、本当に理解が深まりません。

この問題に対処する最善の方法について何か提案はありますか?

4

3 に答える 3

3

ArrangeOverride次のように、オーバーライドして常に正方形に配置する単純なデコレータ コントロールを作成できます。

public class SquareDecorator : ContentControl
{
    public SquareDecorator()
    {
        VerticalAlignment = VerticalAlignment.Stretch;
        HorizontalAlignment = HorizontalAlignment.Stretch;
        VerticalContentAlignment = VerticalAlignment.Stretch;
        HorizontalContentAlignment = HorizontalAlignment.Stretch;
    }

    protected override Size MeasureOverride(Size availableSize)
    {
        var baseSize = base.MeasureOverride(availableSize);

        double sideLength = Math.Max(baseSize.Width, baseSize.Height);

        return new Size(sideLength, sideLength);
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        double sideLength = Math.Min(finalSize.Width, finalSize.Height);

        var result = base.ArrangeOverride(new Size(sideLength, sideLength));

        return result;
    }
}

これで、このデコレータでボタンをラップできます:

<z:SquareDecorator>
    <Button Content="I'm Square"
            VerticalAlignment="Stretch"
            HorizontalAlignment="Stretch" />
</z:SquareDecorator>
于 2012-12-21T18:15:35.157 に答える
1

高さと幅を(ボタン自体またはボタンのスタイルで)固定サイズに設定することはできないと思います。

私はSilverlightでこれをやってみました:

<Button Height={Binding ActualWidth, RelativeSource={RelativeSource Self}}/>

しかし、それは働きたくありません。理由がわからない。WinRT で動作する可能性があります。

または、カスタム パネルを作成して、ボタンの配置とサイズを調整することもできます。単純な要件を考えると、難しいことではありません。たった 2 つの関数の実装と基本的な算術の知識が必要です。これは UniformGrid を作成する例です

UserControl や Button からの派生は、より良い選択だとは思いません。

于 2012-12-21T17:46:50.637 に答える
0

これが私のバージョンのPavloの答えです。ContentControlから派生するよりも効率的でエレガントです(ControlTemplateを使用する必要があり、ビジュアルツリーに他の要素を追加し、他の多くの不要な機能があります)。また、MeasureOverrideは正しい目的のサイズを返すため、より正確であると思います。

public class SquareDecorator : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        if( Children.Count == 0 )   return base.MeasureOverride(availableSize);
        if( Children.Count > 1 )    throw new ArgumentOutOfRangeException("SquareDecorator should have one child");

        Children[0].Measure(availableSize);
        var sideLength = Math.Max(Children[0].DesiredSize.Width, Children[0].DesiredSize.Height);
        return new Size(sideLength, sideLength);
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        if( Children.Count == 0 )   return base.ArrangeOverride(finalSize);
        if( Children.Count > 1 )    throw new ArgumentOutOfRangeException("SquareDecorator should have one child");

        double sideLength = Math.Min(finalSize.Width, finalSize.Height);
        Children[0].Arrange(new Rect(0, 0, sideLength, sideLength));
        return new Size(sideLength, sideLength);
    }
}

同じように使用します(ボタンのHorizo​​ntal / VerticalAlignmentはストレッチする必要がありますが、これがデフォルトです。また、SquareDecoratorのHorizo​​ntal / VerticalAlignmentを非ストレッチに設定すると便利な効果が得られることに注意してください。):

<z:SquareDecorator>
   <Button Content="I'm Square"/>
</z:SquareDecorator>

FrameworkElementから派生したはずですが、SilverlightもWinRTもそれを許可していないようです。(FrameworkElementは封印されていませんが、派生するのに役に立たないAddVisualChildメソッドがありません。ため息、私は.NETやMicrosoftが嫌いです)

于 2012-12-22T11:39:38.887 に答える