[英]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的Horizontal / VerticalAlignment必须拉伸,但这是默认值。另请注意,如果将SquareDecorator的Horizontal / VerticalAlignment设置为非拉伸,则可以获得有用的效果。):
<z:SquareDecorator>
<Button Content="I'm Square"/>
</z:SquareDecorator>
我会从FrameworkElement派生出来,但看起来Silverlight和WinRT都不允许你这样做。 (FrameworkElement没有密封,但没有AddVisualChild方法,这使得它无法派生。叹气,我讨厌.NET和/或微软)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.