Welcome to Pete Brown's 10rem.net

First time here? If you are a developer or are interested in Microsoft tools and technology, please consider subscribing to the latest posts.

You may also be interested in my blog archives, the articles section, or some of my lab projects such as the C64 emulator written in Silverlight.

(hide this)

How to Resize a Silverlight 2 App and Keep the Same Aspect Ratio

Pete Brown - 04 July 2008

A similar question just popped up on a list I’m on, so I thought I’d whip up a quick example on how to resize a Silverlight application while keeping the same aspect ratio and centering the content.

image image image

The key to resizing is to use a ScaleTransform on the LayoutRoot of your main page. Here’s the important part of the xaml for the page. The key part is the “Grid.RenderTransform” section and the RenderTransformOrigin for the grid. In the latter, 0.5, 0.5 tells the engine that any render transforms should originate in the center of the grid. The former we name “PageScale” to allow us to easily manipulate its ScaleX and ScaleY properties from code.

<UserControl x:Class="PeteBrown.SilverlightScalingExample.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    >
    
    <Grid x:Name="LayoutRoot" 
          Background="Cornsilk" ShowGridLines="True"
          Width="400" Height="300" 
          RenderTransformOrigin="0.5 0.5">
        
        <Grid.RenderTransform>
            <ScaleTransform x:Name="PageScale" ScaleX="1" ScaleY="1"/>
        </Grid.RenderTransform>
    </Grid>
</UserControl>

Note also in the markup that I have left the grid lines on. This helps you visualize and debug resizing behavior especially when working with complex layouts that combine true expanding grids along with transforms and combinations of other panels.

Here’s the code. It is pretty straight-forward. I set the desired aspect ratio as a constant and then resize against that using the new SizeChanged event.

public partial class Page : UserControl
{
    // this is the aspect ratio we want to maintain
    // you can specify this all sorts of ways, but the
    // easiest is to take the original size and divide
    // X by Y (4:3 or 1.333 in this case)
    private const double _originalWidth = 400;
    private const double _originalHeight = 300;
    private const double _originalAspectRatio = 
        _originalWidth / _originalHeight;

    public Page()
    {
        InitializeComponent();

        // wire up the event handler. This is a great addition
        // to silverlight, as you used to have to hook into the
        // browser event yourself
        SizeChanged += new SizeChangedEventHandler(Page_SizeChanged);
    }

    void Page_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        if (e.NewSize.Width < _originalWidth || 
            e.NewSize.Height < _originalHeight)
        {
            // don't shrink
            PageScale.ScaleX = 1.0;
            PageScale.ScaleY = 1.0;
        }
        else
        {
            // resize keeping aspect ratio the same
            if (e.NewSize.Width / e.NewSize.Height > _originalAspectRatio)
            {
                // height is our constraining property
                PageScale.ScaleY = e.NewSize.Height / _originalHeight;
                PageScale.ScaleX = PageScale.ScaleY;
            }
            else
            {
                // either width is our constraining property, or the user
                // managed to nail our aspect ratio perfectly.
                PageScale.ScaleX = e.NewSize.Width / _originalWidth;
                PageScale.ScaleY = PageScale.ScaleX;
            }
        }
    }
}

In this example, I decided to restrict the user from resizing to a size smaller than the original size of the application. That is often but not always desirable. The check is easy enough to remove should you wish to allow a tiny thumbnail application.

If you have bitmap assets, resizing may not be as fluid. Experiment with the largest version you can include in your xap while keeping a reasonable download size.

Full source code available here.

Running example here.

   
posted by Pete Brown on Friday, July 4, 2008
filed under:    

8 comments for “How to Resize a Silverlight 2 App and Keep the Same Aspect Ratio”

  1. DrYSGsays:
    I think I was the guy who asked the question in the forum you mentioned.

    Quick Question (which I could probably figure out by doodling, but perhaps you already know the answer).

    The effect I am trying to achieve is a GridLayout where 3/4 of the screen is fixed, and the lower-right quadrant has an MSI that scales to fill the available space.

    Since you are using the PageScale of the whole page, I assume what I have to do is embedd a Grid in the lower quadrant and watch the scale of that grid itself (What I probably will do is create a UserControl with and embedded great and then the MSI in the grid.)

    Does that sound right to you?

  2. Rui Marinhosays:
    And if you don't want to give a fixed size?

    how can the render transform.. transform also the childrens in the grid? like a user control..

    thanks for sharing :)
  3. Pete Brownsays:
    @Rui the fixed size is only the starting point - the "natural" resolution of the application. Depending on how you set up your containers, you can retrieve that at runtime. More often than not, however, you end up with zero or NaN (more on that in another post).

    As to resizing children as well: scaling the parent scales the children. If you want to scale only the children, that's a slightly more difficult problem as Silverlight has only render transforms, not layout transforms, making holistic layout a bit trickier.

    Pete
  4. Phil Bachmannsays:
    Maybe I was looking in the wrong places, but I tried five different methods offereed by luminaries around the internet - none of which quite worked.

    Your solution worked immediately. Thank you for putting it up, especially the downloadable source.

Comment on this Post

Remember me

5 trackbacks for “How to Resize a Silverlight 2 App and Keep the Same Aspect Ratio”

  1. Dew Drop &ndash; July 5, 2008 | Alvin Ashcraft's Morning Dewsays:
    PingBack from http://www.alvinashcraft.com/2008/07/05/dew-drop-july-5-2008/
  2. Community Blogssays:
    Michael Washington on SL Security, Jesse LIberty on Styles & Templates, Koen Swikstra on Tweening
  3. Community Blogssays:
    Michael Washington on SL Security, Jesse LIberty on Styles & Templates, Koen Swikstra on Tweening
  4. Mirrored Blogssays:
    Post: Approved at: Jul-8-2008 GUI .. GUI ... GUI ... Themes for Silverlight Applications "A theming
  5. 代震军says:
    Pete Brown在它的BLOG中提到了一个按自定义比例使用silverlight适应IE窗口大小的方法