
Support WP7 Orientation Without Rotation
While working on a new app, I came upon a scenario in which I wanted the phone to support both Portrait and Landscape orientations, but I didn’t want the content on the page to rotate. I wanted the user to feel that they had rotated the phone, but the particulars of my app would make rotating the content nonsensical. What advantages are there for this? First, from the user perspective, if your app has an app bar and supports multiple orientations, the app bar rotates the icons and the menu items fly in from the sides. Everything is right side up, providing a great experience to the user. Second, supporting multiple orientations allows you to receive the OnOrientationChanged event and make easy calls to determine the orientation of the phone.
Before I begin, If all you want is the second option, the best way might be to only support Portrait (or Landscape) orientation and use the OrientationHelpers class from the Level Starter Kit sample. In my case, what I really wanted was the app bar buttons and menu to work as normally expected in both orientations, so OrientationHelpers wasn’t sufficient.
The easiest way to keep the content from rotating is to add a counter rotation to the Page using a RenderTransform of type CompositeTransform. Your XAML would look like this:
[sourcecode language=“xml”] <phone:PhoneApplicationPage> . . . <phone:PhoneApplicationPage.RenderTransform> <CompositeTransform x:Name="pageRotator" CenterX="0" CenterY="0" Rotation="0" TranslateY="0" TranslateX="0"></CompositeTransform> </phone:PhoneApplicationPage.RenderTransform>
</phone:PhoneApplicationPage> [/sourcecode]
This is added to the XAML of the page and the properties can be entered and bound just like most Silverlight properties. Here, I changed the properties in the OnOrientationChanged event in the code behind.
[sourcecode language=“csharp”] protected override void OnOrientationChanged(OrientationChangedEventArgs e) { switch (e.Orientation) { case PageOrientation.PortraitUp: pageRotator.Rotation = 0; pageRotator.TranslateY = 0; pageRotator.TranslateX = 0; break; case PageOrientation.LandscapeLeft: pageRotator.Rotation = -90; pageRotator.TranslateY = 480; pageRotator.TranslateX = 0; break; case PageOrientation.LandscapeRight: pageRotator.Rotation = 90; pageRotator.TranslateY = 0; pageRotator.TranslateX = 728; break; } base.OnOrientationChanged(e); } [/sourcecode]
Obviously, if you’re an MVVM purist, you can put all this in the ViewModel and have the XAML databound to properties. The above code checks what orientation the phone was changed to and then sets the transforms on the CompositeTransform accordingly. If we only had a RotateTransform, the page would rotate, but would be off the screen. Here, I’m supporting a device of resolution 480 x 800 with an app bar of 72px tall.
Below shows how I wanted the screen to look in 3 orientations.* [gallery orderby=“post_date”]
- Since this was some Photoshop work, sharp eyed readers will note all the icons in the app bar in Landscape Down are in the wrong position. They would be right side up, but in the reverse order. The idea is evident, though.