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:
http://www.excastle.com/misc/viewbox-center.png
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:
http://www.excastle.com/misc/viewbox-stretch.png
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?
I'm pretty sure the answer is "not easily".
Here's an idea that seems to work but it's kind of clunky:
Throw your StackPanel into a UserControl (
UserControl1
in the example below).Place two copies of this UserControl into a container (a Grid in the example below).
a. Align the first copy top/left so that it remains at its default size. This copy is strictly for measurement purposes and should have its Visibility set to Hidden.
b. Place the second copy inside a Viewbox. This copy is the one the user will actually see.
Use a MultiBinding with a MultiValueConverter to adjust the width of the second UserControl so that it has the correct aspect ratio before it gets expanded by the Viewbox.
Here's the markup:
Here's the MultiValueConverter
Result for 525 x 350 container
To keep width to work correctly:
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:
and you use it like this:
It definitely needs some work but this might get you started.
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
Once again: in my project all children are similar in size and margin, algorithm BREAKS otherwise.