Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

wpf - Making a Viewbox scale vertically but stretch horizontally

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

If I do this:

<Viewbox>
  <StackPanel>
    <Button>Foo</Button>
    <Button>Bar</Button>
  </StackPanel>
</Viewbox>

then I get this:


(source: excastle.com)

It acts as if both of the buttons had HorizontalAlignment="Center", and then scales the result. But I don't want HorizontalAlignment="Center"; I want HorizontalAlignment="Stretch", like this:


(source: excastle.com)

So I want it to read its contents' desired height, calculate a scaling factor based only on the height, and then allow the scaled content to stretch horizontally.

Is there any way to accomplish this using the Viewbox, and/or some third-party panel?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There is no such control include with WPF but you can write one yourself without too much trouble. Here is a custom ViewboxPanel that has your specifications:

public class ViewboxPanel : Panel
{
    private double scale;

    protected override Size MeasureOverride(Size availableSize)
    {
        double height = 0;
        Size unlimitedSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
        foreach (UIElement child in Children)
        {
            child.Measure(unlimitedSize);
            height += child.DesiredSize.Height;
        }
        scale = availableSize.Height / height;

        return availableSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        Transform scaleTransform = new ScaleTransform(scale, scale);
        double height = 0;
        foreach (UIElement child in Children)
        {
            child.RenderTransform = scaleTransform;
            child.Arrange(new Rect(new Point(0, scale * height), new Size(finalSize.Width / scale, child.DesiredSize.Height)));
            height += child.DesiredSize.Height;
        }

        return finalSize;
    }
}

and you use it like this:

<local:ViewboxPanel>
    <Button>Foo</Button>
    <Button>Bar</Button>
</local:ViewboxPanel>

It definitely needs some work but this might get you started.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...