Creating a Resolution Independent Metro App with the ViewBox!

Recently, while working on a Windows Metro App, we faced some issues with Adaptive Layout. The requirement was that our app should support all resolutions (Minimum:-1024*768, Maximum:- 2560*1440)and maintain aspect ratios when it came to images.

We solved the issue using a ViewBox but had to learn a few tricks about the Viewbox first!

This blog essentially describes the use of ViewBox for Adaptive Layout in WinRT.

Before beginning with Adaptive Layout, let us describe what a Viewbox is.

A viewbox is a content decorator that can stretch and scale a single child to fill the available space.

Confused?

Lets work with an example…

1) Create a store app project.

2) Create a Grid with two Columns of equal width.

<Grid Background="{ThemeResourceApplicationPageBackgroundThemeBrush}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<Image Stretch="Fill"Grid.Column="0" Source="/Assets/Royalty Free wallpaper4.jpg"></Image>
<Image Stretch="Fill"Grid.Column="1" Source="/Assets/clearday.jpg"></Image>
</Grid>

Heres what the output looks like

image

Resize ….

image

So the screen resizes but the aspect ratio of the image is not maintained.

3) Let’s place our Grid in a Viewbox so that the aspect ratio is maintained.

<Viewbox>
<Grid Background="{ThemeResourceApplicationPageBackgroundThemeBrush}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<Image Stretch="Fill"Grid.Column="0" Source="/Assets/Royalty Free wallpaper4.jpg"></Image>
<Image Stretch="Fill"Grid.Column="1" Source="/Assets/clearday.jpg"></Image>
</Grid>
</Viewbox>

image

 

On Resizing

image

So… the viewbox maintains the aspect ratio but the Grid’s layout has changed i.e. grid’s column widths are not equal inspite of giving both the columns an equal star.

4) Let’s see what happens if we give the column definitions absolute values

<Viewbox>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Image Stretch="Fill" Grid.Column="0" Source="/Assets/Royalty Free wallpaper4.jpg"></Image>
<Image Stretch="Fill" Grid.Column="1" Source="/Assets/clearday.jpg"></Image>
</Grid>
</Viewbox>

image

On Resizing…

image

Looks like this is working but we don’t really like to give absolute numbers do we? And it also is a little confusing because the width looks more than the provided 50 anyways…So to the logical programmer this is no good…

So, what is the right way to ensure that the aspect ratio is maintained as well as the relative Layout within the Grid is respected?

5) Let’s give the Grid a Width and Height.

<Viewbox>
<Grid Width="1366" Height="768" Background="{ThemeResourceApplicationPageBackgroundThemeBrush}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<Image Stretch="Fill"Grid.Column="0" Source="/Assets/Royalty Free wallpaper4.jpg"></Image>
<Image Stretch="Fill"Grid.Column="1" Source="/Assets/clearday.jpg"></Image>
</Grid>
</Viewbox>

image

 

On Resizing…

image

Bingo!! Both the aspect ratio and Grid relative sizing and  layout is maintained and we avoided absolute numbers

Lesson Learnt :- Merely placing our Content in Viewbox will maintain the aspect ratio of the image but the Viewbox will override any star layout values(in our case the column definitions). This is because the viewbox considers itself to have infinite space. So star sizing stops having an effect because anything into infinity is still infinity!

Therefore it is essential that our top level element within the Viewbox must have a width and height if we are to use Viewbox for Adaptive layout.

Some More Tips from our experience:-

1) If possible try to avoid Viewbox within a Viewbox. They interfere with each other more than helping you further!

2) If you want your app to run on multiple resolutions then design your screen using one particular resolution i.e. Give the top level element within the Viewbox a Width and Height of a particular resolution (E.g. 2160*1440 :- Screen Resolution of Surface Pro) and design your inner elements as per the Width and Height of the top level element. Leave it to the ViewBox to handle the other resolutions!

Have you had similar experiences with the MagicBox…we mean ViewBox? Any more tips to share?

Until next time!

Team Cennest!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>