Easy Scaling in XAML (WPF)

Ran into a problem that needed solving that was kind of fun.  I’m not a XAML guru, and I’m sure there are better solutions, but I thought I’d share mine.

The problem was this:  Our designer had, appropriately, designed the system for a 1920 x 1080 screen resolution.  This is for a full screen, touch screen device (think Kiosk), which has that resolution, but we also wanted to demo the device on a tablet (currently using the AWESOME Samsung tablet given out at Microsoft Build).  When you’d run it on that tablet, things were ugly because it was at a lower resolution than the target device.

Enter scaling.  I did some research and found out that I probably just need to monkey with the LayoutTransform of some grid somewhere.  This project is using MVVM and has a navigation container that we built that lives on a single root view.  User controls are then loaded into that view as navigation occurs.

In the parent grid of the root view, I added the following XAML:

<Grid.LayoutTransform>
 <ScaleTransform ScaleX="{Binding ScaleWidth}" ScaleY="{Binding ScaleHeight}" />
 </Grid.LayoutTransform>

And then in the root View Model, I added the following code:

/// <summary>
/// The required design width
/// </summary>
private const double RequiredWidth = 1920;

/// <summary>
/// The required design height
/// </summary>
private const double RequiredHeight = 1080;
/// <summary>Gets the ActualHeight</summary>
public double ActualHeight {
 get { return this.View.ActualHeight; }
}

/// <summary>Gets the ActualWidth</summary>
public double ActualWidth {
 get { return this.View.ActualWidth; }
}

/// <summary>
/// Gets the scale for the height.
/// </summary>
public double ScaleHeight {
 get { return this.ActualHeight / RequiredHeight; }
}

/// <summary>
/// Gets the scale for the width.
/// </summary>
public double ScaleWidth {
 get { return this.ActualWidth / RequiredWidth; }
}

Note that View.ActualWidth and View.ActualHeight are just pointing directly at FrameworkElement.ActualWidth and FrameworkElement.ActualHeight.

That’s it.  Just calculate the ratio and bind the scale transform to it.

Hopefully you’ll find this useful.

Update (7-2-2012):

Note that I tried a ViewBox before, but it didn’t work because of the navigation.  Basically, we needed the following structure in the grid:

<Grid.ColumnDefinitions>
 <ColumnDefinition Width="1920"/>
 <ColumnDefinition Width="1920"/>
 <ColumnDefinition Width="1920"/>
 </Grid.ColumnDefinitions>

The first column is the Last Screen.  The second column is the Currently displayed screen, and the last column is the “Next” screen.  When moving next, the “next” screen is loaded into the last column, then the animation is fired to slide in the screen, and then the current panel has the current view replaced and is refocused without animation.  Navigating back is similar in flow.

The total screen space isn’t consumed by the navigation grid.

When using a ViewBox, the entire 5760 pixels are compressed into the available screen space.  A picture would make this more clear, but I can’t show that without revealing stuff you shouldn’t know. Smile

Basically, I needed a single column of the grid to be scaled, not the entire grid, which is what my solution does, where the viewbox attempts to scale everything.

Make sense?

Technorati Tags: ,

Print | posted on Monday, July 02, 2012 4:29 PM |

This article is part of the GWB Archives. Original Author: gwbarchive

New on Geeks with Blogs

  • We Won The One Award I Actually Care About

    Full Scale made the Inc. 5000 for the fifth year straight, the 12th listing across my three companies. Here is why the one award you cannot buy is worth stopping for.

  • Your Customers Build the Features Now

    I let a tool I liked sit dead for a year rather than build the features I wanted. An MCP server meant I never had to, and your customers can do the same to your product.

  • Get the Size of a Directory in Linux the Easy Way

    du -sh for the quick answer, ncdu for the cleanup, df for the disk itself: every command for checking directory size in Linux, plus why du and df never agree.

  • Vim Search and Replace: The Ultimate Guide

    One :%s command replaces every match in a file before a find dialog would even open. The Vim substitute patterns worth the muscle memory: flags, ranges, capture groups, and multi-file edits.