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.

giovedì 12 giugno 2014

Windows Phone 8.1 e i pulsanti hardware

Windows Phone 8.1 è un enorme passo avanti rispetto al passato verso una reale unificazione del codice sorgente tra la piattaforma desktop e la piattaforma mobile. Unificando i controlli e utilizzando pattern come MVVM per disgiungere completamente la componente visuale da quella logica è possibile scrivere degli applicativi il cui modello è comune e dove solo le pagine hanno comportamenti specifici per la piattaforma su cui stanno girando oppure, grazie agli stati visuali, addirittura avere le viste in comune per ogni piattaforma e variare il posizionamento dei componenti in base al form factor. Poi, ovviamente, un controllo per Windows Phone verrà renderizzato e gestito diversamente dall'OS rispetto allo stesso controllo per Windows 8.1, però in linea di massima allo sviluppatore questo dovrebbe importare poco se non rispetto al form factor. Il sistema di input è tutto a carico dell'OS.

Con Windows Phone 8.1 il ciclo di vita dell'applicativo è stato cambiato a favore dello stesso modello di Windows 8.1 Desktop. In un progetto Win81 che utilizza le WinPRT (Windows Phone RT), il pulsante hardware "back" viene gestito dell'OS come il mezzo di uscita dall'applicativo. Questo comportamento è profondamente differente rispetto a Windows Phone 7.1/8 e potrebbe creare problemi nella conversione di alcune applicazioni. La soluzione al nostro problema di retrocompatibilità è, però, decisamente semplice.

In un progetto WinPRT i pulsanti hardware sono gestiti dalla classe HardwareButtons che espone una serie di eventi relativi ai pulsanti di back, volume e camera. Tramite questa classe, possiamo scrivere un controllo dedicato alla gestione del pulsante di "indietro" secondo il vecchio comportamento che troviamo nei Windows Phone 7.1 e 8 prima generazione:

  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
    }


Basterà poi scambiare la pagina standard con questa nuova classe nello XAML e il gioco è fatto.

<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>

Il nostro applicativo seguirà ora la regola: "finchè ci sono elementi nella backstack torna indietro, altrimenti esci". Ovviamente il metodo di gestione dei pulsanti è scritto come virtual, in modo da poter gestire l'override per ogni esigenza particolare.

giovedì 23 gennaio 2014

Cenni su XAML

Cenni su XAML

In questo articolo inizieremo a introdurre il linguaggio di markup XAML, diventato ormai una pietra miliare nello sviluppo di applicativi per Microsoft Windows. Questo argomento si collega direttamente all'implementazione del pattern MVVM in Microsoft .NET, in quanto fornisce gli strumenti base per l'implementazione dei comandi e per legare l'interfaccia grafica al modello logico dell'applicativo.

lunedì 13 gennaio 2014

Lambda expressions - IL e blando performance test a pari condizioni di esecuzione - parte 1

Lamba expressions e IL

Era da tempo che mi chiedevo come il compilatore gestisse una funzione lambda. Esistono diverse possibilità al riguardo, tra cui una generazione a Runtime tramite dynamic methods. Oggi ho messo mano al disassemblatore .NET, alla ricerca di una risposta concreta.

mercoledì 8 gennaio 2014

Introduzione alle funzioni lambda in C#

Introduzione alle funzioni lambda (lambda expressions)

Nei linguaggi di programmazione ad alto livello vengono spesso introdotte particolari tipi di funzioni, dette funzioni anonime o funzioni lambda. Rimanendo su un discorso relativamente semplice, le lambda trovano il loro utilizzo come valore di argomento passato ad altre funzioni. Per loro stessa natura sono una sorta di funzioni annidate, ovvero funzioni dichiarate all'interno di altre funzioni, di cui condividono la visibilità locale delle variabili. Questo le rende particolarmente adatte a query o alberi di espressioni per funzioni di livello superiore. Tratteremo gli alberi di espressioni in un post dedicato. A grandi linee sono una rappresentazione a grafo di una serie di istruzioni imperative da eseguire, che possono essere popolati e compilati a runtime.
Utilizzando una variabile dove il puntatore alla funzione viene memorizzato, possono essere rese ricorsive.

