WPF 使用纵横比调整用户控件的大小



我有一个用户控件,并且必须使用纵横比调整该用户控件的大小。这意味着:宽度:高度 = 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;
    }

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

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

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

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);
   }

我希望它对某人有所帮助!

ViewBox包装控件,并将ViewBox.Stretch设置为 Uniform 。您也可以通过这种方式限制最大宽度和最大高度。

有关拉伸枚举 @ MSDN 的详细信息

如何应用 Stretch @ MSDN

最新更新