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 中工作。

或者,您可以创建自定义面板来排列和调整按钮的大小。考虑到您的简单要求,应该不难。它只涉及实现两个功能和基本算术知识。这是一个创建 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);
    }
}

以同样的方式使用它(Button 的 Horizo​​ntal/VerticalAlignment 必须是拉伸的,但这是默认设置。另请注意,如果将 SquareDecorator 的 Horizo​​ntal/VerticalAlignment 设置为非拉伸,您可以获得有用的效果。):

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

I would have derived from FrameworkElement, but it looks like neither Silverlight nor WinRT allow you to do that. (FrameworkElement is not sealed, but has no AddVisualChild method which makes it useless to derive from. Sigh, I hate .NET and/or Microsoft)

于 2012-12-22T11:39:38.887 回答