簡體   English   中英

創建具有約束比例的可調整大小的Button控件網格的最佳方法(Silverlight .XAML,WinRT)

[英]Best way to create a resizable Grid of Button control with constrained proportions (Silverlight. XAML, WinRT)

在XAML / C#中編寫一個WinRT應用程序,我想要一個簡單的方形按鈕網格。 按鈕的數量目前是固定的,但是隨着我創建更多內容,將來會增加更多。

必須處理所有UI調整大小(拍攝,填充,縱向等)和分辨率我遇到了UIContainer的問題(我使用Grid然后切換WrapGrid )只是自動調整按鈕大小,因為我不知道有什么方法可以約束縱橫比和方形按鈕對我的UI很重要。

有沒有辦法約束按鈕控件的寬度和高度的寬高比/比例? 如果是這樣,我假設它將創建一個自定義控件,但除了創建樣式和數據模板,我真的只是我的深度。

有關解決此問題的最佳方法的任何建議?

您可以創建一個簡單的裝飾器控件,它將覆蓋ArrangeOverride並始終將自身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>

我假設您不能只將高度和寬度設置為固定大小(按鈕本身或按鈕的樣式)。

我嘗試在Silverlight中這樣做:

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

但它不想工作。 不知道為什么。 它可能在WinRT中有效。

或者,您可以創建自定義面板來排列和調整按鈕大小。 鑒於您的簡單要求,應該不難。 它涉及實現兩個基本算術的功能和知識。 這是一個創建UniformGrid的示例

我不認為UserControl或從Button派生是更好的選擇。

這是我的Pavlo的答案版本。 它比從ContentControl派生更有效和優雅(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);
    }
}

以相同的方式使用它(Button的Horizo​​ntal / VerticalAlignment必須拉伸,但這是默認值。另請注意,如果將SquareDecorator的Horizo​​ntal / VerticalAlignment設置為非拉伸,則可以獲得有用的效果。):

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

我會從FrameworkElement派生出來,但看起來Silverlight和WinRT都不允許你這樣做。 (FrameworkElement沒有密封,但沒有AddVisualChild方法,這使得它無法派生。嘆氣,我討厭.NET和/或微軟)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM