Categories: Blog

Understanding Page Orientation in Silverlight for Windows Phone

At MIX this year, Silverlight developers were handed a real treat: their first look at Silverlight for Windows Phone. Silverlight is the primary platform that developers will use to write applications for the new Windows phone, which will debut later this year. I can’t remember being this excited about a platform since…well, since Silverlight 1.0. If you’re an iPhone user like me, and you’d love to write iPhone apps but don’t care for Objective-C (soooooo 1990s!), Silverlight for Windows Phone is the hottest thing since color TV. Just think: you can leverage the skills you acquired writing Silverlight apps for the browser to write Silverlight apps for phones. You already know 90% of what you need to know; all you have to do is learn about the relatively few differences between Silverlight for the browser and Silverlight for the phone.

One of those differences is page orientation. When you write browser-based (or out-of-browser) Silverlight apps, you don’t have to worry about a user turning his or her monitor on its side. The phone, of course, is different. Silverlight for Windows Phone introduces the concept of page orientation, which tells you whether the phone is upright, upside-down, or on its side. Most apps don’t have to do much to rotate the entire display when the phone itself rotates; Silverlight does that for them. But some apps will need to know when the phone has rotated so they can customize the UI programmatically.

To demonstrate, I built a simple app that displays Dooby the Penguin:

 

When you create a new Silverlight for Windows Phone application, Visual Studio includes the following line of code in MainPage’s constructor in MainPage.xaml.cs:

SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;

This tells the runtime that the application supports both portrait and landscape orientations, and when the phone is rotated onto a side, Silverlight automatically rotates the display:

When you design a Silverlight for Windows Phone application that supports portrait and landscape modes, you strive to create a XAML UI that produces the look you want in either orientation without code intervention. In this example, because the penguin is positioned inside a Grid cell, it is automatically centered in the display whether the phone is upright or on its side.

If you don’t want the display to rotate when the orientation changes, you can remove Landscape from the page’s supported orientations:

SupportedOrientations = SupportedPageOrientation.Portrait;

Now turning the phone on its side will produce this:

The more interesting case is when code intervention is required to achieve the look you want when the orientation changes. For example, suppose you want to display one penguin in portrait mode, but two penguins in landscape mode:

 

If SupportedOrientations is SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape (or simply SupportedPageOrientation.PortraitOrLandscape), the page fires an OrientationChanging event when a turn begins and an OrientationChanged event once the turn is complete. You can use these events to modify the XAML UI. For example, I structured my XAML this way to display one penguin in portrait mode and two in landscape mode:

<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneBackgroundBrush}">

    <Grid.RowDefinitions>

        <RowDefinition Height="Auto"/>

        <RowDefinition Height="*"/>

    </Grid.RowDefinitions>

    <!–TitleGrid is the name of the application and page title–>

    <Grid x:Name="TitleGrid" Grid.Row="0">

        <TextBlock Text="ORIENTATION DEMO" x:Name="textBlockPageTitle"

            Style="{StaticResource PhoneTextPageTitle1Style}"

            HorizontalAlignment="Center"/>

    </Grid>

    <!–ContentGrid is empty. Place new content here–>

    <Grid x:Name="ContentGrid" Grid.Row="1">

        <Grid>

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="*" />

                <ColumnDefinition Width="0" x:Name="SecondColumn" />

            </Grid.ColumnDefinitions>

            <local:PenguinUserControl Grid.Column="0" />

            <local:PenguinUserControl Grid.Column="1"

                Visibility="Collapsed" x:Name="SecondPenguin" />

        </Grid>

    </Grid>

</Grid>

Then I did this in the code-behind:

public partial class MainPage : PhoneApplicationPage

{

    public MainPage()

    {

        InitializeComponent();

        SupportedOrientations = SupportedPageOrientation.Portrait |

            SupportedPageOrientation.Landscape;

         this.OrientationChanged +=

             new EventHandler<OrientationChangedEventArgs>(OnOrientationChanged);

    }

 

    void OnOrientationChanged(object sender, OrientationChangedEventArgs e)

    {

        if ((e.Orientation & PageOrientation.Landscape) != 0)

        {

            SecondPenguin.Visibility = Visibility.Visible;

            SecondColumn.Width = GridLength.Auto;

        }

        else // Portrait

        {

            SecondPenguin.Visibility = Visibility.Collapsed;

            SecondColumn.Width = new GridLength(0);

        }

    }

}

The Orientation property of the OrientationChangedEventArgs passed to the event handler is a PageOrientation object, which is defined this way in the Silverlight for Windows Phone runtime:

public enum PageOrientation

{

    Landscape = 2,

    LandscapeLeft = 0x12,

    LandscapeRight = 0x22,

    None = 0,

    Portrait = 1,

    PortraitDown = 9,

    PortraitUp = 5

} 

It follows that you can determine exactly what the phone’s orientation is (upright, upside-down, on its left side, or on its right side) by comparing e.Orientation to specific values such as PortraitUp and LandscapeRight. But the more common case is that you simply want to know whether the phone is oriented vertically or horizontally. You can check for the latter by ANDing e.Orientation with Landscape and checking for a nonzero value. That’s precisely what I’m doing in the OnOrientationChanged method above.

Interestingly enough, you can’t determine the phone’s orientation by checking the ActualWidth and ActualHeight properties of the Silverlight control or any other control; these properties don’t change when the orientation changes. (That’s how it works in the Silverlight for Windows Phone CTP, anyway; I can’t guarantee that will be the case in the final version.) Nor does there appear to be any way to determine what the phone’s orientation is at startup. However, if the application starts up in landscape mode, the page immediately fires its OrientationChanging and OrientationChanged events, so you can design your UI to assume that the application starts up in portrait mode and let your event handlers adjust the display if in fact it starts up in landscape mode.

Jeff Prosise

Recent Posts

8-Step AWS to Microsoft Azure Migration Strategy

Microsoft Azure and Amazon Web Services (AWS) are two of the most popular cloud platforms.…

3 days ago

How to Navigate Azure Governance

 Cloud management is difficult to do manually, especially if you work with multiple cloud…

2 weeks ago

Why Azure’s Scalability is Your Key to Business Growth & Efficiency

Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…

3 weeks ago

Unlocking the Power of AI in your Software Development Life Cycle (SDLC)

https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…

1 month ago

The Role of FinOps in Accelerating Business Innovation

FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…

1 month ago

Azure Kubernetes Security Best Practices

Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…

2 months ago