The WPF Viewbox: What It’s For and How To Use It

wpf viewboxThe WPF viewbox is an automatically resizable/redimensionable Windows Presentation Foundation layout control. It is capable of resizing to fill the available area, automatically adjusting the size of the child (the control which it contains, and which is displayed) and the sizes and relative positions of the elements which make up the child as it does so.  It automatically adjusts coordinates for the change in size, so that a set of coordinates given in pixels in the original size, for example, will still describe the same relative location in the resized child control.

The Windows Presentation Foundation is only part of Microsoft NET Framework 3.0.  There are plenty of online classes where you can find out more about NET Framework and Microsoft programming in general.

Why a Viewbox?

What’s the purpose of the WPF Viewbox?  When would you use it?

When you’re writing a program, you generally don’t know with any certainty what the hardware characteristics of the target system are going to be.  You may know some things, but particularly if the application is intended for general distribution, or if it’s likely to be in use for more than a short time, you really can’t be sure of such things as the size or resolution of the monitor on any given system.  Last year’s ultra-high-resolution monitor may be next year’s “How could anybody ever stand to look at that” low-resolution  monitor  —  and if you wrote your code with last year’s monitor in mind, the windows, buttons, and other elements of your GUI may be so small that they’re practically unusable on next year’s monitor.

Resize!

The Viewbox gives you a way to automatically adjust for the resolution of an unknown monitor.  If a window is maximized in any monitor of any resolution, the viewbox will adjust accordingly.  If the user resizes or reproportions the window manually, the Viewbox will adjust the size and relative positions of the contents to fit.  This gives both the programmer and the user a maximum degree of flexibility in adjusting window size without distorting the contents of the window.

The following XAML code will create a Viewbox with a single button which resizes automatically as you resize the Viewbox window:

<Window x:Class="ViewboxTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Viewbox Test"
        SizeToContent="WidthAndHeight" Height="75" Width="250">
    <Viewbox>
        <Button Content="I'm a Button" Width="150"/>
    </Viewbox>
</Window>

What About the Margins?

If the Viewbox window can be resized and redimensioned in the manner of a typical window, and if the control that it contains is going to be resized automatically, what happens when the window is not only resized but redimensioned in a way that the control doesn’t fit?  Are there ways to control margins and aspect ratio under those conditions?  The Viewbox control includes two properties, Stretch and StretchDirection, which are designed to do just that.

Stretching it a Bit

First, let’s take a look at what happens when you compile the “Viewbox Test” code shown above, then run the compiled EXE.  You’ll see a window labeled “Viewbox Test” containing a button labeled “I’m a Button”.  When you resize the window, the button will automatically resize to fit, maintaining its aspect ratio.  This results in a nicely-proportioned button at any size, but if the aspect ratio of the Viewbox window doesn’t fit the dimensions of the button, you will see white space either above and below the button, or to the left and right.

The Default

When you don’t explicitly set the Stretch property, Viewbox uses the default value for Stretch, which is Uniform, so this:

    <Viewbox>
        <Button Content="I'm a Button" Width="150"/>
    </Viewbox>

is actually the equivalent of this:

    <Viewbox Stretch="Uniform">
        <Button Content="I'm a Button" Width="150"/>
    </Viewbox>

There are four options for Viewbox’s Stretch property.  We’ll take a look at each one:

No Stretch At All

If you want to tell Viewbox to never resize the child control, you need to explicitly tell it that by setting Stretch to None:

    <Viewbox Stretch="None">
        <Button Content="I'm a Button" Width="150"/>
    </Viewbox>

When you do this, the button will always remain the same size, no matter how you resize or redimension the Viewbox window.  If you enlarge the window, the button will be surrounded by white space, and if you shrink it, the button will become obscured and finally hidden without changing size.

Free-Form

To go to the other extreme, and alway resize and redimension the button along with the Viewbox window, set Stretch to the Fill option:

    <Viewbox Stretch="Fill">
        <Button Content="I'm a Button" Width="150"/>
    </Viewbox>

This causes the button to completely fill the Viewbox window, no matter what size or aspect ratio you give it.  A tall, narrow window will be filled with a tall, narrow button, and a perfectly square window will be filled with a square button.  As you resize the window on-the-fly, the button resizes.

Needless to say, since the button’s aspect ratio changes to fit the window, the button and the text may undergo considerable distortion.  This isn’t necessarily bad; there may be times when a professional programmer will want to make use of such distortion.

Uniform Adjustment

The Uniform option, as described above, is the default setting for Stretch.  Since the child control always maintains the same aspect ratio, it never undergoes distortion when it changes size.  The tradeoff is that when the aspect ratio of the Viewbox window doesn’t match that of the control, you may see white margins at the top and bottom or on the sides.

Uniform and Fill

You can, if you want to, combine the Uniform and Fill options by using the UniformToFill option:

    <Viewbox Stretch="UniformToFill">
        <Button Content="I'm a Button" Width="150"/>
    </Viewbox>

Like the Uniform option, UniformToFill always maintains the original aspect ratio for the control, so its proportions are never distorted.  But like the Fill option, UniformToFill fills the Viewbox window completely.  The way that it manages to do this is by simply cutting off the portion of the control that doesn’t fit.  This means for example, that if you were to redimension the “Viewbox test” window to a square, the button would fill it, but it would be cut off after “I'”.

Which Way?

Now look at this code:

    <Viewbox Stretch="Uniform" StretchDirection="UpOnly">
        <Button Content="I'm a Button" Width="150"/>
    </Viewbox>

When the Viewbox window expands past the original size and dimensions of the button, the button will expand with it, following the rules for Uniform stretching.  But when the Viewbox shrinks down past the original size of the button, the button will remain the same size, until it is finally hidden by the shrinking window.

The Right Direction

There are three StretchDirection options; the outcome of using a StretchDirection option depends on the Stretch option with which it is used.  If the Stretch option is None, the StretchDirection options have no effect.

The simplest StretchDirection option is Both.  It tells Viewbox to stretch the control based on the Stretch option, with no modifications.  It is also the default setting for StretchDirection, so this:

    <Viewbox Stretch="Uniform" StretchDirection="Both">
        <Button Content="I'm a Button" Width="150"/>
    </Viewbox>

Is the equivalent of this:

    <Viewbox>
        <Button Content="I'm a Button" Width="150"/>
    </Viewbox>

Going Up

The UpOnly StretchDirection option, as described above, tells Viewbox to only stretch the control if the Viewbox is larger.  For Fill, Uniform, and UniformToFit, the results are similar  —  when the Viewbox window is larger than the control, the rules for the Stretch Option apply.  Below the control size, the control acts as if its Stretch option is None.

And Getting Down

The DownOnly option is the reverse of the UpOnly option.  If the Viewbox is resized to be smaller than the control, the control will be resized downward based on the Size option.  If the Viewbox is larger than the control, the control will be surrounded by white space.

A Rich Set of Tools

The Viewbox control is only one of many controls available in the Windows Presentation Foundation, which is itself only one part of the very large and very rich world of the Microsoft NET 3.0 framework.  If you’re interested in a career in programming, you owe it to yourself to look into the many online classes in programming for NET Framework and related Microsoft platforms.