Making a Viewbox scale vertically but stretch horizontally

后端 未结 4 1528
南旧
南旧 2020-12-03 01:36

I want to make a Viewbox (or something similar) that scales only its height, and then stretches its content horizontally.

If I do this:

         


        
4条回答
  •  春和景丽
    2020-12-03 02:11

    I had an almost similar problem. My panel had to fit all its children, placing tham in a row and stretching them, filling the panel uniformly. Algorithm above uses render transform to scale elements. The problem is that render transform stretches children themselves, but ignores margin. If margin is high and scale coefficient is below 1, elements fall out from panel. You have to correct scale for RenderTransform according to margin on that axis and use same scale coefficient for arranging. MeasureOverride I used was

    protected override Size MeasureOverride(Size availableSize)
    {
        double width = 0; double maxHeight = 0; double mY=0; double mX=0;
        Size unlimitedSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
        foreach (UIElement child in Children)
        {
            child.Measure(unlimitedSize);
            width += child.DesiredSize.Width;
            maxHeight = Math.Max(maxHeight, child.DesiredSize.Height);
    
            FrameworkElement cld = child as FrameworkElement;
            mY = cld.Margin.Top + cld.Margin.Bottom;
            mX = cld.Margin.Left + cld.Margin.Right;
        }
    
        double scaleX = availableSize.Width / width;
        double scaleY = availableSize.Height / maxHeight;
        //That is scale for arranging
        positionScaling = Math.Min(scaleX, scaleY); 
    
        try
        {
            // Let FrameworkElement hight be Xn. mY = Element.Margin.Top + Element.Margin.bottom.
            // DesiredSize includes margin therefore:
            // (Yn + mY) * scaleY = availableSize.Height
            // But render transform doesn't scales margin. Actual render height with margin will be
            // Yn * RenderScaleY + mY = availableSize.Height;
            // We must find render transform scale coeff like this:
    
            double yn = availableSize.Height / scaleY - mY;
            scaleY = (availableSize.Height - mY) / yn;
    
            double xn = availableSize.Width / scaleX - mX;
            scaleX = (availableSize.Width - mX) / xn;
    
    
            scale = Math.Min(scaleX, scaleY); //scale to use in RenderTransform   
            // In my project all children are similar in size and margin, algorithm BREAKS otherwise!!!
        }
        catch { scale = 1; }
    
        return availableSize;
    }
    

    Once again: in my project all children are similar in size and margin, algorithm BREAKS otherwise.

提交回复
热议问题