Personalmente trovo le lambda una componente fondamentale della programmazione moderna. Permettono di scrivere codice molto compatto, sopratutto quando sono necessari degli handlers che verranno utilizzati sporadicamente dove il codice da scrivere risulta particolarmente semplice, e quindi di rendere più leggibile il nostro codice e a volte di generare IL maggiormente ottimizzato. Le lambda sono anche indispensabili per lo sviluppo utilizzando query LINQ, funzionalità diventata indispensabile nella manipolazione di strutture dati complesse.

domenica 5 gennaio 2014

Accenni di MVVM - Implementazione base

Nel post precedente, Accenni di MVVM - La teoria, abbiamo introdotto il pattern di sviluppo MVVM, derivato da MVC e pensato per disgiungere completamente la componente View e la componente Model di un software, utilizzando però una "zona franca" dove sia la parte grafica che la parte logica del programma possono accedere bi-direzionalmente.

Procediamo adesso con alcuni esempi di implementazione del pattern MVVM.

venerdì 3 gennaio 2014

Accenni di MVVM - la teoria

Breve Introduzione

Con l'avvento dei dispositivi moderni, sono emerse necessità nuove riguardo l'usabilità del software. Con l'avvento nel mercato consumer di tecnologie nuove per le grandi masse come ad esempio le CPU multi-core e le schede madri multi-CPU anche lo sviluppatore impegnato nella realizzazione di progetti non di grandi dimensioni o Enterprise ha dovuto imparare nuovi pattern, ovvero principi di realizzazione o tecniche di realizzazione se preferiamo, pensati appositamente per queste nuove necessità.

Il pattern MVC nasce già agli inizi degli anni 1970, quando hanno fatto la prima apparizione le interfacce grafiche e i linguaggi ad oggetti.

Il principio fondamentale di MVC è la distinzione tra una componente "Model", ovvero la logica pura completamente disgiunta da qualsiasi contesto visivo dell'applicazione, la componente "View" che rappresenta la parte visuale dell'applicativo a prescindere dai meccanismi logici che lo muovono sotto il cofano e componente "Controller", ovvero quella parte di codice che si prende carico di interpretare gli input dell'utente e mandare segnali sia alla "View" che al "Model".

Introducendo Windows Presentation Foundation all'interno del Framework .NET, è stato definito un pattern derivativo di MVC chiamato MVVM. Il principio fondamentale è lo stesso, mantenere disgiunte le parti di logica di funzionamento con quelle della componente grafica.
La differenza sottile, e neanche tanto secondo il mio punto di vista, sta nel fatto che nell'MVVM la terza componente è definita "ViewModel", ovvero una sezione ibrida di codice che contiene sia elementi della View che del Model, in pratica agendo senza l'utilizzo dei segnali tipici dell'MVC. La View viene pilotata tramite i Bindings, ovvero delle espressioni che descrivono un legame tra proprietà del ViewModel e elementi visuali della View, mentre al ViewModel gli input dell'utente vengono passati tramite i Command, che invece di segnali sono classi relazionali alla quale vengono associati metodi di esecuzione e metodi di validazione per l'esecuzione.

Schema riassuntivo del pattern MVVM


Perchè MVC/MVVM sono importanti nella programmazione moderna?

Sia MVC che MVVM sono importantissimi nella programmazione moderna. Sono a disposizione dei team di sviluppo strumenti di unit test sempre più sofisticati. Tramite questi software, è possibile vedere ogni oggetto o parte di codice come una scatola nera chiusa, mandare in input determinati valori e misurare l'output e le prestazioni di esecuzione. Legando il modello logico alla parte visuale come è ancora pratica diffusa, per esempio nella programmazione ad eventi, le attività di test vengono rese molto più difficili per la natura stessa non lineare del codice. Il debug e la manutenzione delle librerie è reso più dispersivo, perché il codice può non essere dove ce lo dovremmo aspettare. L'MVVM costringe a una buona progettazione delle classi sin dall'inizio. E anche in caso di errore, si può essere relativamente sicuri che tutto il codice che riguarda le logiche complesse lo andremo a trovare nelle aree dedicate al Model, quello puramente grafico nelle view e tutto il codice di collegamento nel ViewModel.

