Model View ViewModel per Windows Store
                Apps
              Andrea Boschin
              MVP Silverlight

                guest star
               MVVM Toolkit
agenda

 introduzione
   due parole due sul pattern (per chi non lo
    conosce)
 mvvm topics
   carrellata sulle problematiche
 toolkit
   strumenti da utilizzare
 soluzioni
   demo di una soluzione windows store
introduzione

 perchè mvvm?
  manutenibilità
    migliore organizzazione del codice è quindi più semplice
     la manutenzione.
  riutilizzo
    la realizzazione di viewmodel generici consente un
     riutilizzo delle logiche
  testabilità
    il codice nei viewmodel è completamente testabile
     mediante unit test e mocking.
  disaccopiamento
    la separazione tra view e viewmodel consente la
     separazione del lavoro tra designer e developer.
introduzione
 model-view-viewmodel
  View
    rappresenta l’interfaccia visibile
     all’utente
  ViewModel
    adattatore tra View e Model,
     contiene la logica di UI
                                                      VIEW
  Model
    rappresenta la                       binding               command
     sorgente/destinazione delle
                                                    VIEWMODEL
     informazioni


                                                     MODEL
introduzione
 i messaggi
  La UI contiene molte View
    Ciascuna ha un compito specifico
  Ogni View ha un ViewModel separato
    due view con lo stesso viewmodel hanno il medesimo
     comportamento
  i ViewModel «parlano» tra loro
    utilizzano «Messaggi»      VIEW                   VIEW




                              VIEWMODEL   messaggi   VIEWMODEL




                               MODEL                  MODEL
introduzione
 i servizi
   forniscono funzionalità a supporto
   incapsulano logiche che non si sposano col
    pattern
   anche il model è un servizio


                         VIEW                   VIEW




                                                          SERVIZI
                       VIEWMODEL   messaggi   VIEWMODEL




                        MODEL                  MODEL
mvvm basic

 connettere model e viewmodel
  Il ViewModel è il DataContext della View
  <ui:View.DataContext>
      <vm:MyViewModel />
  </ui:View.DataContext>




  Le proprietà popolano la View mediante binding
  <TextBox Text="{Binding Title}" />




  I comandi comunicano le azioni al ViewModel
  <Button Content="Ok"
          Command="{Binding OkCommand}"
          CommandParameter="{Binding Id}" />
mvvm basic

 comandi
  un comando è una istanza di "ICommand"
  <Button Content="Ok"
          Command="{Binding OkCommand}"
          CommandParameter="{Binding Id}" />




  Nel ViewModel è rappresentato da una proprietà
  public class MyViewModel
  {
      public ICommand OkCommand { get; set; }
  }



  N.B. ICommand espone
     CanExecute(parameter)
     Execute(parameter)
mvvm basic

 messaggi
  i messaggi sono gestiti mediante un servizio
   "dispatcher" (vedi toolkit)
  possono essere diretti ad uno specifico
   ViewModel oppure in "broadcast"
  public class MyViewModel
  {
      public void MyViewModel()
      {
           Messenger.Default.Subscribe(ReceiveAMessage);
      }

      public void SendAMessage()
      {
           Messenger.Default.Send("this is a message");
      }

      public void ReceiveAMessage(object message) {}
  }
mvvm basic

 servizi
   i servizi sono classi che vivono "lateralmente" ai
    ViewModel
   possono essere oggetto di messaggi o essere
    forniti al ViewModel mediante interfacce

  public class MyViewModel
  {
      public MyViewModel(IDataService dataService)
      { ... }
  }


   Dependency Injection
toolkit

 mvvm light toolkit
   strumento open source gratuito scaricabile da
    "nuget"
   fornisce quasi tutto ciò che serve
       template di VS2012
       dispatcher/messenger
       implementazioni di ICommand (RelayCommand)
       simple IoC
   esiste per WPF/Silverlight/Windows
    Phone/Windows Store
