#1,065 – ViewBox Child Must Have Explicit Size

Whatever content you set as the content wrapped by a ViewBox, that content needs to be able to determine its own size.  The ViewBox needs to know what size to make the content at a scale of 1.0.

If the ViewBox wraps a panel containing elements that can size based on their own content, like buttons, everything works fine.

1065

However, if the ViewBox wraps a Canvas, you need to give the Canvas an explicit size so that the ViewBox knows what size to start with.  If you don’t do this, the ViewBox won’t be able to scale the content within the Canvas.

1065-001

#1,064 – Limiting ViewBox to Scale in Just One Direction

When you use a ViewBox to scale some content, by default it scales the content either larger or smaller than the default size of the content.

You can change this behavior by setting the StretchDirection of the ViewBox to one of the following values:

  • Both (the default) – allow scaling both up and down, relative to the default size of the content
  • UpOnly – Only allow scaling larger than default size of content
  • DownOnly – Only allow scaling smaller than default size of content

If you make the ViewBox a size at which scaling of the content is not allowed, the content will be clipped or whitespace will be added.

        <Viewbox StretchDirection="UpOnly">
            <Canvas Background="Bisque" Width="200" Height="100">
                <Line X1="5" Y1="5" X2="195" Y2="95"
                        Stroke="Black"/>
                <Label Canvas.Left="80" Canvas.Top="5" Content="Howdy"/>
                <Ellipse Height="30" Width="50" Stroke="Blue" StrokeThickness="2"
                            Canvas.Left="140" Canvas.Top="5"/>
            </Canvas>
        </Viewbox>

1064-001

#1,063 – ViewBox Stretching Options

By default, content scaled by using a ViewBox will preserve its aspect ratio as it is being scaled.  Content is scaled until its size fills its container in one dimension.  White borders are added in the other dimension.

This default behavior corresponds to setting the Stretch property of the ViewBox to Uniform.  We can see this behavior below as we scale a Canvas.

1063-001

1063-002

If we set Stretch to Fill, the content always fills the available area and the aspect ratio is not preserved.  That is, content is stretched more in one direction than in another.

1063-003

Setting the Stretch property to UniformToFill preserves the aspect ratio, but content stretches until it fills the container in both dimensions.  If the aspect ratio of the container is different than that of the content, content is clipped.

1063-004

Finally, setting Stretch to None disables all scaling.

1063-005

 

#1,062 – Scaling a Canvas Using a ViewBox

ViewBox is typically used to scale a panel containing other elements.  One common use of a ViewBox is to scale the contents of a Canvas panel.

We might include several elements within a Canvas that has an explicit size.

1062-001

If we re-size the window, however, the canvas stays the same size.

1062-002

We could have had the Canvas stretch to fill the remaining area, but its elements would still be the same size.

We can get the elements within the Canvas to scale by wrapping the Canvas in a ViewBox.

    <DockPanel>
        <Label DockPanel.Dock="Top" Background="LightGray"
               Content="Stuff at top of window here"
               VerticalAlignment="Top"/>
        <Label DockPanel.Dock="Bottom" Background="AliceBlue"
               Content="Bottom stuff down here"
               VerticalAlignment="Bottom"/>
        <Viewbox>
            <Canvas Background="Bisque" Width="200" Height="100">
                <Line X1="5" Y1="5" X2="195" Y2="95"
                        Stroke="Black"/>
                <Label Canvas.Left="80" Canvas.Top="5" Content="Howdy"/>
                <Ellipse Height="30" Width="50" Stroke="Blue" StrokeThickness="2"
                            Canvas.Left="140" Canvas.Top="5"/>
            </Canvas>
        </Viewbox>
    </DockPanel>

Now when we resize the window, everything within the Canvas is scaled.
1062-003

 

#1,061 – Scaling Content Using a ViewBox

You can scale entire panels by embedding the panel to be scaled within a ViewBox.

Assume that you start with a simple StackPanel in a Window (the StackPanel scales up to fit in the Window).

1061-001

If you want to scale these elements larger as the window gets larger, you can place the StackPanel in a ViewBox.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Scaling" Width="220" Height="140">
    <Viewbox>
        <StackPanel Background="Bisque">
            <Label Margin="5" Background="AliceBlue"
              Content="Alice Isn't Blue Anymore"/>
            <Button Content="Got It"
              HorizontalAlignment="Center"/>
            <TextBox Margin="5"
                  Text="Enter something here"/>
        </StackPanel>
    </Viewbox>
</Window>

Everything is a little bigger now, within the original window. This is because the StackPanel is no longer stretching to fill the Window, but sizing to fit its contents. And the ViewBox is then scaling the StackPanel to fit into the Window.

1061-002

Now scaling the Window larger causes everything within the ViewBox to scale up.

1061-003