Handling Page Orientation in Windows Phone 7

Ed’s Note: This is an extract from the forthcoming book Windows Phone 7 In Action by Timothy Binkley-Jones, Massimo Perga and Michael Sync. For Source Code, Sample Chapters, the Author Forum and other resources, go to http://www.manning.com/perga/

Compliments of manning.com is a 35% discount off your next purchase at manning.com. Use Promotional Code perga1035 when you check out at manning.com.

Windows Phone 7 In Action Book Cover

Windows Phones, as with other small form factor devices, are able to deal with both the landscape and the portrait mode. Each page in the application must declare orientation modes it supports, so that the runtime framework can properly display the application, and can notify the application when the orientation changes.

The way in which a Silverlight page declares its supported orientations is by setting the PhoneApplicationPage, SupportedOrientations and Orientation properties, either in XAML or code behind.

<phone :PhoneApplicationPage 
   SupportedOrientations="Portrait" Orientation="Portrait">

In this case, the page declares that it supports Portrait mode using the SupportedOrientations attribute. SupportedOrientations can be set of one of the following values:

  • Portrait
  • PortraitOrLandscape
  • Landscape

The Orientation attribute defines the default orientation of the page. If just one orientation is supported, then the Orientation property must match the SupportedOrientations property; otherwise, it can be one of the PageOrientation values:

  • None
  • Portrait
  • Landscape
  • PortraitUp
  • PortraitDown
  • LandscapeLeft
  • LandscapeRight

The PageOrientation enum values are bit fields. The PortraitUp value has the bit flag for Portrait set. LandscapeLeft and LandscapeRight have the bit flag for Landscape set. PortraitDown is not used since the Windows Phone does will not rotate the screen into an upside down position.

If you’ve assigned a page ’s SupportedOrientations as PortraitOrLandscape you have to handle both orientations. For many applications, the best way to support both orientations is by using a layout control like StackPanel or Grid and doing nothing else. When the phone changes orientation, the layout panels automatically resize themselves and adjust the positions of their child controls.

To see how StackPanel automatically readjusts its children, we only need to build a simple application and modify the main page to support both Landscape and the Portrait mode.

SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"

When you launch the modified application, the layout can be changed by pressing one of the rotation buttons on the emulator ’s command bar. When the emulator changes orientation, the page automatically updates. This is because the page uses a combination of Grid and StackPanel controls, which rearrange their child controls. This works well when both orientations show the same basic user interface.

Let’s consider a situation where the landscape and portrait view are not identical. We are going to build a sample application, shown in figure 1, that displays an application title, a picture and a caption. When the phone is rotated to landscape, the page title disappears and only the picture and caption are shown.

Sample application demonstrating orientation support

Figure 1 Sample application demonstrating orientation support

To start our new sample application, create a new project from the Windows Phone Application project template. Open MainPage.xaml and update the SupportedOrientations property to PortraitOrLandscape. Import a picture into the root of your project, and set its Build Action pro perty to Content. Then add the code shown in listing 1 to the Grid named ContentPanel in MainPage.xaml.

Listing 1. Displaying a picture and a caption

<Grid x:Name="ContentPanel" Grid.Row ="1" Margin="12,0,12,0"> 
      <Grid.RowDefinitions> 
         <RowDefinition Height="*" /> 
         <RowDefinition Height="*" /> 
         <RowDefinition Height="Auto" /> 
         <RowDefinition Height="*" /> 
      </Grid.RowDefinitions> 
      <Grid.ColumnDefinitions> 
         <ColumnDefinition Width ="*" /> 
         <ColumnDefinition Wid th="Auto" /> 
         <ColumnDefinition Width ="*" /> 
      </Grid.ColumnDefinitions> 
      <Image x:Name="MyPhoto" Grid.Row="1" Grid.Column="1" 
         Source="/photo.jpg" /> 
      <TextBlock x:Name="MyPhotoLabel" Grid.Row ="2" Grid.Column="1"  
         Text="book cover" TextAlignment="Center" /> 
    </Grid>

In addition to this markup, we want to make the title disappear when in landscape mode and restore it when in portrait mode. To achieve this scenario we need to add a new handler for the OrientationChanged event. Select the whole page and add a handler for the OrientationChanged event. The code to implement the rotation is shown in listing 2.

Listing 2. Handling a change in orientation

private void PhoneApplicationPage_OrientationChanged( object sender,  
      OrientationChangedEventArgs e) 
{ 
  PageOrientation orientation = e.Orientation; 

  if ((orientation & PageOrientation.Landscape) 
        == PageOrientation.Landscape ) 
  { 
     ApplicationTitle.Visibility = Visibility .Collapsed; #A 
     PageTitle.Visibility = Visibility .Collapsed;        #A 

     ContentPanel.RowDefinitions[2].Height = GridLength .Auto; 
     ContentPanel.RowDefinitions[3].Height = GridLength .Auto; 

     MyPhoto.SetValue(Grid.RowProperty, 0);      
     MyPhoto.SetValue(Grid.RowSpanProperty, 3);    
     MyPhoto.SetValue(Grid.ColumnProperty, 0); 
     MyPhoto.SetValue(Grid.ColumnSpanProperty, 3); 

     MyPhotoLabel.SetValue(Grid.RowProperty, 3); 
     MyPhotoLabel.SetValue(Grid.ColumnProperty, 1); 
  } 
  else if ((orientation & PageOrientation.Portrait) 
        == PageOrientation.Portrait) 
  { 
     ApplicationTitle.Visibility = Visibility.Visible;    #B 
     PageTitle.Visibility = Visibility.Visible;           #B 

    ContentPanel.RowDefinitions[1].Height = 
      new GridLength (1, GridUnitType.Star); 
     ContentPanel.RowDefinitions[2].Height = GridLength .Auto; 
     ContentPanel.RowDefinitions[3].Height =  
      new GridLength (1, GridUnitType.Star); 

     MyPhoto.SetValue(Grid.RowProperty, 1); 
     MyPhoto.SetValue(Grid.RowSpanProperty, 1); 
     MyPhotoLabel.SetValue(Grid.ColumnProperty, 1); 
     MyPhotoLabel.SetValue(Grid.ColumnSpanProperty, 1); 

     MyPhotoLabel.SetValue(Grid.RowProperty, 3); 
     MyPhotoLabel.SetValue(Grid.ColumnProperty, 1); 
  } 
} 
#A Hide the titles 
#B Show the titles

The event handler gets the new orientation from the passed-in OrientationChangedEventArgs parameter and uses the new orientation value to determine how the layout should be updated. When checking the orientation property, a bitwise operation is performed to determine if the orientation value is Portrait or Landscape. In addition to hiding and showing the page titles, this code adjusts the layout and the positioning of the image and caption controls.

Screen orientation is not a something you normally have to account for when building Silverlight applications. Orientation is something unique to Silverlight for Windows Phone.

Summary

In this article, you learned about how an application can adapt to changes in the orientation of the phone. For many applications, the best way to support both orientations is by using a layout control like StackPanel or Grid, and doing nothing else. I n that case , when the phone changes orientation, the layout panels automatically resize themselves and adjust the positions of their child controls. We showed you what modifications to make when the landscape and portrait view are not identical.

You might also like...

Comments

About the author

Dan Maharry

Dan Maharry United Kingdom

Dan Maharry is the editor of DeveloperFusion. He has covered the latest in software development since the mid 90s. Not wishing to preach what he doesn't practice, Dan has also worked as a profes...

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.” - Donald Knuth