如何创建方形按钮?

感谢@Justin XL和@ grek40对我的帮助。
我必须为那些让每个人都烦恼的英语不好而道歉。
而且我认为我需要改进这个问题以帮助其他任何人。

这是最新的:
我需要像这样制作一个方形按钮: 在此处输入图像描述

我的程序是一个全屏程序,不同的设备有不同的窗口大小。
所以我的方形按钮应该可以resize也是我想要制作一个react nativeUI。
现在如何制作方形按钮?
谢谢。

使用Rectangle.Stretch属性:

  

我认为这回答了创建矩形的实际问题,其中宽度和高度相同,矩形被拉伸到可用空间。

在绑定方面, WidthHeight上的MultiBinding以及返回所有输入值的最小值的IMultiValueConverter实现可能有效。 但是,只有不提供自动拉伸的控件才需要它。


您可以使用附加属性为给定限制设置相同的宽度/高度:

 public static class SquareSize { public static double GetWidthLimit(DependencyObject obj) { return (double)obj.GetValue(WidthLimitProperty); } public static void SetWidthLimit(DependencyObject obj, double value) { obj.SetValue(WidthLimitProperty, value); } public static readonly DependencyProperty WidthLimitProperty = DependencyProperty.RegisterAttached( "WidthLimit", typeof(double), typeof(SquareSize), new FrameworkPropertyMetadata(double.PositiveInfinity, new PropertyChangedCallback(OnWidthLimitChanged))); private static void OnWidthLimitChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { UpdateSize(d, (double)e.NewValue, GetHeightLimit(d)); } public static double GetHeightLimit(DependencyObject obj) { return (double)obj.GetValue(HeightLimitProperty); } public static void SetHeightLimit(DependencyObject obj, double value) { obj.SetValue(HeightLimitProperty, value); } public static readonly DependencyProperty HeightLimitProperty = DependencyProperty.RegisterAttached( "HeightLimit", typeof(double), typeof(SquareSize), new FrameworkPropertyMetadata(double.PositiveInfinity, new PropertyChangedCallback(OnHeightLimitChanged))); private static void OnHeightLimitChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { UpdateSize(d, GetWidthLimit(d), (double)e.NewValue); } private static void UpdateSize(DependencyObject d, double widthLimit, double heightLimit) { double resultSize = Math.Min(widthLimit, heightLimit); d.SetCurrentValue(FrameworkElement.WidthProperty, resultSize); d.SetCurrentValue(FrameworkElement.HeightProperty, resultSize); } } 

与适当的xmlns命名空间一起使用

    

一个涉及自定义控件作为方形内容包装器的解决方案:

 public class SquareContentControl : ContentControl { protected override Size ArrangeOverride(Size arrangeBounds) { var sizeLimit = Math.Min(arrangeBounds.Width, arrangeBounds.Height); if (VisualChildrenCount > 0) { var child = GetVisualChild(0) as UIElement; if (child != null) { child.Arrange(new Rect(new Point((arrangeBounds.Width - sizeLimit) / 2, (arrangeBounds.Height - sizeLimit) / 2), new Size(sizeLimit, sizeLimit))); return arrangeBounds; } } return base.ArrangeOverride(arrangeBounds); } protected override Size MeasureOverride(Size constraint) { var sizeLimit = Math.Min(constraint.Width, constraint.Height); if (VisualChildrenCount > 0) { var child = GetVisualChild(0) as UIElement; if (child != null) { child.Measure(new Size(sizeLimit, sizeLimit)); return child.DesiredSize; } } return base.MeasureOverride(constraint); } } 

用法:

      

像这样的 UI逻辑在其代码隐藏中存在是完全正常的。 在大多数情况下,我甚至认为它更有效率。

在您的示例中,使用以下代码对Rectangle进行平方非常容易

XAML

    

代码隐藏

 private void MyBorder_SizeChanged(object sender, SizeChangedEventArgs e) { if (MyBorder.ActualWidth > MyBorder.ActualHeight) { MyRectangle.Width = MyRectangle.Height = MyBorder.ActualHeight; } else if (MyBorder.ActualWidth < MyBorder.ActualHeight) { MyRectangle.Height = MyRectangle.Height = MyBorder.ActualWidth; } } 

但我们可以改善吗? 由于您需要一个方形Button ,因此最有意义的是创建一个SquareButton并将其直接插入到Grid

因此,XAML可以简化为下面更易读的版本

  

然后你只需要像下面这样实现自定义控件

SquareButton

 [TemplatePart(Name = PART_Root, Type = typeof(Border))] [TemplatePart(Name = PART_ContentHost, Type = typeof(Border))] public sealed class SquareButton : Button { private const string PART_Root = "Root"; private const string PART_ContentHost = "ContentHost"; public SquareButton() { DefaultStyleKey = typeof(SquareButton); } protected override void OnApplyTemplate() { base.OnApplyTemplate(); var root = (Border)GetTemplateChild(PART_Root); var contentHost = (Border)GetTemplateChild(PART_ContentHost); root.SizeChanged += (s, e) => { if (root.ActualWidth > root.ActualHeight) { contentHost.Width = contentHost.Height = root.ActualHeight; } else if (root.ActualWidth < root.ActualHeight) { contentHost.Height = contentHost.Height = root.ActualWidth; } }; } } 

Themes/Generic.xaml SquareButton样式

  

希望这可以帮助!

编辑2017/8/17仅适用于WPF,而不适用于UWP。

使用最小转换器:

 public class MinConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { double result = double.NaN; if (values != null) { try { result = values.Cast().Aggregate(double.PositiveInfinity, (a, b) => Math.Min(a, b)); } catch (Exception) { result = double.NaN; } } return result; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotSupportedException(); } } 

然后在你的xaml中设置Rectangle Height以匹配父的Border Min(ActualHeight,ActualWidth)。 Rectangle Width可以绑定到Rectangle的ActualHeight