Principi base dell'implementazione di un ViewModel nel .NET Framework, ovvero INotifyPropertyChanged

La componente ViewModel deve essere in grado di comunicare in maniera efficiente con la View. Abbiamo già accennato che per fare questo vengono utilizzati solitamente i bindings e i commands. Il meccanismo di funzionamento dei bindings è molto semplice: una volta specificata una espressione di binding, il framework .NET si fa carico di registrare un handle di gestione dell'evento NotifyPropertyChanged della proprietà specificata come argomento dell'espressione. In questo modo, ogniqualvolta l'evento viene lanciato e ha come argomento il nome della proprietà del binding, la View automaticamente rilegge il valore della proprietà e aggiorna la proprietà del controllo collegato.



L'evento NotifyPropertyChanged è una implementazione locale dell'evento definito all'interno dell'interfaccia INotifyPropertyChanged, presente nel namespace System.ComponentModel.

Tutte le proprietà del ViewModel che sappiamo verranno aggiornate dal Model dovranno implementare una chiamata all'evento NotifyPropertyChanged, altrimenti la View non potrà sapere di eventuali modifiche ai valori. In più, non potranno essere utilizzate le proprietà automatiche, semplicemente perché nel set mancano di logica di controllo.

Input dell'utente - Commands

Molti dei controlli WPF implementano nativamente il supporto ai Commands. In MVVM, gli input utente sono passati al ViewModel mediante i commands, ovvero una serie di classi specifiche alla quel vengono legati due metodi: uno di esecuzione e l'altro, opzionale, di controllo e verifica.
Il comando dovrà implementare l'interfaccia ICommand del namespace System.Windows.Input. 
Tramite binding sulla proprietà Command del FrameworkElement, sarà possibile implementare le funzionalità del metodo di esecuzione su tutti i componenti di layout che ci interessano. Eventualmente, nel caso il nostro comando definisca un metodo di controllo e verifica, sarà premura del .NET abilitare o disabilitare quel controllo visuale nel caso il metodo di verifica restituisca "false" o "true" alla possibilità di eseguire il comando.

Svantaggi nell'implementazione di MVVM

In caso di progetti poco complessi o banali, lo svluppo MVVM può portare a inutile complessità del codice. Un classico esempio di Hello, World, ad esempio, che richiederebbe un semplice output nell'evento click di un controllo verrebbe ingigantito con l'implementazioni di almeno una classe ViewModel, un Command e due binding, uno per il comando e uno per l'output.
MVVM quindi si presta bene per progetti anche piccoli, ma con una complessità tale da giustificare la totale disgiunzione della logica di programmazione dalla logica di interfaccia. Per progetti con complessità minore, il pattern ad eventi risulta ancora una soluzione non solo percorribile, ma a mio parere migliore rispetto a MVVM.

Conclusioni

Per implementare l'MVVM è indispensabile solamente una buona progettazione iniziale e l'implementazione di INotifyPropertyChanged o equivalente. MVVM può essere utilizzato su qualsiasi linguaggio per qualsiasi piattaforma, non è un pattern specificatamente legato a .NET. Penso di essere nel giusto affermando che piuttosto .NET 3 e WPF in particolare sono nati per poter sposare completamente i pattern MVC e MVVM e facilitare lo unit testing e lo sviluppo agile delle applicazioni n-tier.
Progettando correttamente lo stato di ViewModel e astraendo completamente la View della logica, i software di media complessità risulteranno più semplici da manutenere e più adatti allo sviluppo multihread.