【问题标题】:WPF Resize UserControl with aspect ratioWPF 使用纵横比调整 UserControl 的大小
【发布时间】:2012-05-26 07:30:18
【问题描述】:

我有一个 UserControl,并且必须根据纵横比调整 UserControl 的大小。 这意味着:宽度:高度= 2:1。 目前我正在使用此代码:

    protected override Size ArrangeOverride(Size arrangeBounds)
    {
        if (ActualWidth == 0 || ActualHeight == 0) return arrangeBounds;
        base.ArrangeOverride(arrangeBounds);
        double ratio = 2;

        if (Parent != null)
        {
            var size = new Size(arrangeBounds.Height * ratio, arrangeBounds.Height);

            double containerWidth = ((FrameworkElement)Parent).ActualWidth;
            if (containerWidth < size.Width)
            {
                double newHeight = arrangeBounds.Height * (containerWidth / size.Width);
                canvas.Width = newHeight * ratio;
                canvas.Height = newHeight;
            }
            else
            {
                canvas.Width = size.Height * ratio;
                canvas.Height = size.Height;
            }
        }

        return arrangeBounds;
    }

但它并没有真正起作用。这意味着它有效,但并非每次都有效。如果我最大。它有时不会调整窗口大小,因此如果控件调整大小,它会有点“随机”。因此,如果有人有更好的解决方案,那就太好了。

【问题讨论】:

    标签: wpf resize aspect-ratio


    【解决方案1】:

    最直接的解决方案是通过值转换器将高度直接绑定到宽度。

    【讨论】:

    • 主要问题是高度会变得太大。因为如果容器的宽度是 3000 像素,高度是 600 像素,我会将高度缩放到 1500 像素。所以它会太大。
    【解决方案2】:

    有点晚了,但我最近遇到了同样的问题,由于我没有找到好的解决方案,我决定编写自己的布局控件/装饰器,并在这里写了一篇关于它的博客文章:

    http://coding4life.wordpress.com/2012/10/15/wpf-resize-maintain-aspect-ratio/

    基本上我的解决方案是同时覆盖MeasureOverrideArrangeOverride。到目前为止,它在所有常见容器中都运行良好,并且我没有遇到您描述的任何问题。

    我推荐阅读这篇文章,在那里你可以找到一个可以工作的装饰器控件,但最重要的方法是:

       protected override Size MeasureOverride(Size constraint)
       {
          if (Child != null)
          {
             constraint = SizeToRatio(constraint, false);
             Child.Measure(constraint);
    
             if(double.IsInfinity(constraint.Width)
                || double.IsInfinity(constraint.Height))
             {
                return SizeToRatio(Child.DesiredSize, true);
             }
    
             return constraint;
          }
    
          // we don't have a child, so we don't need any space
          return new Size(0, 0);
       }
    
       protected override Size ArrangeOverride(Size arrangeSize)
       {
          if (Child != null)
          {
             var newSize = SizeToRatio(arrangeSize, false);
    
             double widthDelta = arrangeSize.Width - newSize.Width;
             double heightDelta = arrangeSize.Height - newSize.Height;
    
             double top = 0;
             double left = 0;
    
             if (!double.IsNaN(widthDelta)
                && !double.IsInfinity(widthDelta))
             {
                left = widthDelta/2;
             }
    
             if (!double.IsNaN(heightDelta)
                && !double.IsInfinity(heightDelta))
             {
                top = heightDelta/2;
             }
    
             var finalRect = new Rect(new Point(left, top), newSize);
             Child.Arrange(finalRect);
          }
    
          return arrangeSize;
       }
    
       public Size SizeToRatio(Size size, bool expand)
       {
          double ratio = AspectRatio;
    
          double height = size.Width / ratio;
          double width = size.Height * ratio;
    
          if (expand)
          {
             width = Math.Max(width, size.Width);
             height = Math.Max(height, size.Height);
          }
          else
          {
             width = Math.Min(width, size.Width);
             height = Math.Min(height, size.Height);
          }
    
          return new Size(width, height);
       }
    

    希望对大家有所帮助!

    【讨论】:

      【解决方案3】:

      ViewBox 包裹你的控件并将ViewBox.Stretch 设置为Uniform。您也可以通过这种方式限制 MaxWidth 和 MaxHeight。

      More Info on the Stretch-Enumeration @ MSDN

      How to apply Stretch @ MSDN

      【讨论】:

        猜你喜欢
        • 2010-12-14
        • 2017-08-10
        • 2022-01-23
        • 2012-11-16
        • 2013-05-07
        • 2020-06-14
        • 2013-06-26
        • 2012-04-15
        相关资源
        最近更新 更多