domenica 15 giugno 2014

About the Windows Phone 8.1 hardware buttons

Windows Phone 8.1 is a huge step forward compared to the past towards a real unification of the source code between the desktop and mobile platform. Unifying the controls and start using programming patterns as MVVM to uncouple the visual component from the model logic it is now possible to write applications which is in common with desktop and mobile scenarios and where only the pages have specific behaviors for the platform on which are running or, through Visual States, apps can even have common views for each platform and component placement will only vary depending on the form factor. Then, of course, a control for Windows Phone will be rendered and operated differently from the OS than the same control for Windows 8.1, though in principle the developer should matter little if compared to the form factor. The input system is entirely handled by the OS.

With Windows Phone 8.1 the lifecycle of the application has been changed in favour of the same Windows 8.1 Desktop model. In a Win81 project that uses the new WinPRT (Windows Phone RT), the hardware back button is handled by the OS as this means that common behavior is the exit from the application. This behavior is profoundly different than Windows Phone 7.1/8 and could create problems in the conversion of some applications. The solution to our compatibility problem is, however, very simple.

In a WinPRT project hardware buttons are handled by the HardwareButtons class that exposes a set of events related to back, volume and camera buttons. Through this class, we can write a control dedicated to the management of the "back" button according to the old behavior that we find in the Windows Phone 7.1 and 8 first generation:

  public class PhoneButtonsAwarePage
        : Page
    {
        #region .ctor

        public PhoneButtonsAwarePage()
            : base()
        {
            this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Required;
            HardwareButtons.BackPressed += HardwareButtons_BackPressed;
            HardwareButtons.CameraPressed += HardwareButtons_CameraPressed;
        }

        

        ~PhoneButtonsAwarePage()
        {
            try
            {
                HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
                HardwareButtons.CameraPressed -= HardwareButtons_CameraPressed;
            }
            catch(Exception)
            {

            }
        }

        #endregion

        #region Methods

        protected virtual void OnBackPressed(BackPressedEventArgs e)
        {
            if (this.Frame.CanGoBack)
            {
                e.Handled = true;
                this.Frame.GoBack();
            }
            else
                e.Handled = false;
        }

        protected virtual void OnCameraPressed(CameraEventArgs e)
        {            
        }

        #endregion

        #region Event Handlers

        private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
        {
            this.OnBackPressed(e);
        }

        private void HardwareButtons_CameraPressed(object sender, CameraEventArgs e)
        {
            this.OnCameraPressed(e);
        }        

        #endregion
    }

Then just swap the standard page with this new class in XAML and you're done.

<common:PhoneButtonsAwarePage x:Class="Test.Views.TestPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:Test.Views"
      xmlns:common="using:Test.Common"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d"
      RequestedTheme="Light"
      Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>

    </Grid>
</common:PhoneButtonsAwarePage>

Our application will follow the rule: "as long as there are items in the backstack, go back, otherwise exit." Obviously the management method of the buttons is written as virtual, so you can handle the override for any special requirements of your app.

Nessun commento:

Posta un commento