soluzioni

 dov'è il mio viewmodel?
  collegare il viewmodel alla view direttamente non
   è consigliabile
  meglio sfruttate un servizio che gestisce i
   ViewModel


 ViewModel Locator
  consente la "dependency injection" e facilita la
   testabilità
  supporta il design time
  gestisce il lifetime dei ViewModel
  fornisce le istanze alle View
soluzioni

 comandi
   da Silverlight in poi solo i Button hanno un
    command!!
   per tutti gli altri si "usavano" i behavior di "Blend
    SDK"


 purtroppo...
   i behavior non esistono in WinRT 

 soluzione?
   "smanacciare" nel codebehind...
   ...oppure farsi un behavior (EventToCommand)!
     http://winrtbehaviors.codeplex.com/
     https://nuget.org/packages/WinRtBehaviors
soluzioni

 gestire il load del ViewModel
  usare il costruttore può causare freezing
    spesso è conveniente aspettare un momento più
     propizio


  conviene gestire l'evento LayoutUpdated
    al primo caricamento l'evento viene sollevato al termine
     del render della pagina
    è il momento giusto per caricare i dati

  usare una classe base per la View.
    gestire l'evento e comunicarlo al ViewModel
    funziona solo a runtime. a design-time LayoutUpdate
     non è invocato
soluzioni

 inviare messaggi
  nel mvvm toolkit, è un dispatcher molto efficace
    Messenger.Default

  implementa il pattern publish-subscribe
    Send<T>()
      invia un messaggio
    Register<T>()
      si mette in ascolto


  consente di fare broadcast o inviare messaggi
   diretti
soluzioni

 un servizio per navigare
   la navigazione è strettamente connessa con il frame
     in teoria può essere invocata solo dal codebehind

   un servizio può inizializzare il frame e detenere un
    riferimento
     in OnLaunched si inizializza il frame
     il servizio viene acquisito dai ViewModel dal container IoC (per
       testabilità)

   il NavigationService ha comandi bindabili per facilitare la
    gestione da XAML
     GoBackCommand
     CanGoBack

   la navigazione avviene mediante Url interni che
    ammettono parametri
     app://MainView/?id=100
    
soluzioni

 gestione di ApplicationViewState
  la classe base delle View gestisce i possibili stati
    gestione simile alla LayoutAwarePage (template VS)

  per comodità li mappa su stati che hanno lo
   stesso nome
      FullScreenLandscape
      Filled
      Snapped
      FullScreenPortrait

  usare opportunamente gli stati del
   VisualStateManager
    gli elementi vengono modificati in funzione allo stato
soluzioni

 blendability
   caratteristica delle applicazioni MVVM
      sfrutta la capacità di blend di eseguire parte del codice a
       design-time

   consentono l'utilizzo di dati fittizi che facilitano il
    design
      il design è nettamente avvantaggiato da un feedback
       diretto

   grazie al container IoC viene iniettato un servizio dati
    che ha dei metodi che restituiscono valori fittizi
     il supporto è garantito dal ViewModelLocator

   il supporto richiede un minimo sforzo nei ViewModel
    che si aspettano parametri
     in tal caso bisogna gestire parametri fittizi a design-time
conclusione

 mvvm a tutti i costi?
   NO: le logiche di interfaccia vanno nel codebehind
     esempio: attivare un textbox alla selezione di un checkbox)

   NO: alcune logiche che richiedono eccessiva
    complessità vanno nel codebehind
     esempio: usare le proprietà alla stregua di metodi

   NO: i controlli possono incapsulare logiche di
    interfaccia e renderle riutilizzabili
      esempio: una textbox animata non ha nulla a che vedere
      con il ViewModel

   NO: i servizi servono anche a questo
     quello che non si può mettere nel ViewModel può far parte
      di un servizio (dialog, navigazione...)
