繁体   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