Search
Close this search box.

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: WPF,XAML

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

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

Related Posts