Windows 8.1 – Screen Mode Detection

During the development of my Windows Store application I faced out that is not that easy to detect the current screen mode to adjust consequently the layout.

These are the different screen modes available in Windows 8:

  • Portait orientation.
  • Landscape orientation, Full Screen.
  • Landscape orientation, Snapped. Sharing the screen with other applications, see the next image as an example.

Windows 8 - Screen Sharing

When the application is sharing the screen with other applications it is also important to distinguish between having a big portion of the screen or not:

smallPortionScreen

In Windows 8 it was easier to detect the screen mode:

private void WindowSizeChanged(object sender, WindowSizeChangedEventArgs e) {
    // Get view state
    ApplicationViewState currentViewState = ApplicationView.Value;

    if (currentViewState == ApplicationViewState.FullScreenLandscape) {
       // Full screen Landscape layout
    }
    else if (currentViewState == ApplicationViewState.FullScreenPortrait) {
       // Full screen Portrait layout
    }
    else if (currentViewState == ApplicationViewState.Filled) {
       // Filled layout
    }
    else if (currentViewState == ApplicationViewState.Snapped) {
       // Snapped layout
    }
}

But in Windows 8.1 the ApplicationView is deprecated, developers can only know if the screen is in Landscape or Portrait. I implemented a helper class called ScreenManager to get the current screen mode, this class has also an Event to notify when the screen mode changed:

These are the Screen Modes that I defined:

public enum ScreenMode
    {
        /// <summary>
        /// Unknown state
        /// </summary>
        Unknown = 0,
 
        /// <summary>
        /// Full screen in landscape mode
        /// </summary>
        Landscape,
 
        /// <summary>
        /// Full screen in portrait mode
        /// </summary>
        Portrait,
 
        /// <summary>
        /// Shared screen, current application has 500px or less
        /// </summary>
        Narrow,
 
        /// <summary>
        /// Shared screen, current application has more than 500px
        /// </summary>
        Wide,
    }

This class could be used to calculate the current screen mode and also to detect when it changes, we could for example shrink or hide some elements when the application is only taking a small portion of the screen. Of course it could be used to trigger a different VisualState.

Example of use:

public GamePage()
{
    this.InitializeComponent();
 
    ScreenManager screenManager = new ScreenManager(this);
    screenManager.ScreenModeChanged += ScreenManagerOnScreenModeChanged;
}
 
private void ScreenManagerOnScreenModeChanged(object sender, ScreenModeChangedEventArgs screenModeChangedEventArgs)
{
    Debug.WriteLine("GamePage: {0}, New VisulState: {1}", screenModeChangedEventArgs.ScreenSize.Width, screenModeChangedEventArgs.ScreenMode);
}

ScreenManager.cs

using System;
using Windows.UI.Core;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
 
namespace WindowsStore.Common.Screen
{
    public class ScreenManager : IDisposable
    {
        private ScreenMode screenMode;
 
        /// <summary>
        /// Initializes a new instance of the <see cref="ScreenManager"/> class.
        /// </summary>
        /// <param name="page">The associated page.</param>
        public ScreenManager(Page page)
        {
            page.Loaded += delegate
            {
                Window.Current.SizeChanged += this.OnSizeChanged;
            };
 
            page.Unloaded += delegate
            {
                Window.Current.SizeChanged -= this.OnSizeChanged;
                this.Dispose();
            };
        }
 
        /// <summary>
        /// Occurs when [screen mode changed].
        /// </summary>
        public event ScreenModeChangedEventHandler ScreenModeChanged;
 
        /// <summary>
        /// Gets the screen mode.
        /// </summary>
        /// <value>
        /// The screen mode.
        /// </value>
        public ScreenMode ScreenMode
        {
            get
            {
                if (screenMode == ScreenMode.Unknown)
                {
                    screenMode = this.DetermineScreenMode();
                }
                return screenMode;
            }
            private set { screenMode = value; }
        }
 
        #region privates
 
        /// <summary>
        /// Determines the screen mode:
        /// - FullScreenLandscape
        /// - FullScreenPortrait
        /// - Wide
        /// - Narrow
        /// </summary>
        private ScreenMode DetermineScreenMode()
        {
            ScreenMode state;
 
            var applicationView = ApplicationView.GetForCurrentView();
            var size = Window.Current.Bounds;
 
            if (applicationView.IsFullScreen)
            {
                state = applicationView.Orientation == ApplicationViewOrientation.Landscape ? ScreenMode.Landscape : ScreenMode.Portrait;
            }
            else
            {
                state = size.Width <= 500 ? ScreenMode.Narrow : ScreenMode.Wide;
            }
 
            return state;
        }
 
        /// <summary>
        /// Called when [size changed], trigger the determination of the current visual state.
        /// </summary>
        private void OnSizeChanged(object sender, WindowSizeChangedEventArgs e)
        {
            this.ScreenMode = DetermineScreenMode();
 
            if (ScreenModeChanged != null)
            {
                ScreenModeChanged(sender, new ScreenModeChangedEventArgs { ScreenMode = this.ScreenMode, ScreenSize = e.Size });
            }
        }
 
        #endregion
 
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            this.ScreenModeChanged = null;
        }
    }
}

References:

Advertisements

One thought on “Windows 8.1 – Screen Mode Detection

Your feedback is important...

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s