XPF: Star Grid Length and Windows Phone 7 Orientation

We recently added support to XPF’s Grid for star grid length.  Star grid lengths describe a grid layout using proportional values, allowing you to split up available space using percentages.  This can be extremely powerful, especially in situations when your host window changes size - think going in and out of full screen on Windows or changes in orientation on Windows Phone 7.

In our original Getting Started post, we had to use explicit row height and column widths creating a slightly inflexible structure.  Let’s rewrite the code using star grid lengths, but this time on Windows Phone 7.

Star Grid Length

We want to create a Grid with the following characteristics:

Grid

Because star is now the default grid length unit, to get the above layout we only have to provide explicit values on our top and bottom rows; making them a fixed height of 50 pixels each.  The middle row can default to what is effetely a value of 1 star, which will use 100% of the remaining space.  The 2 columns both have 1 star too and so will share the available horizontal space equally between them; 50% each.

var grid = new Grid{
    Background = new SolidColorBrush(Colors.White), 
    RowDefinitions =
        {
            new RowDefinition { Height = new GridLength(50) }, 
            new RowDefinition(), 
            new RowDefinition { Height = new GridLength(50) }
        }, 
    ColumnDefinitions =
        {
            new ColumnDefinition(),
            new ColumnDefinition()
        }
};

The rest of the code from the Getting Started sample is exactly the same.  The result is a layout that stretches itself to the available space:

image

Windows Phone 7 Orientation

Now that we have a flexible layout, we can change the RootElement’s viewport whenever we want and XPF will re-evaluate our layout for us.  Let’s continue our example, by looking at how we might handle changes in orientation on WP7.  First let’s tell XNA that we can support all forms of orientation:

new GraphicsDeviceManager(this)
{
    SupportedOrientations =
        DisplayOrientation.Portrait |
        DisplayOrientation.LandscapeLeft |
        DisplayOrientation.LandscapeRight
};

Next we need to hook-up to the OrientationChanged event, changing XPF’s RootElement.Viewport in the handler.  You could do this using standard event handlers, but I’m going to use Reactive Extensions (Rx) so it will handle unhooking the event later if RootElement is disposed:

Observable.FromEvent<EventArgs>(
        handler => this.Game.Window.OrientationChanged += handler,
        handler => this.Game.Window.OrientationChanged -= handler)
    .Subscribe(_ => this.rootElement.Viewport = this.Game.GraphicsDevice.Viewport.ToRect());

That’s it we’re done.  Let’s fire it up and rotate our phone through 270 degrees and see the result:

A few lines of code and our entire layout becomes fluid and reflows without any manual intervention.  Building fluid layouts allows us to use the exact same code to target multiple resolutions and frees us from having to think too hard about how that impacts our implementation.

Star grid length and resizable RootElement are both available in the latest Nightly Build.

David Wynne
More from David