Set supported orientations in XAML on Windows Phone 8.1

Being able to set supported orientations in XAML on every page by simply setting the SupportedOrientations property on PhoneApplicationPage is something Windows Phone developers are used to on Silverlight platform. However, with Windows Phone 8.1 and WinRT platform, it's possible to do so (only?) in code behind.

On Windows Phone 8.1 you can set the supported orientations in Package.appxmanifest. Setting it that way means you're setting it on application level - all pages follow the same rule.  However, there is a way to set the current supported orientation using

DisplayInformation.AutoRotationPreferences = DisplayOrientations.Portrait;  

at any moment, which sets the orientation to Portrait (in this example). It makes sense to have different supported orientations on different pages in some cases.

DisplayOrientations is an enum with the following (flag) values:

public enum DisplayOrientations  
    None = 0,
    Landscape = 1,
    Portrait = 2,
    LandscapeFlipped = 4,
    PortraitFlipped = 8,

which means that you can combine orientations. So, if you want to support LandscapeFlipped and Portrait, you would do:

DisplayInformation.AutoRotationPreferences = DisplayOrientations.LandscapeFlipped | DisplayOrientations.Portrait;  

That works, but it has to be set in code behind.

However, if you're used to defining it in XAML, which seems a bit cleaner to me especially if you're implementing MVVM pattern and you feel that this belongs to your view, you could use the following attached property:

public class PageOrientation  
    public static readonly DependencyProperty SupportedOrientationsProperty =
        typeof(String), typeof(PageOrientation),
        new PropertyMetadata(null, OnSupportedOrientationsChanged));

    public static void SetSupportedOrientations(UIElement element, object value)
        element.SetValue(SupportedOrientationsProperty, value);

    public static object GetSupportedOrientations(UIElement element)
        return element.GetValue(SupportedOrientationsProperty);

    private static void OnSupportedOrientationsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        DisplayOrientations supportedOrientations = (DisplayOrientations)Enum.Parse(typeof(DisplayOrientations), (string)args.NewValue);

        DisplayInformation.AutoRotationPreferences = supportedOrientations;

in page XAML like this:


If you want multiple enum values, just add them in the form of comma-separated values. I attached it to Page object because it's intuitive that way, but as you can see in OnSupportedOrientationsChanged callback, it doesn't really care about the Page object - it's setting the DisplayInformation.AutoRotationPreferences instead. This means that you're changing the setting for the entire application when you do this, so if you want different orientations on different pages, it's best that you define it explicitly on every page so that it's easy to understand and that no bugs get introduced.

I thought about abstracting the enums to 3 values - Portrait, LandscapePortraitOrLandscape. Do you think that it would make it more straightforward?

About Igor Ralic

Software engineer at Microsoft. Running for Office. Passionate about making an impact with great apps & services. Stays close to coffee and away from coriander. Opinions expressed here are my own.