contact me…

            o feedback su:
                • http://xedotnet.org/feedback


            codice feedback: MAR63

            email: andrea@boschin.it
            twitter: @aboschin
            xbox: codeblock68
            facebook: http://www.facebook.com/thelittlegrove


 feedback




 10

Model-View-ViewModel con Windows Store Apps

  • 1.
    Model View ViewModelper Windows Store Apps Andrea Boschin MVP Silverlight guest star MVVM Toolkit
  • 2.
    agenda  introduzione  due parole due sul pattern (per chi non lo conosce)  mvvm topics  carrellata sulle problematiche  toolkit  strumenti da utilizzare  soluzioni  demo di una soluzione windows store
  • 3.
    introduzione  perchè mvvm?  manutenibilità  migliore organizzazione del codice è quindi più semplice la manutenzione.  riutilizzo  la realizzazione di viewmodel generici consente un riutilizzo delle logiche  testabilità  il codice nei viewmodel è completamente testabile mediante unit test e mocking.  disaccopiamento  la separazione tra view e viewmodel consente la separazione del lavoro tra designer e developer.
  • 4.
    introduzione  model-view-viewmodel View  rappresenta l’interfaccia visibile all’utente  ViewModel  adattatore tra View e Model, contiene la logica di UI VIEW  Model  rappresenta la binding command sorgente/destinazione delle VIEWMODEL informazioni MODEL
  • 5.
    introduzione  i messaggi  La UI contiene molte View  Ciascuna ha un compito specifico  Ogni View ha un ViewModel separato  due view con lo stesso viewmodel hanno il medesimo comportamento  i ViewModel «parlano» tra loro  utilizzano «Messaggi» VIEW VIEW VIEWMODEL messaggi VIEWMODEL MODEL MODEL
  • 6.
    introduzione  i servizi  forniscono funzionalità a supporto  incapsulano logiche che non si sposano col pattern  anche il model è un servizio VIEW VIEW SERVIZI VIEWMODEL messaggi VIEWMODEL MODEL MODEL
  • 7.
    mvvm basic  connetteremodel e viewmodel  Il ViewModel è il DataContext della View <ui:View.DataContext> <vm:MyViewModel /> </ui:View.DataContext>  Le proprietà popolano la View mediante binding <TextBox Text="{Binding Title}" />  I comandi comunicano le azioni al ViewModel <Button Content="Ok" Command="{Binding OkCommand}" CommandParameter="{Binding Id}" />
  • 8.
    mvvm basic  comandi  un comando è una istanza di "ICommand" <Button Content="Ok" Command="{Binding OkCommand}" CommandParameter="{Binding Id}" />  Nel ViewModel è rappresentato da una proprietà public class MyViewModel { public ICommand OkCommand { get; set; } }  N.B. ICommand espone  CanExecute(parameter)  Execute(parameter)
  • 9.
    mvvm basic  messaggi  i messaggi sono gestiti mediante un servizio "dispatcher" (vedi toolkit)  possono essere diretti ad uno specifico ViewModel oppure in "broadcast" public class MyViewModel { public void MyViewModel() { Messenger.Default.Subscribe(ReceiveAMessage); } public void SendAMessage() { Messenger.Default.Send("this is a message"); } public void ReceiveAMessage(object message) {} }
  • 10.
    mvvm basic  servizi  i servizi sono classi che vivono "lateralmente" ai ViewModel  possono essere oggetto di messaggi o essere forniti al ViewModel mediante interfacce public class MyViewModel { public MyViewModel(IDataService dataService) { ... } }  Dependency Injection
  • 11.
    toolkit  mvvm lighttoolkit  strumento open source gratuito scaricabile da "nuget"  fornisce quasi tutto ciò che serve  template di VS2012  dispatcher/messenger  implementazioni di ICommand (RelayCommand)  simple IoC  esiste per WPF/Silverlight/Windows Phone/Windows Store
  • 12.
    soluzioni  dov'è ilmio viewmodel?  collegare il viewmodel alla view direttamente non è consigliabile  meglio sfruttate un servizio che gestisce i ViewModel  ViewModel Locator  consente la "dependency injection" e facilita la testabilità  supporta il design time  gestisce il lifetime dei ViewModel  fornisce le istanze alle View
  • 13.
    soluzioni  comandi  da Silverlight in poi solo i Button hanno un command!!  per tutti gli altri si "usavano" i behavior di "Blend SDK"  purtroppo...  i behavior non esistono in WinRT   soluzione?  "smanacciare" nel codebehind...  ...oppure farsi un behavior (EventToCommand)!  http://winrtbehaviors.codeplex.com/  https://nuget.org/packages/WinRtBehaviors
  • 14.
    soluzioni  gestire ilload del ViewModel  usare il costruttore può causare freezing  spesso è conveniente aspettare un momento più propizio  conviene gestire l'evento LayoutUpdated  al primo caricamento l'evento viene sollevato al termine del render della pagina  è il momento giusto per caricare i dati  usare una classe base per la View.  gestire l'evento e comunicarlo al ViewModel  funziona solo a runtime. a design-time LayoutUpdate non è invocato
  • 15.
    soluzioni  inviare messaggi  nel mvvm toolkit, è un dispatcher molto efficace  Messenger.Default  implementa il pattern publish-subscribe  Send<T>()  invia un messaggio  Register<T>()  si mette in ascolto  consente di fare broadcast o inviare messaggi diretti
  • 16.
    soluzioni  un servizioper navigare  la navigazione è strettamente connessa con il frame  in teoria può essere invocata solo dal codebehind  un servizio può inizializzare il frame e detenere un riferimento  in OnLaunched si inizializza il frame  il servizio viene acquisito dai ViewModel dal container IoC (per testabilità)  il NavigationService ha comandi bindabili per facilitare la gestione da XAML  GoBackCommand  CanGoBack  la navigazione avviene mediante Url interni che ammettono parametri  app://MainView/?id=100 
  • 17.
    soluzioni  gestione diApplicationViewState  la classe base delle View gestisce i possibili stati  gestione simile alla LayoutAwarePage (template VS)  per comodità li mappa su stati che hanno lo stesso nome  FullScreenLandscape  Filled  Snapped  FullScreenPortrait  usare opportunamente gli stati del VisualStateManager  gli elementi vengono modificati in funzione allo stato
  • 18.
    soluzioni  blendability  caratteristica delle applicazioni MVVM  sfrutta la capacità di blend di eseguire parte del codice a design-time  consentono l'utilizzo di dati fittizi che facilitano il design  il design è nettamente avvantaggiato da un feedback diretto  grazie al container IoC viene iniettato un servizio dati che ha dei metodi che restituiscono valori fittizi  il supporto è garantito dal ViewModelLocator  il supporto richiede un minimo sforzo nei ViewModel che si aspettano parametri  in tal caso bisogna gestire parametri fittizi a design-time
  • 19.
    conclusione  mvvm atutti i costi?  NO: le logiche di interfaccia vanno nel codebehind  esempio: attivare un textbox alla selezione di un checkbox)  NO: alcune logiche che richiedono eccessiva complessità vanno nel codebehind  esempio: usare le proprietà alla stregua di metodi  NO: i controlli possono incapsulare logiche di interfaccia e renderle riutilizzabili  esempio: una textbox animata non ha nulla a che vedere con il ViewModel  NO: i servizi servono anche a questo  quello che non si può mettere nel ViewModel può far parte di un servizio (dialog, navigazione...)
  • 20.
    contact me… o feedback su: • http://xedotnet.org/feedback codice feedback: MAR63 email: andrea@boschin.it twitter: @aboschin xbox: codeblock68 facebook: http://www.facebook.com/thelittlegrove feedback 10