[英]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.