<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>QMatteoQ's blog - Il blog di Matteo Pagani</title><link>http://www.qmatteoq.com/</link><description>QMatteoQ's blog - Il blog di Matteo Pagani</description><copyright>Dexter</copyright><docs>http://www.rssboard.org/rss-specification</docs><generator>http://www.tostring.it/about/dexter</generator><language>en-US</language><lastBuildDate>Wed, 15 May 2013 10:00:00 GMT</lastBuildDate><webMaster>qmatteoq</webMaster><category>QMatteoQ</category><category>Mobile</category><category>iPhone</category><category>iPad</category><category>Windows Phone</category><category>Microsoft</category><category>Apple</category><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/qmatteoq" /><feedburner:info uri="qmatteoq" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Caliburn Micro e Windows Phone – Il controllo Pivot</title><description>&lt;p&gt;Panorama e pivot sono due concetti chiave in Windows Phone: sono, probabilmente, due dei controlli più utilizzati per definire l’interfaccia delle applicazioni, dato che consentono di creare interfacce originali e molto differenti da quelle tipiche delle applicazioni per iOS e Android.&lt;/p&gt;  &lt;p&gt;Il controllo Panorama viene utilizzato, solitamente, come punto di partenza di un’applicazione: ogni pagina, che può essere sfogliata con uno swipe verso destra o verso sinistra, mostra un’anteprima del contenuto della pagina successiva, così che l’utente possa immediatamente capire che ci sono altri elementi da visualizzare. Il controllo Panorama deve essere utilizzato come punto di partenza di un’applicazione, non come contenitore di dati: un panorama deve essere utilizzato per dare una breve anteprima di quello che l’applicazione ha da offrire e un modo semplice per accedere alle varie sezioni e opzioni. Per esempio, se state sviluppando un’applicazione per leggere le ultime notizie, non è corretto mostrare tutte le notizie in una pagina del panorama; è corretto, invece, mostrare solo le ultime 10 notizie e aggiungere un pulsante per aprire una pagina di dettaglio con l’elenco completo delle notizie.&lt;/p&gt;  &lt;p&gt;Il controllo Pivot, invece, viene utilizzato per mostrare informazioni differenti legate allo stesso contesto, oppure la stessa informazione ma collegata a elementi diversi. Un esempio del primo scenario ci viene dato dall’hub People, nello specifico dalla pagina di dettaglio di un contatto: in questo caso, il controllo Pivot viene utilizzato per mostrare informazioni differenti (dettaglio, foto, post sui social network, ecc.) legate allo stesso contesto (il contatto). Un’applicazione meteo, invece, è un buon esempio del secondo scenario: il controllo Pivot può essere utilizzato per mostrare la stessa informazione (le previsioni del tempo) ma legata a elementi differenti (le città).&lt;/p&gt;  &lt;p&gt;Gestire il controllo Panorama o Pivot in un’applicazione sviluppata con il pattern MVVM non è complesso: le pagine che compongono un Panorama o un Pivot sono “finte” (non sono effettivamente pagine XAML diverse, ma controlli differenti, di tipo &lt;strong&gt;PanoramaItem&lt;/strong&gt; o &lt;strong&gt;PivotItem&lt;/strong&gt;, inseriti all’interno di un “grande contenitore” presente nella pagina, ovvero il controllo &lt;strong&gt;Panorama &lt;/strong&gt;o &lt;strong&gt;Pivot&lt;/strong&gt;). Di conseguenza, è sufficiente collegare tra di loro una View e un ViewModel (con i relativi dati esposti) usando le convenzioni di Caliburn Micro che abbiamo imparato ad utilizzare nei post precedenti.&lt;/p&gt;  &lt;p&gt;Esiste però un altro approccio, che consente di suppportare caratteristiche come il lazy loading e di organizzare meglio il proprio codice. Vediamo quale.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;IMPORTANTE! &lt;/strong&gt;Anche se, dal punto di vista dell’architettura, Panorama e Pivot sfruttano il medesimo approccio, saremo in grado di sfruttare il meccanismo che vedremo a breve solo con il controllo Pivot, a causa di un bug nel Panorama introdotto in Windows Phone 8. Qual è il problema? Che se gli elementi che compongono un Panorama vengono aggiunti sfruttando il binding con la proprietà &lt;strong&gt;ItemsSource&lt;/strong&gt; (invece che essere direttamente dichiarati nello XAML o manualmente nel code behind), la proprietà &lt;strong&gt;SelectedIndex&lt;/strong&gt; (che è importante per tenere traccia della vista corrente) non funziona correttamente e restituisce solamente i valori 0 e 1, indipendentemente da quale sia la vista effettivamente in uso.&lt;/p&gt;  &lt;h3&gt;La classe Conductor&lt;/h3&gt;  &lt;p&gt;Calibun Micro supporta il concetto di &lt;strong&gt;Conductor: &lt;/strong&gt;una serie di pagine che sono collegate tra di loro e che sono gestite da un singolo punto di accesso. Con questo approccio, siamo in grado di avere una pagina principale, che funge da “conductor”, e pagine differenti con il relativo ViewModel, che costituscono le varie viste del Pivot. &lt;/p&gt;  &lt;p&gt;Il primo vantaggio di questo approccio è che che ci consente di mantenere il codice più pulito e semplice da mantenere: invece di avere un unico ViewModel che deve gestire tutte le viste differenti, avete View e ViewModel separati.&lt;/p&gt;  &lt;p&gt;Facciamo qualche esperimento utilizzando il controllo Pivot. Innanzitutto dobbiamo creare la pagina che fungerà da conduttore e che conterrà il Piot: aggiungete una nuova pagina nella cartella &lt;strong&gt;Views&lt;/strong&gt; del progetto (ad esempio, di nome &lt;strong&gt;PivotView&lt;/strong&gt;) e il relativo ViewModel nella cartella &lt;strong&gt;ViewModels&lt;/strong&gt; (seguendo la convenzione standard, il nome da assegnare alla classe è &lt;strong&gt;PivotViewModel&lt;/strong&gt;). Ricordatevi di registrare il ViewModel nel metodo &lt;strong&gt;Configure()&lt;/strong&gt; del boostrapper!&lt;/p&gt;  &lt;p&gt;Vediamo ora la definizione del ViewModel:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;public class PivotViewModel: Conductor&amp;lt;IScreen&amp;gt;.Collection.OneActive 
{ 
    private readonly PivotItem1ViewModel item1; 
    private readonly PivotItem2ViewModel item2; 
  
    public PivotViewModel(PivotItem1ViewModel item1, PivotItem2ViewModel item2) 
    { 
        this.item1 = item1; 
        this.item2 = item2; 
    } 
  
    protected override void OnInitialize() 
    { 
        base.OnInitialize(); 
  
        Items.Add(item1); 
        Items.Add(item2); 
  
        ActivateItem(item1); 
    } 
}&lt;/pre&gt;

&lt;p&gt;Innanzitutto, il ViewModel deve ereditare dalla classe &lt;strong&gt;Conductor&amp;lt;T&amp;gt;.Collection.OneActive&lt;/strong&gt;: in questo modo andiamo a definire che il ViewModel conterrà una collezione di viste (useremo come valore di T l’interfaccia &lt;strong&gt;IScreen&lt;/strong&gt;, che viene implementata dalla classe &lt;strong&gt;Screen&lt;/strong&gt; da cui ereditano tutti i ViewModel) e, utilizzando la proprietà &lt;strong&gt;OneActive&lt;/strong&gt;, definiamo che potrà essere solamente mostrata una vista alla volta. E’ l’unica opzione che può essere utilizzata per gestire il controllo Pivot: ne sono disponibili altre, ma sono semplicemente un retaggio del fatto che Caliburn Micro supporta anche tecnologie come WPF e Silverlight, dove possono essere attive più viste allo stesso tempo. &lt;/p&gt;

&lt;p&gt;Potete notare come, nel costruttore, abbiamo aggiunto due parametri, il cui tipo è &lt;strong&gt;PivotItem1ViewModel&lt;/strong&gt; e &lt;strong&gt;PivotItem2ViewModel: &lt;/strong&gt;sono i ViewModel collegati alle viste che andremo a mostrare all’interno del controllo Pivot. &lt;/p&gt;

&lt;p&gt;Dopodichè implementiamo il metodo &lt;strong&gt;OnInitialize(), &lt;/strong&gt;che viene chiamato quando la pagina viene inizializzata per la prima volta: dato che il ViewModel eredita dalla classe &lt;strong&gt;Conductor&amp;lt;T&amp;gt; &lt;/strong&gt;abbiamo accesso alla proprietà &lt;strong&gt;Items &lt;/strong&gt;e al metodo &lt;strong&gt;ActivateItem()&lt;/strong&gt;. La prima è la collezione (il cui tipo T coincide con il tipo con cui è stata definita la classe &lt;strong&gt;Conductor&amp;lt;T&amp;gt;&lt;/strong&gt;) che contiene le viste che compongono il controllo Pivot e la utilizziamo semplicemente per aggiungere tutti i ViewModel che abbiamo inizializzato nel costruttore. Dopodichè chiamiamo il metodo &lt;strong&gt;ActivateItem()&lt;/strong&gt;, che permette di impostare il focus del Pivot su una specifica vista: in questo caso, impostiamo il primo ViewModel (ovvero la prima vista), ma potremmo aver specificato qualsiasi altra vista. Ad esempio, potremmo aver ricevuto l’informazione sulla pagina da mostrare da un parametro in query string, in seguito alla navigazione da un’altra pagina o da una tile secondaria. &lt;/p&gt;

&lt;p&gt;Ora possiamo creare le vere e proprie pagine che andranno a comporre il nostro Pivot: aggiungete due nuove pagine nella cartella &lt;strong&gt;View&lt;/strong&gt; del vostro progetto (chiamati &lt;strong&gt;PivotItem1View&lt;/strong&gt; e &lt;strong&gt;PivotItem2View&lt;/strong&gt;) e i relativi ViewModel nella cartella &lt;strong&gt;ViewModels&lt;/strong&gt; (chiamati &lt;strong&gt;PivotItem1ViewModel&lt;/strong&gt; e &lt;strong&gt;PivotItem2ViewModel&lt;/strong&gt;).&amp;#160; Sono delle semplici pagine, niente di speciale da segnalare a riguardo. Possono anche essere degli UserControl, è indifferente: nel caso optiate per creare delle vere e proprie pagine, ricordatevi di rimuovere gli elementi nello XAML non necessari (dato che sono già contenute all’interno di una pagina, non è necessario mantenere l’header incluso nel template standard con il nome dell’applicazione e il titolo della pagina). &lt;/p&gt;

&lt;p&gt;Ecco un esempio di definizione dello XAML:&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;&amp;lt;phone:PhoneApplicationPage
    x:Class=&amp;quot;CaliburnMicro.Views.PivotItem1View&amp;quot;
    xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;
    xmlns:x=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;
    xmlns:phone=&amp;quot;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone&amp;quot;
    xmlns:shell=&amp;quot;clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone&amp;quot;
    xmlns:d=&amp;quot;http://schemas.microsoft.com/expression/blend/2008&amp;quot;
    xmlns:mc=&amp;quot;http://schemas.openxmlformats.org/markup-compatibility/2006&amp;quot;
    FontFamily=&amp;quot;{StaticResource PhoneFontFamilyNormal}&amp;quot;
    FontSize=&amp;quot;{StaticResource PhoneFontSizeNormal}&amp;quot;
    Foreground=&amp;quot;{StaticResource PhoneForegroundBrush}&amp;quot;
    SupportedOrientations=&amp;quot;Portrait&amp;quot; Orientation=&amp;quot;Portrait&amp;quot;
    mc:Ignorable=&amp;quot;d&amp;quot;
    shell:SystemTray.IsVisible=&amp;quot;True&amp;quot;&amp;gt; 
  
    &amp;lt;!--LayoutRoot is the root grid where all page content is placed--&amp;gt;
    &amp;lt;Grid x:Name=&amp;quot;LayoutRoot&amp;quot; Background=&amp;quot;Transparent&amp;quot;&amp;gt; 
        &amp;lt;Grid.RowDefinitions&amp;gt; 
            &amp;lt;RowDefinition Height=&amp;quot;Auto&amp;quot;/&amp;gt; 
            &amp;lt;RowDefinition Height=&amp;quot;*&amp;quot;/&amp;gt; 
        &amp;lt;/Grid.RowDefinitions&amp;gt; 
  
      &amp;lt;!--ContentPanel - place additional content here--&amp;gt;
        &amp;lt;Grid x:Name=&amp;quot;ContentPanel&amp;quot; Grid.Row=&amp;quot;1&amp;quot; Margin=&amp;quot;12,0,12,0&amp;quot;&amp;gt; 
  
        &amp;lt;/Grid&amp;gt; 
    &amp;lt;/Grid&amp;gt; 
  
&amp;lt;/phone:PhoneApplicationPage&amp;gt;&lt;/pre&gt;

&lt;p&gt;Ed ecco il relativo ViewModel:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class PivotItem1ViewModel: Screen 
{ 
    public PivotItem1ViewModel() 
    { 
        DisplayName = &amp;quot;First pivot&amp;quot;; 
    } 
}&lt;/pre&gt;

&lt;p&gt;Niente di speciale neanche qui: è il classico ViewModel di un’applicazione che fa uso di Caliburn Micro e che eredita dalla classe &lt;strong&gt;Screen&lt;/strong&gt;. Potete notare solamente che, nel costruttore, diamo un valore alla proprietà &lt;strong&gt;DisplayName, &lt;/strong&gt;che fa parte della classe base &lt;strong&gt;Screen: &lt;/strong&gt;è il titolo della vista che sarà utilizzata come header del Pivot. &lt;/p&gt;

&lt;p&gt;Ora vediamo lo XAML della pagina &lt;strong&gt;PivotView&lt;/strong&gt;, ovvero quella che funge da Conductor:&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;&amp;lt;Grid x:Name=&amp;quot;LayoutRoot&amp;quot; Background=&amp;quot;Transparent&amp;quot;&amp;gt; 
    &amp;lt;!--Pivot Control--&amp;gt;
    &amp;lt;phone:Pivot Title=&amp;quot;MY APPLICATION&amp;quot; x:Name=&amp;quot;Items&amp;quot; SelectedItem=&amp;quot;{Binding ActiveItem, Mode=TwoWay}&amp;quot;&amp;gt; 
        &amp;lt;phone:Pivot.HeaderTemplate&amp;gt; 
            &amp;lt;DataTemplate&amp;gt; 
                &amp;lt;TextBlock Text=&amp;quot;{Binding DisplayName}&amp;quot; /&amp;gt; 
            &amp;lt;/DataTemplate&amp;gt; 
        &amp;lt;/phone:Pivot.HeaderTemplate&amp;gt; 
    &amp;lt;/phone:Pivot&amp;gt; 
&amp;lt;/Grid&amp;gt;&lt;/pre&gt;

&lt;p&gt;Potete notare alcune delle “magie” di Caliburn in azione: la prima è che abbiamo dato al controllo Pivot il nome &lt;strong&gt;Items;&lt;/strong&gt; in questo modo la proprietà &lt;strong&gt;ItemsSource&lt;/strong&gt; viene in automatico collegata alla proprietà &lt;strong&gt;Items&lt;/strong&gt; definita nel ViewModel, che contiene la collezione di viste da mostrare. La seconda “magia” è che la proprietà &lt;strong&gt;SelectedItem&lt;/strong&gt; è collegata (in modalità two way) ad una proprità chiamata &lt;strong&gt;ActiveItem&lt;/strong&gt;, la quale è definita nella classe base &lt;strong&gt;Conductor&amp;lt;T&amp;gt; &lt;/strong&gt;da cui eredita il ViewModel e viene utilizzata per mantenere un riferimento alla vista correntemente selezionata. Grazie a questo binding ci assicuriamo che il metodo &lt;strong&gt;ActivateItem()&lt;/strong&gt; che abbiamo definito nella classe &lt;strong&gt;PivotViewModel &lt;/strong&gt;funzioni correttamente. &lt;/p&gt;

&lt;p&gt;L’ultima cosa da sottolineare è che definiamo un template per la proprietà &lt;strong&gt;HeaderTemplate&lt;/strong&gt; del controllo: semplicemente, utilizziamo una &lt;strong&gt;TextBlock&lt;/strong&gt;, in binding con la proprietà &lt;strong&gt;DisplayName&lt;/strong&gt;. In questo modo, il titolo della pagina viene preso automaticamente dalla proprietà &lt;strong&gt;DisplayName&lt;/strong&gt; che abbiamo definito nel ViewModel.&lt;/p&gt;

&lt;p&gt;Siamo pronti per testare l’applicazione? Non ancora! Prima, dobbiamo registrare, nel metodo &lt;strong&gt;Configure() &lt;/strong&gt;del bootstrapper, tutti i ViewModel che abbiamo appena definito (quello della pagina che funge da conductor più tutti i singoli ViewModel).&lt;/p&gt;

&lt;p&gt;Ora possiamo finalmente provare l’applicazione: se abbiamo fatto tutto correttamente, vedrete il controllo Pivot con due pagine, uno per ognuno delle View e dei ViewModel che avete definito. Ora potete giocare con il progetto: potete provare ad aggiungere alcuni dati in una pagina, oppure altre viste al contollo Pivot.&lt;/p&gt;

&lt;p&gt;Nel prossimo post vedremo come sfruttare quanto abbiamo appreso per supportare il lazy loading. Nel frattempo, potete fare esperimenti con il progetto di esempio.&lt;/p&gt;

&lt;div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:01035a83-9987-452f-95d0-3c0a4245609a" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;p&gt; &lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/CaliburnMicro_Pivot.zip" target="_blank"&gt;Scarica il progetto di esempio&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-la-teoria"&gt;Caliburn Micro e Windows Phone – La teoria&lt;/a&gt; (3/18/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-il-primo-progetto"&gt;Caliburn Micro e Windows Phone – Il primo progetto&lt;/a&gt; (3/21/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-collezioni-e-navigazione"&gt;Caliburn Micro e Windows Phone – Collezioni e navigazione&lt;/a&gt; (3/29/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-tombstoning"&gt;Caliburn Micro e Windows Phone – Tombstoning&lt;/a&gt; (4/3/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-messaggi"&gt;Caliburn Micro e Windows Phone – Messaggi&lt;/a&gt; (4/12/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-utilizzare-i-launcher-e-i-chooser"&gt;Caliburn Micro e Windows Phone – Utilizzare i launcher e i chooser&lt;/a&gt; (4/24/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/caliburn-micro-e-windows-phone-il-controllo-pivot"&gt;&lt;strong&gt;More related document (288)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/qmatteoq/~4/kx_Wdp0tKy8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/qmatteoq/~3/kx_Wdp0tKy8/caliburn-micro-e-windows-phone-il-controllo-pivot</link><author>qmatteoq</author><comments>http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-il-controllo-pivot#feedback</comments><guid isPermaLink="false">http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-il-controllo-pivot</guid><pubDate>Wed, 15 May 2013 10:00:00 GMT</pubDate><category>Windows Phone</category><category>Caliburn</category><category>MVVM</category><feedburner:origLink>http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-il-controllo-pivot</feedburner:origLink></item><item><title>Sviluppare applicazioni per Windows Phone 8 ora in vendita!</title><description>&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/WP_20130509_002_2.jpg"&gt;&lt;img title="WP_20130509_002" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: left; padding-top: 0px; padding-left: 0px; margin: 0px 10px 0px 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="WP_20130509_002" align="left" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/WP_20130509_002_thumb.jpg" width="178" height="317" /&gt;&lt;/a&gt;   &lt;p&gt;&lt;strong&gt;Aggiornamento&lt;/strong&gt;: il libro è ora disponibile anche in versione digitale, sempre sul &lt;a href="http://www.fag.it/libro_sviluppare_applicazioni_per_windows_phone_8_39009.aspx" target="_blank"&gt;sito della casa editrice&lt;/a&gt;, al prezzo di 29,90 € (contrariamente ai 34,90 € precedentemente dichiarati). Prossimamente in vendita anche nei principali store online.&lt;/p&gt;  &lt;p&gt;In tanti mi avete contattato per chiedere informazioni sulla disponibilità via mail o tramite social network e, finalmente, posso segnalarvi che il mio libro “&lt;strong&gt;Sviluppare applicazioni per Windows Phone 8&lt;/strong&gt;” è ora in vendita!&lt;/p&gt;  &lt;p&gt;Al momento, il libro è acquistabile direttamente &lt;a href="http://www.fag.it/libro_sviluppare_applicazioni_per_windows_phone_8_39009.aspx" target="_blank"&gt;dal sito della casa editrice&lt;/a&gt; al prezzo di 49,90 €. A partire da settimana prossima sarà disponibile anche nelle principali librerie della Lombardia mentre, entro due settimane, sarà distribuito in tutta Italia. Per fine Maggio, infine, sarà disponibile anche la versione e-book, al prezzo di 34,90 €.&lt;/p&gt;  &lt;p&gt;Il volume, interamente a colori, è composto da 656 pagine e contiene un’introduzione a cura di Marco Argenti, Senior Vice President della Developer Division di Nokia.&lt;/p&gt;  &lt;p&gt;Per l’occasione, ho creato anche &lt;a href="http://www.qmatteoq.com/libri" target="_blank"&gt;una sezione dedicata&lt;/a&gt; su questo blog: oltre alla descrizione del libro, trovate il download degli esempi di codice e, a breve, una pagina in cui segnalerò eventuali aggiornamenti sugli argomenti trattati emersi dopo la pubblicazione.&lt;/p&gt;  &lt;p&gt;Se siete tra le persone che lo hanno acquistato o che hanno intenzione di acquistarlo, vi ricordo che, per qualsiasi feedback, segnalazione di refuso o richiesta di chiarimento, potete contattarmi usando l’apposito &lt;a href="http://www.qmatteoq.com/contacts" target="_blank"&gt;form di contatto&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/lo-speciale-di-aspitalia-sulle-novita-per-gli-sviluppatori-di-windows-phone-8"&gt;Lo speciale di ASPItalia sulle novità per gli sviluppatori di Windows Phone 8&lt;/a&gt; (10/31/2012)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/windows-phone-8-e-finalmente-realta"&gt;Windows Phone 8 è finalmente realtà!&lt;/a&gt; (10/30/2012)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/il-mio-primo-articolo-cartaceo-con-qualche-rettifica"&gt;Il mio primo articolo cartaceo… con qualche rettifica!&lt;/a&gt; (9/5/2012)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/il-libro-di-aspitalia-sullo-sviluppo-di-applicazioni-windows-phone"&gt;Il libro di ASPItalia sullo sviluppo di applicazioni Windows Phone&lt;/a&gt; (6/23/2011)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/windows-phone-developers-tools-beta"&gt;Windows Phone Developers Tools Beta&lt;/a&gt; (7/13/2010)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/supportare-i-dispositivi-windows-phone-8-da-unapplicazione-windows-phone-7.x"&gt;Supportare i dispositivi Windows Phone 8 da un’applicazione Windows Phone 7.x&lt;/a&gt; (12/17/2012)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/sviluppare-applicazioni-per-windows-phone-8-ora-in-vendita"&gt;&lt;strong&gt;More related document (288)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/qmatteoq/~4/-OOwmedrx44" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/qmatteoq/~3/-OOwmedrx44/sviluppare-applicazioni-per-windows-phone-8-ora-in-vendita</link><author>qmatteoq</author><comments>http://www.qmatteoq.com/blog/post/sviluppare-applicazioni-per-windows-phone-8-ora-in-vendita#feedback</comments><guid isPermaLink="false">http://www.qmatteoq.com/blog/post/sviluppare-applicazioni-per-windows-phone-8-ora-in-vendita</guid><pubDate>Fri, 10 May 2013 12:00:00 GMT</pubDate><category>Windows Phone</category><feedburner:origLink>http://www.qmatteoq.com/blog/post/sviluppare-applicazioni-per-windows-phone-8-ora-in-vendita</feedburner:origLink></item><item><title>Caliburn Micro e Windows Phone – Gestire l’Application Bar</title><description>&lt;p&gt;L’Application Bar è la croce e la delizia di tutti gli sviluppatori Windows Phone che utilizzano il pattern MVVM: tale controllo, infatti, vive “in un mondo a sè” e non fa parte del contesto della pagina. Per questo motivo, non eredita dalla classe base &lt;strong&gt;FrameworkElement&lt;/strong&gt; (dalla quale derivano tutti gli altri controlli) e, di conseguenza, non supporta il binding. Non è possibile utilizzare i command, per collegare delle azioni agli eventi scatenati dalla pressione dei pulsanti, e non è possibile collegare delle proprietà del ViewModel alle proprietà &lt;strong&gt;Text&lt;/strong&gt; e &lt;strong&gt;IconUri&lt;/strong&gt; per gestire dinamicamente testi e icone.&lt;/p&gt;  &lt;p&gt;Dato che, spesso e volentieri, questi limiti portano lo sviluppatore a “rompere” il pattern MVVM e a gestire l’Application Bar direttamente dal code behind, alcuni sviluppatori hanno realizzato delle implementazioni alternative della Application Bar, in grado di supportare il binding. Sono diverse le soluzioni disponibili: due delle migliori che ho trovato sono il &lt;a href="http://cimbalino.org/" target="_blank"&gt;Cimbalino Toolkit&lt;/a&gt; di Pedro Lamas e &lt;a href="https://github.com/kamranayub/CaliburnBindableAppBar" target="_blank"&gt;Caliburn Bindable App Bar&lt;/a&gt; by Kamran Ayub. Il primo toolkit utilizza un approccio basato sui behavior, che vengono applicati direttamente alla Application Bar nativa. Non lo approfondiremo nel corso di questo articolo, non perchè non sia una soluzione valida ma perchè non si sposa molto bene con Caliburn Micro: è perfetto, invece, se utilizzate MVVM Light come toolkit per le vostre applicazioni.&lt;/p&gt;  &lt;p&gt;Tratteremo, invece, la seconda implementazione, che nasce proprio per supportare Caliburn e le sue convenzioni e che rimpiazza comletamente l’Application Bar standard.&lt;/p&gt;  &lt;p&gt;Vediamo come usarla!&lt;/p&gt;  &lt;h3&gt;Aggiungere l’Application Bar al proprio progetto&lt;/h3&gt;  &lt;p&gt;La Caliburn Bindable App Bar è disponibile come pacchetto NuGet: semplicemente fate click con il tasto destro sul vostro progetto, scegliete &lt;strong&gt;Manage NuGet&lt;/strong&gt; &lt;strong&gt;packages &lt;/strong&gt;e cercate il pacchetto chiamato &lt;strong&gt;Caliburn.Micro.BindableAppBar. &lt;/strong&gt;Una volta installato, dovete aggiungere il namespace seguente nello XAML per poterlo utilizzare:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;xmlns:bab=”clr-namespace:Caliburn.Micro.BindableAppBar;assembly=Caliburn.Micro.BindableAppBar”&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;A questo punto potete aggiungere il controllo vero e proprio, che si chiama &lt;strong&gt;BindableAppBar&lt;/strong&gt;. Fate attenzione però! Contrariamente alla Application Bar standard (che viene posizionata &lt;strong&gt;al di fuori della Grid principale&lt;/strong&gt; dato che non fa parte della pagina), questo controllo deve essere inserito, invece, &lt;strong&gt;all’interno della Grid principale&lt;/strong&gt; (mi riferisco al controllo Grid che, nel template standard, è chiamato &lt;strong&gt;LayoutRoot&lt;/strong&gt;). Ecco un esempio:&lt;/p&gt;  &lt;pre class="brush: xml;"&gt;&amp;lt;Grid x:Name=&amp;quot;LayoutRoot&amp;quot; Background=&amp;quot;Transparent&amp;quot;&amp;gt; 
    &amp;lt;Grid.RowDefinitions&amp;gt; 
        &amp;lt;RowDefinition Height=&amp;quot;Auto&amp;quot;/&amp;gt; 
        &amp;lt;RowDefinition Height=&amp;quot;*&amp;quot;/&amp;gt; 
    &amp;lt;/Grid.RowDefinitions&amp;gt; 
  
    &amp;lt;!--TitlePanel contains the name of the application and page title--&amp;gt;
    &amp;lt;StackPanel x:Name=&amp;quot;TitlePanel&amp;quot; Grid.Row=&amp;quot;0&amp;quot; Margin=&amp;quot;12,17,0,28&amp;quot;&amp;gt; 
        &amp;lt;TextBlock Text=&amp;quot;Caliburn Micro&amp;quot; Style=&amp;quot;{StaticResource PhoneTextNormalStyle}&amp;quot; Margin=&amp;quot;12,0&amp;quot;/&amp;gt; 
        &amp;lt;TextBlock Text=&amp;quot;Sample&amp;quot; Margin=&amp;quot;9,-7,0,0&amp;quot; Style=&amp;quot;{StaticResource PhoneTextTitle1Style}&amp;quot;/&amp;gt; 
    &amp;lt;/StackPanel&amp;gt; 
  
    &amp;lt;!--ContentPanel - place additional content here--&amp;gt;
    &amp;lt;Grid x:Name=&amp;quot;ContentPanel&amp;quot; Grid.Row=&amp;quot;1&amp;quot; Margin=&amp;quot;12,0,12,0&amp;quot;&amp;gt; 
  
    &amp;lt;/Grid&amp;gt; 
  
    &amp;lt;bab:BindableAppBar x:Name=&amp;quot;AppBar&amp;quot;&amp;gt; 
        &amp;lt;bab:BindableAppBarButton x:Name=&amp;quot;AddItem&amp;quot;
                                  Text=&amp;quot;{Binding AddItemText}&amp;quot;
                                  IconUri=&amp;quot;{Binding Icon}&amp;quot; 
                                  Visibility=&amp;quot;{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}&amp;quot;
                                  /&amp;gt; 
  
        &amp;lt;bab:BindableAppBarMenuItem x:Name=&amp;quot;RemoveItem&amp;quot;
                                  Text=&amp;quot;Remove&amp;quot;
                                  /&amp;gt; 
    &amp;lt;/bab:BindableAppBar&amp;gt; 
&amp;lt;/Grid&amp;gt;&lt;/pre&gt;

&lt;p&gt;Il controllo è molto semplice da utilizzare. All’interno del tag &lt;strong&gt;BindableAppBar&lt;/strong&gt; potete aggiungere due tipologie di controlli: &lt;strong&gt;BindableAppBarButton,&lt;/strong&gt; che è il pulsante con l’icona (ne potete aggiungere fino a 4) e &lt;strong&gt;BindableAppBarMenuItem&lt;/strong&gt;, che invece rappresentano gli elementi testuali che vengono mostrati sotto le icone.&lt;/p&gt;

&lt;p&gt;Entrambi condividono le stesse proprietà, dato che rappresentano un pulsante che può essere premuto per eseguire un’azione: l’unica differenza è che il controllo &lt;strong&gt;BindableAppBarButton &lt;/strong&gt;ha una proprietà &lt;strong&gt;IconUri&lt;/strong&gt;, che contiene il percorso dell’immagine che viene utilizzata come icona.&lt;/p&gt;

&lt;p&gt;Entrambi i controlli condidono la stessa convenzione di Caliburn che viene utilizzata per le azioni: il valore della proprietà &lt;strong&gt;x:Name&lt;/strong&gt; del controllo coincide con il nome del metodo, dichiarato nel ViewModel, che viene eseguito quando il pulsante viene premuto. In più, tutte le altre proprietà supportano il binding, inclusa &lt;strong&gt;Visibility, &lt;/strong&gt;che permette di mostrare o nascondere un pulsante.&lt;/p&gt;

&lt;p&gt;Prima di iniziare ad interagire con la Application Bar dal ViewModel c’è un’ulteriore passaggio da fare: aggiungere una convenzione personalizzata. Caliburn Micro, infatti, da la possibilità dagli sviluppatori di definire le proprie convenzioni, che vengono aggiunte a quelle già esistenti. Tali convenzioni vengono aggiunte nel &lt;strong&gt;bootstrapper&lt;/strong&gt;, all’interno del metodo &lt;strong&gt;AddCustomConventions()&lt;/strong&gt; che viene chiamato quando il boostrapper viene registrato.&lt;/p&gt;

&lt;p&gt;Ecco il codice da inserire:&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;static void AddCustomConventions()
{
    ConventionManager.AddElementConvention&amp;lt;BindableAppBarButton&amp;gt;(
    Control.IsEnabledProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Click&amp;quot;);
    ConventionManager.AddElementConvention&amp;lt;BindableAppBarMenuItem&amp;gt;(
    Control.IsEnabledProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Click&amp;quot;);
}&lt;/pre&gt;

&lt;p&gt;Tramite questo codice stiamo praticamente aggiungendo una nuova convenzione per gestire l’evento &lt;strong&gt;Click&lt;/strong&gt; del pulsante direttamente dal ViewModel.&lt;/p&gt;

&lt;p&gt;Ora è il momento di passare al codice del ViewModel, per gestire le varie proprietà della &lt;strong&gt;BindableAppBar:&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class MainPageViewModel: Screen
{
 
    private string addItemText;
 
    public string AddItemText
    {
        get { return addItemText; }
        set
        {
            addItemText = value;
            NotifyOfPropertyChange(() =&amp;gt; AddItemText);
        }
    }
 
    private Uri icon;
 
    public Uri Icon
    {
        get { return icon; }
        set
        {
            icon = value;
            NotifyOfPropertyChange(() =&amp;gt; Icon);
        }
    }
 
    private bool isVisible;
 
    public bool IsVisible
    {
        get { return isVisible; }
        set
        {
            isVisible = value;
            NotifyOfPropertyChange(() =&amp;gt; IsVisible);
        }
    }
 
    public MainPageViewModel()
    {
        AddItemText = &amp;quot;Add&amp;quot;;
        Icon = new Uri(&amp;quot;/Assets/AppBar/appbar.add.rest.png&amp;quot;, UriKind.Relative);
        IsVisible = false;  
    }
 
    public void AddItem()
    {
        MessageBox.Show(&amp;quot;Item added&amp;quot;);
    }
 
    public void RemoveItem()
    {
        MessageBox.Show(&amp;quot;Item removed&amp;quot;);
    }
}&lt;/pre&gt;

&lt;p&gt;Se avete seguito gli altri post dedicati a Caliburn Micro la struttura di questo ViewModel dovrebbe esservi famigliare: abbiamo definito alcune proprietà e metodi, che sono collegati alla &lt;strong&gt;BindableAppBar&lt;/strong&gt; tramite delle convenzioni. Quando il ViewModel viene inizializzato, definiamo il testo, l’icona e la visibilità di uno dei pulsanti nell’Application Bar. Si tratta di un approccio molto utile quando lo stato visivo dei pulsanti è dinamico e non “fisso” per tutto il ciclo di vita dell’applicazione. Prendiamo come esempio un’applicazione per leggere le ultime notizie: una delle funzionalità proposte potrebbe essere la possibilità di salvare la notizia in una lista di preferiti, tramite un pulsante ad hoc nella Application Bar. In questo caso, l’aspetto del pulsante deve cambiare in baso allo stato della notizia: se questa è già stata salvata tra i preferiti, probabilmente il testo del pulsante sarà “Rimuovi” e l’icona mostrerà il segno meno; se invece la news non fa parte dei preferiti, il pulsante avrà l’etichetta “Aggiungi” e l’icona mostrerà il segno più.&lt;/p&gt;

&lt;p&gt;Con il ViewModel che abbiamo appena visto sarebbe semplice cambiare l’aspetto visivo del pulsante in base allo stato della notizia: sarebbe sufficiente agire sulle proprietà &lt;strong&gt;AddItemText&lt;/strong&gt; e &lt;strong&gt;Icon&lt;/strong&gt; per cambiare testo e icona del pulsante.&lt;/p&gt;

&lt;p&gt;Anche la proprietà &lt;strong&gt;Visibility&lt;/strong&gt; può essere comoda in molte situazioni: sempre riprendendo l’esempio precedente, ipotizziamo che l’applicazione consenta anche, sempre tramite un pulsante nella Application Bar, di creare una tile secondaria nella schermata Start che punti alla notizia. In tal caso, solo nel momento in cui l’applicazione viene aperta da una tile secondaria, vogliamo aggiungere un pulsante “Home” nella Application Bar per portare l’utente alla pagina principale dell’applicazione, dato che lo stack delle pagine è vuoto e quindi la pressione del pulsante Back la chiuderebbe direttamente. Nel nostro caso, invece, sarebbe sufficiente definire una proprietà nel ViewModel che rappresenti questa informazione e collegarla alla proprietà &lt;strong&gt;Visibility&lt;/strong&gt; del pulsante, così da mostrarlo solo in caso di effettivo bisogno.&lt;/p&gt;

&lt;div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:f0cd0a28-1ed4-4847-8c21-bfdb4e6afc61" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;p&gt; &lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/CaliburnMicro_AppBar3.zip" target="_blank"&gt;Scarica il progetto di esempio&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-la-teoria"&gt;Caliburn Micro e Windows Phone – La teoria&lt;/a&gt; (3/18/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-il-primo-progetto"&gt;Caliburn Micro e Windows Phone – Il primo progetto&lt;/a&gt; (3/21/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-collezioni-e-navigazione"&gt;Caliburn Micro e Windows Phone – Collezioni e navigazione&lt;/a&gt; (3/29/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-tombstoning"&gt;Caliburn Micro e Windows Phone – Tombstoning&lt;/a&gt; (4/3/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-messaggi"&gt;Caliburn Micro e Windows Phone – Messaggi&lt;/a&gt; (4/12/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-utilizzare-i-launcher-e-i-chooser"&gt;Caliburn Micro e Windows Phone – Utilizzare i launcher e i chooser&lt;/a&gt; (4/24/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/caliburn-micro-e-windows-phone-gestire-lapplication-bar"&gt;&lt;strong&gt;More related document (288)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/qmatteoq/~4/Ng3JlleTVkQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/qmatteoq/~3/Ng3JlleTVkQ/caliburn-micro-e-windows-phone-gestire-lapplication-bar</link><author>qmatteoq</author><comments>http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-gestire-lapplication-bar#feedback</comments><guid isPermaLink="false">http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-gestire-lapplication-bar</guid><pubDate>Thu, 02 May 2013 10:00:00 GMT</pubDate><category>Windows Phone</category><category>Caliburn</category><category>MVVM</category><feedburner:origLink>http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-gestire-lapplication-bar</feedburner:origLink></item><item><title>Caliburn Micro e Windows Phone – Utilizzare i propri servizi</title><description>&lt;p&gt;In questa serie di post sull’utilizzo di Caliburn Micro in Windows Phone abbiamo imparato che il toolkit include molti helper e servizi, che vengono automaticamente registrati nel momento in cui, nel boostrapper, chiamiamo il metodo &lt;strong&gt;RegisterPhoneServices()&lt;/strong&gt; della classe &lt;strong&gt;PhoneContainer&lt;/strong&gt;. Abbiamo visto molti esempi di questi servizi, come il &lt;strong&gt;NavigationService&lt;/strong&gt; e l’&lt;strong&gt;EventAggregator&lt;/strong&gt;. Siamo stati in grado di ottenere un riferimento a tali classi semplicemente aggiungendo un parametro nel costruttore del ViewModel: Caliburn Micro, tramite il suo sistema integrato di dependency injection, è in grado di risolvere da solo le dipendenze.&lt;/p&gt;  &lt;p&gt;Ma come comportarsi nel caso in cui abbiamo la necessità di registrare le nostre classi e i nostri servizi? Ipotizziamo che stiate sviluppando un’applicazione per leggere un feed RSS, che è in grado di fare il parsing dell’XML e di mostrare le notizie in una lista. In questo caso, potreste avere un servizio (ovvero una classe separata dal ViewModel) che si occupa di scaricare l’RSS e di convertirlo da una stringa piatta (l’XML) in una serie di oggetti che possiamo manipolare. Un approccio potrebbe essere quello di creare un’istanza del servizio direttamente nel ViewModel, come nell’esempio:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;public MainPageViewModel() 
{
    IFeedService feedService = new FeedService();
     // do something with the feed service
}&lt;/pre&gt;

&lt;p&gt;Questo approccio, però, ha uno svantaggio. Ipotizziamo che vogliate fare dei test con dei dati fittizzi e, di conseguenza, vogliata utilizzare, al posto della classe &lt;strong&gt;FeedService&lt;/strong&gt;, un’altra classe chiamata &lt;strong&gt;FakeFeedService&lt;/strong&gt; che, invece di prelevare i dati dal feed RSS reale, li prenda da un file XML locale. In uno scenario reale, la vostra classe &lt;strong&gt;FeedService&lt;/strong&gt; probabilmente sarebbe utilizzata da diversi ViewModel: di conseguenza, dovreste andare nel costruttore di ogni ViewModel e cambiare l’inizializzazione della classe nel modo seguente:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public MainPageViewModel() 
{
    IFeedService feedService = new FakeFeedService();
     // do something with the fake feed service
}&lt;/pre&gt;

&lt;p&gt;Un approccio migliore sarebbe di usare lo stesso adottato da Caliburn Micro: i servizi vengono registrati all’avvio, in questo modo è sufficiente aggiungere un parametro al costruttore del ViewModel affinchè il servizio venga automaticamente risolto e “iniettato” nel ViewModel. In questo modo, se dovete cambiare l’implementazione concreta del vostro servizio, dovrete farlo solo nel bootstrapper, quando il servizio viene registrato: automaticamente tutti i ViewModel inizieranno ad utilizzare la nuova classe.&lt;/p&gt;

&lt;p&gt;Di conseguenza, ecco come cambia la definizione del ViewModel con questo nuovo approccio:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public MainPageViewModel(IFeedService feedService)
{
    //do something with the feed service
}&lt;/pre&gt;

&lt;h3&gt;Registrare i propri servizi&lt;/h3&gt;

&lt;p&gt;Vediamo ora come implementare un vostro servizio e registrarlo, così da poterlo utilizzare con l’approccio sopra descritto.&lt;/p&gt;

&lt;p&gt;Innanzitutto dovete creare un’interfaccia per il servizio, che descriva i metodi che la classe deve esporre. Si tratta di un passaggio molto importante, in quanto consente di cambiare, in maniera semplice, l’implementazione concreta di un servizio semplicemente registrandolo nel bootstrapper. Riprendendo l’esempio di prima, &lt;strong&gt;FeedService&lt;/strong&gt; e &lt;strong&gt;FakeFeedService&lt;/strong&gt; sono due implementazioni concrete differenti, ma si rifanno alla stessa interfaccia, dato che espongono gli stessi metodi: quelli per elaborare un feed RSS. Andremo perciò a creare l’interfaccia &lt;strong&gt;IFeedService&lt;/strong&gt; e a registrarla nel costruttore del ViewModel.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public interface IFeedService
{
    Task&amp;lt;List&amp;lt;FeedItem&amp;gt;&amp;gt; GetNews(string url);
}&lt;/pre&gt;

&lt;p&gt;L’interfaccia descrive solamente un metodo, che utilizzeremo per recuperare l’elenco delle notizie: accetta in ingresso l’url del feed RSS e restituisce una collezione di oggetti di tipo &lt;strong&gt;FeedItem&lt;/strong&gt;, che è una semplice classe che descrive una singola notizia:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class FeedItem
{
    public string Title { get; set; }
    public string Description { get; set; }
    public Uri Url { get; set; }
}&lt;/pre&gt;

&lt;p&gt;Infine, ecco l’implementazione concreta della classe &lt;strong&gt;FeedService&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class FeedService: IFeedService
{
    public async Task&amp;lt;List&amp;lt;FeedItem&amp;gt;&amp;gt; GetNews(string url)
    {
        WebClient client = new WebClient();
        string content = await client.DownloadStringTaskAsync(url);
 
        XDocument doc = XDocument.Parse(content);
        var result = doc.Descendants(&amp;quot;rss&amp;quot;).Descendants(&amp;quot;channel&amp;quot;).Elements(&amp;quot;item&amp;quot;).Select(x =&amp;gt; new FeedItem
        {
            Title = x.Element(&amp;quot;title&amp;quot;).Value,
            Description = x.Element(&amp;quot;description&amp;quot;).Value
        }).ToList();
 
        return result;
    }
}&lt;/pre&gt;

&lt;p&gt;Questa classe contiene l’implementazione concreta dell’interfaccia &lt;strong&gt;IFeedService&lt;/strong&gt; e, di conseguenza, del metodo &lt;strong&gt;GetNews(). &lt;/strong&gt;All’interno di tale metodo andiamo ad utilizzare la classe &lt;strong&gt;WebClient&lt;/strong&gt; per scaricare il feed: nello specifico, per comodità ho installato l’Async Pack di cui vi ho parlato &lt;a href="http://www.qmatteoq.com/blog/post/async-targeting-pack-perche-e-utile-nei-progetti-windows-phone-8" target="_blank"&gt;in un post precedente&lt;/a&gt;, grazie al quale possiamo utilizzare il metodo asincrono &lt;strong&gt;DownloadStringTaskAsync(). &lt;/strong&gt;Una volta ottenuto l’XML del feed RSS, utilizziamo &lt;strong&gt;LINQ TO XML&lt;/strong&gt; per attraversare i nodi che lo compongono e creare una serie di oggetti di tipo &lt;strong&gt;FeedItem&lt;/strong&gt; con le principali informazioni (titolo e descrizione).&lt;/p&gt;

&lt;p&gt;Ora è tempo di registrare il nostro servizio, così da utilizzarlo nel ViewModel. La registrazione viene fatta nel bootrapper e dovrebbe esservi famigliare, dato che è lo stesso approccio utilizzato per la registrazione dei ViewModel: lo facciamo nel metodo &lt;strong&gt;Configure()&lt;/strong&gt; della classe boostrapper.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;protected override void Configure()
{
    container = new PhoneContainer(RootFrame);
 
    container.RegisterPhoneServices();
    container.PerRequest&amp;lt;MainPageViewModel&amp;gt;();
    container.PerRequest&amp;lt;IFeedService, FeedService&amp;gt;();
    AddCustomConventions();
}&lt;/pre&gt;

&lt;p&gt;Potete notare una differenza rispetto a quanto facciamo con i ViewModel: dato che, in questo caso, il nostro servizio utilizza un’interfaccia, dobbiamo dire al container che ogni qualvolta un ViewModel richiederà un oggetto di tipo &lt;strong&gt;IFeedService&lt;/strong&gt;, sarà suo compito restituirgli un’istanza concreta della classe &lt;strong&gt;FeedService&lt;/strong&gt;. Lo facciamo grazie al metodo &lt;strong&gt;PerRequest&amp;lt;T, Y&amp;gt;(), &lt;/strong&gt;dove &lt;strong&gt;T&lt;/strong&gt; è l’interfaccia e &lt;strong&gt;Y&lt;/strong&gt; l’implementazione reale. Ora siamo in grado di usare il servizio nel nostro ViewModel per mostrare le notizie.&lt;/p&gt;

&lt;p&gt;Ecco un esempio di XAML, all’interno della View, in grado di mostrare la collezione di oggetti di tipo &lt;strong&gt;FeedItem:&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;&amp;lt;StackPanel&amp;gt;
    &amp;lt;Button Content=&amp;quot;Load website&amp;quot; x:Name=&amp;quot;LoadWebsite&amp;quot;&amp;gt;&amp;lt;/Button&amp;gt;
    &amp;lt;ListBox x:Name=&amp;quot;News&amp;quot;&amp;gt;
        &amp;lt;ListBox.ItemTemplate&amp;gt;
            &amp;lt;DataTemplate&amp;gt;
                &amp;lt;StackPanel&amp;gt;
                    &amp;lt;TextBlock Text=&amp;quot;{Binding Path=Title}&amp;quot;&amp;gt;&amp;lt;/TextBlock&amp;gt;
                    &amp;lt;TextBlock Text=&amp;quot;{Binding Path=Description}&amp;quot;&amp;gt;&amp;lt;/TextBlock&amp;gt;
                &amp;lt;/StackPanel&amp;gt;
            &amp;lt;/DataTemplate&amp;gt;
        &amp;lt;/ListBox.ItemTemplate&amp;gt;
    &amp;lt;/ListBox&amp;gt;
&amp;lt;/StackPanel&amp;gt;&lt;/pre&gt;

&lt;p&gt;Abbiamo un pulsante, che utilizzeremo per caricare il feed RSS, e una lista che, tramite la definizione dell’&lt;strong&gt;ItemTemplate&lt;/strong&gt;, mostrerà le proprietà &lt;strong&gt;Title&lt;/strong&gt; e &lt;strong&gt;Description&lt;/strong&gt; (ovvero titolo e descrizione) della notizia.&lt;/p&gt;

&lt;p&gt;Ed ecco la definizione del ViewModel:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class MainPageViewModel: Screen
{
    private readonly IFeedService feedService;
 
    private List&amp;lt;FeedItem&amp;gt; news;
 
    public List&amp;lt;FeedItem&amp;gt; News
    {
        get { return news; }
        set
        {
            news = value;
            NotifyOfPropertyChange(() =&amp;gt; News);
        }
    }
 
    public MainPageViewModel(IFeedService feedService)
    {
        this.feedService = feedService;
    }
 
    public async void LoadWebsite()
    {
        News = await feedService.GetNews(&amp;quot;http://feeds.feedburner.com/qmatteoq_eng&amp;quot;);
    }
}&lt;/pre&gt;

&lt;p&gt;Nulla di speciale da evidenziare se non che, nel costruttore del ViewModel, abbiamo aggiunto un parametro di tipo &lt;strong&gt;IFeedService&lt;/strong&gt;: questo fa si che, grazie alla registrazione nel boostrapper fatta in precedenza, il ViewModel contenga in automatico un riferimento al servizio, che siamo in grado perciò di utilizzare nel momento in cui l’utente preme il pulsante e il metodo &lt;strong&gt;LoadWebsite()&lt;/strong&gt; viene invocato. Nell’esempio, tramite il metodo &lt;strong&gt;GetNews()&lt;/strong&gt; recuperiamo l’elenco di notizie pubblicate sul mio blog in inglese.&lt;/p&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;h3&gt;Passare dati da una pagina all’altra&lt;/h3&gt;

&lt;p&gt;Nel momento in cui abbiamo parlato di navigazione abbiamo evidenziato la possibilità di passare parametri nell’URL della pagina, così da poter scambiare informazioni tra le pagine. Il limite di questo approccio è che, trattandosi di parametri in query string, siamo in grado solamente di scambiare dati testuali, come stringhe o numeri. Nella maggior parte dei casi, invece, abbiamo la necessità di passare oggetti complessi. Ipotizziamo di voler espandere la nostra applicazione di esempio ed implementare una pagina per leggere il dettaglio della notizia: in tal caso, quello che vogliamo fare è passare l’intero oggetto &lt;strong&gt;FeedItem&lt;/strong&gt; che è stato selezionato, così da poterne accedere a tutte le proprietà.&lt;/p&gt;

&lt;p&gt;Un approccio che possiamo utilizzare è quello che abbiamo descritto in questo post: utilizzare un nostro servizio ad hoc, che passeremo ad ogni ViewModel.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class DataService
{
    public FeedItem SelectedItem { get; set; }
}&lt;/pre&gt;

&lt;p&gt;La classe è molto semplice, dato che contiene solamente una proprietà di tipo &lt;strong&gt;FeedItem&lt;/strong&gt;, nella quale andremo a salvare la notizia selezionata dall’utente.&lt;/p&gt;

&lt;p&gt;Ora dobbiamo registrare questa nuova classe nel bootstrapper:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;protected override void Configure()
{
    container = new PhoneContainer(RootFrame);
 
    container.RegisterPhoneServices();
    container.PerRequest&amp;lt;MainPageViewModel&amp;gt;();
    container.PerRequest&amp;lt;DetailPageViewModel&amp;gt;();
    container.PerRequest&amp;lt;IFeedService, FeedService&amp;gt;();
    container.Singleton&amp;lt;DataService&amp;gt;();
    AddCustomConventions();
}&lt;/pre&gt;

&lt;p&gt;In questa occasione possiamo vedere un nuovo tipo di registrazione, tramite il metodo &lt;strong&gt;Singleton&amp;lt;T&amp;gt;(). &lt;/strong&gt;Qual è la differenza? Nel momento in cui registriamo una classe con il metodo &lt;strong&gt;PerRequest&amp;lt;T&amp;gt;()&lt;/strong&gt;, ogni volta che all’interno dell’applicazione tentiamo di utilizzarla ci sarà restituita una nuova istanza. E’ l’approccio ideale per i ViewModel: nel nostro caso, ogni volta che la pagina di dettaglio viene caricata il suo contenuto deve essere cambiato, perchè deve essere mostrata la news selezionata; ha senso perciò che, ad ogni richiesta, ci venga restituita una nuova pagina con un nuovo ViewModel. Ecco perciò che la classe &lt;strong&gt;DetailPageViewModel&lt;/strong&gt; viene registrata con il metodo &lt;strong&gt;PerRequest&amp;lt;T&amp;gt;()&lt;/strong&gt;. Non è però la stessa situazione della classe &lt;strong&gt;DataService&lt;/strong&gt;: in questo caso abbiamo la necessità di mantenere la stessa istanza della classe, perchè vogliamo che ogni ViewModel possa accedere al dato contenuto nella proprietà &lt;strong&gt;SelectedItem&lt;/strong&gt;. Se ci facessimo restituire una nuova istanza ogni volta, il valore della proprietà andrebbe perso ad ogni richiesta. La soluzione è proprio quella di utilizzare il metodo &lt;strong&gt;Singleton&amp;lt;T&amp;gt;()&lt;/strong&gt;, che registra l’istanza della classe come univoca, facendo si che venga restituita sempre la stessa ad ogni richiesta.&lt;/p&gt;

&lt;p&gt;Ora dobbiamo aggiungere semplicemente un parametro di tipo &lt;strong&gt;DataService&lt;/strong&gt; sia nel costruttore della classe &lt;strong&gt;MainPageViewModel&lt;/strong&gt;, che in quello della classe &lt;strong&gt;DetailPageViewModel&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class MainPageViewModel: Screen
{
    private readonly IFeedService feedService;
    private readonly INavigationService navigationService;
    private readonly DataService dataService;
 
    private List&amp;lt;FeedItem&amp;gt; news;
 
    public List&amp;lt;FeedItem&amp;gt; News
    {
        get { return news; }
        set
        {
            news = value;
            NotifyOfPropertyChange(() =&amp;gt; News);
        }
    }
 
    private FeedItem selectedNew;
 
    public FeedItem SelectedNew
    {
        get { return selectedNew; }
        set
        {
            selectedNew = value;
            dataService.SelectedItem = value;
            navigationService.UriFor&amp;lt;DetailPageViewModel&amp;gt;().Navigate();
            NotifyOfPropertyChange(() =&amp;gt; SelectedNew);
        }
    }
 
    public MainPageViewModel(IFeedService feedService, INavigationService navigationService, DataService dataService)
    {
        this.feedService = feedService;
        this.navigationService = navigationService;
        this.dataService = dataService;
    }
 
    public async void LoadWebsite()
    {
        News = await feedService.GetNews(&amp;quot;http://feeds.feedburner.com/qmatteoq_eng&amp;quot;);
    }
}&lt;/pre&gt;

&lt;p&gt;Nel ViewModel della pagina principale abbiamo aggiunto anche una proprietà di nome &lt;strong&gt;SelectedNew&lt;/strong&gt;: se vi ricordate quanto spiegato &lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-collezioni-e-navigazione" target="_blank"&gt;nel post dedicato alle collezioni&lt;/a&gt;, in questo modo facciamo sì che questa venga automaticamente collegata all’elemento selezionato della lista. Dobbiamo però fare due modifiche al &lt;strong&gt;set&lt;/strong&gt; della proprietà (che viene invocato ogni qualvolta il suo valore viene modificato, nel nostro caso quando viene selezionato un elemento dalla lista): la prima è quella di salvare, all’interno della classe &lt;strong&gt;DataService&lt;/strong&gt;, l’elemento selezionato; la seconda è quella di scatenare la navigazione verso la pagina di dettaglio.&lt;/p&gt;

&lt;p&gt;E per quanto riguarda la pagina di dettaglio? La View, semplicemente, si limiterà a mostrare le informazioni della news selezionata:&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;&amp;lt;StackPanel&amp;gt;     
    &amp;lt;TextBlock x:Name=&amp;quot;Title&amp;quot; /&amp;gt;     
    &amp;lt;TextBlock x:Name=&amp;quot;Description&amp;quot; /&amp;gt;
&amp;lt;/StackPanel&amp;gt;&lt;/pre&gt;

&lt;p&gt;Il ViewModel conterrà semplicemente due proprietà, &lt;strong&gt;Title&lt;/strong&gt; e &lt;strong&gt;Description&lt;/strong&gt;, che saranno valorizzate con le informazioni recuperate dal &lt;strong&gt;DataService:&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class DetailPageViewModel: Screen
{
    private string title;
 
    public string Title
    {
        get { return title; }
        set
        {
            title = value;
            NotifyOfPropertyChange(() =&amp;gt; Title);
        }
    }
 
    private string description;
 
    public string Description
    {
        get { return description; }
        set
        {
            description = value;
            NotifyOfPropertyChange(() =&amp;gt; Description);
        }
    }
 
    public DetailPageViewModel(DataService dataService)
    {
        Title = dataService.SelectedItem.Title;
        Description = dataService.SelectedItem.Description;
    }
}&lt;/pre&gt;

&lt;p&gt;Anche in questo caso abbiamo aggiunto un parametro di tipo &lt;strong&gt;DataService&lt;/strong&gt; nel costruttore: dato che, nel boostrapper, lo abbiamo registrato come singleton, il risultato è che l’istanza che ci sarà passata è la stessa che è stata definita nel &lt;strong&gt;MainPageViewModel&lt;/strong&gt;: di conseguenza, la proprietà &lt;strong&gt;SelectedItem&lt;/strong&gt; della classe &lt;strong&gt;DataService&lt;/strong&gt; sarà valorizzata con la notizia scelta dall’utente nella pagina precedente.&lt;/p&gt;

&lt;p&gt;Come al solito, vi lascio a disposizione un progetto di esempio con cui sperimentare le funzionalità descritte in questo post. Buon lavoro!&lt;/p&gt;

&lt;div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:68f81ee8-c30d-4398-b677-263477b9436b" class="wlWriterSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;
  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/CaliburnMicro_Services.zip" target="_blank"&gt;Scarica il progetto di esempio&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-la-teoria"&gt;Caliburn Micro e Windows Phone – La teoria&lt;/a&gt; (3/18/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-il-primo-progetto"&gt;Caliburn Micro e Windows Phone – Il primo progetto&lt;/a&gt; (3/21/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-collezioni-e-navigazione"&gt;Caliburn Micro e Windows Phone – Collezioni e navigazione&lt;/a&gt; (3/29/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-tombstoning"&gt;Caliburn Micro e Windows Phone – Tombstoning&lt;/a&gt; (4/3/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-messaggi"&gt;Caliburn Micro e Windows Phone – Messaggi&lt;/a&gt; (4/12/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-utilizzare-i-launcher-e-i-chooser"&gt;Caliburn Micro e Windows Phone – Utilizzare i launcher e i chooser&lt;/a&gt; (4/24/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/caliburn-micro-e-windows-phone-utilizzare-i-propri-servizi"&gt;&lt;strong&gt;More related document (288)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/qmatteoq/~4/kRt8cEmpS7A" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/qmatteoq/~3/kRt8cEmpS7A/caliburn-micro-e-windows-phone-utilizzare-i-propri-servizi</link><author>qmatteoq</author><comments>http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-utilizzare-i-propri-servizi#feedback</comments><guid isPermaLink="false">http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-utilizzare-i-propri-servizi</guid><pubDate>Tue, 30 Apr 2013 10:00:00 GMT</pubDate><category>Windows Phone</category><category>Caliburn</category><category>MVVM</category><feedburner:origLink>http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-utilizzare-i-propri-servizi</feedburner:origLink></item><item><title>Prossimi appuntamenti: Community Days, DotNetCampus, Intel MeetUp e altro ancora</title><description>&lt;p&gt;Periodo ricco di appuntamenti per gli sviluppatori e per le community d’Italia! Vi segnalo alcuni degli eventi più interessanti nel prossimo periodo.&lt;/p&gt;  &lt;h3&gt;Community Days&lt;/h3&gt;  &lt;p&gt;Dopo la tappa di Milano, tornano i Community Days e questa volta si spostano a Catania, per offrire anche agli sviluppatori del Sud Italia due giorni di sessioni e lab su Windows 8, Windows Phone, Azure e Web. Avrò il piacere di essere presente anche io a rappresentare DotNetLombardia, a dare una mano ai laboratori e a tenere una sessione sulla distribuzione di applicazioni Windows Phone: lo Store, gli scenari Enterprise e l’in app-purchase. L’appuntamento è per il &lt;strong&gt;20 e 21 Maggio &lt;/strong&gt;presso la&lt;strong&gt; Cittadella Universataria di Catania&lt;/strong&gt;. Trovate l’agenda completa, le informazioni logistiche e i link per iscrivervi &lt;a href="http://www.communitydays.it/events/communitydays2013-catania"&gt;sul sito ufficiale&lt;/a&gt;. Attenzione che i laboratori su Windows 8, Windows Phone e Azure richiedono una registrazione separata rispetto a quella tradizionale per le giornate.&lt;/p&gt;  &lt;h3&gt;DotNetCampus&lt;/h3&gt;  &lt;p&gt;Anche il DotNetCampus si ripete e, dopo la tappa di Roma, propone altri due appuntamenti a Cosenza (il &lt;strong&gt;15 Maggio&lt;/strong&gt; presso la sede dell’&lt;strong&gt;Università della Calabria&lt;/strong&gt;) e a Cesena (il &lt;strong&gt;14 Giugno, &lt;/strong&gt;presso il TechnoGym Village). Sarò presente anche in questa occasione, proponendo una sessione dedicata all’accesso ai dati locali in Windows Phone: database, isolated storage e file sharing. A rappresentare DotNetLombardia, con me, ci sarà anche Roberto, che terrà due sessioni dedicate a Windows Phone e ad Azure.&lt;/p&gt;  &lt;p&gt;Trovate tutte le indicazioni, l’agenda e i link per iscrivervi ad entrambe le tappe &lt;a href="http://www.dotnetcampus.it/"&gt;sul sito ufficiale&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Windows Azure Conference&lt;/h3&gt;  &lt;p&gt;DotNetLombardia e Microsoft propongono insieme una giornata di approfondimento dedicata alle novità recentemente annunciate su Azure, suddivisa in due momenti: uno più formativo, al mattino, con sessioni su tematiche come i Mobile Service o lo sviluppo e il deploy di applicazioni web, e uno più pratico, con laboratori e ampio spazio alle domande. L’appuntamento è per il &lt;strong&gt;6 Maggio&lt;/strong&gt; presso il &lt;strong&gt;Microsoft Innovation Campus&lt;/strong&gt; di Peschiera Borromeo (MI). Iscrizioni e maggiori dettagli &lt;a href="https://msevents.microsoft.com/cui/EventDetail.aspx?EventID=1032552059&amp;amp;culture=it-IT"&gt;sulla pagina ufficiale&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Intel MeetUp – The Natural User Interface Episode&lt;/h3&gt;  &lt;p&gt;Anche gli amici di Intel propongono, &lt;strong&gt;Sabato 4 Maggio&lt;/strong&gt; a &lt;strong&gt;Bologna&lt;/strong&gt;, un evento molto interessante dedicato alle Natural User Interface, in collaborazione con la community emiliana DotDotNet. Si parlerà di Perceptual Computing con le tecnologie di Intel, di Kinect e del nuovo Leap Motion. Se volete scoprire le ultime novità sulle nuove modalità di interazione con le più recenti tecnologie, non potete mancare! Agenda e iscrizioni &lt;a href="http://www.meetup.com/ItalyDeveloperZone/events/112662122/"&gt;sul sito ufficiale&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Tutto quello che avreste voluto sapere sull'accesso ai dati (e non avete mai osato chiedere)&lt;/h3&gt;  &lt;p&gt;Gli amici di DotNetToscana propongono, &lt;strong&gt;Sabato 18 Maggio&lt;/strong&gt; a &lt;strong&gt;Pisa&lt;/strong&gt;, una giornata completamente dedicata all’accesso ai dati in Windows Phone e Windows 8: si parlerà di SQLite, WebAPI, Mobile Service e SkyDrive. Se siete di quelle parti non perdetevelo perchè l’agenda è decisamente interessante. Informazioni e iscrizioni &lt;a href="http://www.dotnettoscana.org/windows-8-e-windows-phone-tutto-quello-che-avreste-voluto-sapere-sullaccesso-ai-dati.aspx?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+dotnettoscana+%28DotNetToscana+News%29"&gt;sul sito ufficiale&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Spring Event by Visual Basic Tips &amp;amp; Tricks&lt;/h3&gt;  &lt;p&gt;Visual Basic Tips &amp;amp; Tricks, una delle community italiane storiche, propone &lt;strong&gt;Sabato 8 Giugno a Vicenza&lt;/strong&gt; una mattinata di approfondimento sulle nuove tecnologie web e cloud di Microsoft. Si parlerà di Azure, SignalR e LightSwitch, l’ottimo strumento di Microsoft per realizzare in maniera semplice e veloce applicazioni business. Iscrizioni e agenda &lt;a href="http://www.visual-basic.it/DettaglioNews/tabid/160/ArticleId/1664/VBTT-a-Vicenza-per-lo-Spring-Event.aspx#.UX5J7LX-GX4"&gt;sul sito ufficiale&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Web e ASP.NET Live&lt;/h3&gt;  &lt;p&gt;Gli eventi community sono da sempre il modo migliore per avvicinarsi alle nuove tecnologie e, allo stesso tempo, espandere la propria rete di contatti e conoscere nuove persone. Non sempre però si ha la possibilità di partecipare fisicamente. Vi farà piacere sapere, perciò, che ASPItalia ha organizzato un pomeriggio dedicato alle ultime novità Microsoft per il Web e che sarà tramesso in streaming online: tra gli argomenti trattati le Single Page Application, SignalR, WebAPI e tanto altro ancora, a cura dei membri di ASPItalia. Pur essendo un evento esclusivamente online, è comunque necessario iscriversi &lt;a href="http://www.aspitalia.com/eventi/49/Web-ASP.NET-Live-Online.aspx"&gt;sul sito ufficiale&lt;/a&gt;, dove trovate anche l’agenda completa. L’appuntamento è per il &lt;strong&gt;16 Maggio.&lt;/strong&gt;&lt;/p&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/due-grandi-eventi-per-il-2012-community-days-e-dotnetcampus"&gt;Due grandi eventi per il 2012: Community Days e DotNetCampus&lt;/a&gt; (12/22/2011)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/i-prossimi-eventi-su-windows-phone"&gt;I prossimi eventi su Windows Phone&lt;/a&gt; (2/5/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/community-days-2012-al-via"&gt;Community Days 2012 al via!&lt;/a&gt; (2/16/2012)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/slide-e-demo-dai-community-days-2013"&gt;Slide e demo dai Community Days 2013&lt;/a&gt; (3/1/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/visual-studio-day-by-dotnetlombardia-e-intel"&gt;Visual Studio Day by DotNetLombardia e Intel&lt;/a&gt; (8/20/2012)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/prossimi-appuntamenti-community-days-dotnetcampus-intel-meetup-e-altro-ancora"&gt;&lt;strong&gt;More related document (184)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/qmatteoq/~4/rbWchDwonqI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/qmatteoq/~3/rbWchDwonqI/prossimi-appuntamenti-community-days-dotnetcampus-intel-meetup-e-altro-ancora</link><author>qmatteoq</author><comments>http://www.qmatteoq.com/blog/post/prossimi-appuntamenti-community-days-dotnetcampus-intel-meetup-e-altro-ancora#feedback</comments><guid isPermaLink="false">http://www.qmatteoq.com/blog/post/prossimi-appuntamenti-community-days-dotnetcampus-intel-meetup-e-altro-ancora</guid><pubDate>Mon, 29 Apr 2013 10:00:00 GMT</pubDate><category>Microsoft</category><category>DotnetCampus</category><category>Community Days</category><category>Intel</category><feedburner:origLink>http://www.qmatteoq.com/blog/post/prossimi-appuntamenti-community-days-dotnetcampus-intel-meetup-e-altro-ancora</feedburner:origLink></item><item><title>Caliburn Micro e Windows Phone – Utilizzare i launcher e i chooser</title><description>&lt;p&gt;Nel post precedente della serie abbiamo visto come funzioni l’infrastrattura dei messaggi integrata in Caliburn Micro. In questo post vedremo come utilizzare i launcher e i chooser in un ViewModel: i due argomenti sono strettamente collegati, dato che per eseguire questo compito Caliburn Micro utilizzato un tipo speciale di messaggio. Infatti, per interagire con launcher e chooser andremo ad utilizzare la classe &lt;strong&gt;IEventAggregator&lt;/strong&gt; che abbiamo imparato ad utilizzare in precedenza. La differenza, in questo caso, sarà che i messaggi saranno “nascosti” e già inclusi all’interno del toolkit. Iniziamo!&lt;/p&gt;  &lt;p&gt;Do per scontato che, se state leggendo questo blog, dato che MVVM è un argomento “avanzato”, sappiate già cosa sono i launcher e i chooser. In caso contrario, vi basti sapere per ora che sono un meccanismo che il sistema operativo mette a disposizione per interagire con le applicazioni native: ad esempio, per mostrare una posizione nell’applicazione Mappe o per importare un contatto dall’hub People; o ancora, inviare un SMS tramite l’applicazione Messaggi.&lt;/p&gt;  &lt;h3&gt;I launcher&lt;/h3&gt;  &lt;p&gt;Vediamo come interagire con i launcher, ovvero i task che sono utilizzati per demandare un’operazione ad un’applicazione nativa ma non si aspettano dati di ritorno: il nostro esempio sarà basato sulla classe &lt;strong&gt;MapsTask&lt;/strong&gt;, che consente di mostrare una posizione nell’applicazione Mappe. Do per scontato che abbiate già creato il progetto base utilizzando Caliburn Micro, perciò abbiate già a disposizione una View collegata al relativo ViewModel tramite l’apposita convenzione che abbiamo imparato ad usare nei primi post.&lt;/p&gt;  &lt;p&gt;Nella View aggiungiamo un pulsante, che useremo per eseguire il launcher:&lt;/p&gt;  &lt;pre class="brush: xml;"&gt;&amp;lt;StackPanel&amp;gt;
    &amp;lt;Button Content=&amp;quot;Launch map&amp;quot; x:Name=&amp;quot;LaunchMap&amp;quot; /&amp;gt;
&amp;lt;/StackPanel&amp;gt;&lt;/pre&gt;

&lt;p&gt;Come sempre, grazie alle convenzioni di Caliburn, questa dichiarazione fa si che, al click sul pulsante, venga eseguito un metodo dal nome &lt;strong&gt;LaunchMap&lt;/strong&gt; dichiarato nel ViewModel. Diamo uno sguardo al codice:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class MainPageViewModel: Screen
{
    public MainPageViewModel(IEventAggregator eventAggregator)
    {
        this.eventAggregator = eventAggregator;
        eventAggregator.Subscribe(this);
    }
 
    public void LaunchMap()
    {
        eventAggregator.RequestTask&amp;lt;MapsTask&amp;gt;(task =&amp;gt;
                                                  {
                                                      task.SearchTerm = &amp;quot;Milan&amp;quot;;
                                                  });
    }
}&lt;/pre&gt;

&lt;p&gt;Come abbiamo potuto vedere nel post dedicato ai messaggi, è sufficiente aggiungere un parametro nel costruttore del ViewModel di tipo &lt;strong&gt;IEventAggregator &lt;/strong&gt;per ottenere un riferimento all’oggetto da utilizzare per interagire con i messaggi. Il primo passaggio è sottoscriversi alla ricezione, utilizzando il metodo &lt;strong&gt;Subscribe(), &lt;/strong&gt;passando come parametro la parola chiave &lt;strong&gt;this&lt;/strong&gt; (dato che vogliamo abilitare alla ricezione il ViewModel stesso).&lt;/p&gt;

&lt;p&gt;Nel metodo &lt;strong&gt;LaunchMap()&lt;/strong&gt; utilizziamo la classe &lt;strong&gt;EventAggregator&lt;/strong&gt;, chiamando uno degli extension method aggiunti alla versione di Caliburn Micro per Windows Phone: &lt;strong&gt;RequestTask&amp;lt;T&amp;gt;()&lt;/strong&gt;, dove &lt;strong&gt;T&lt;/strong&gt; è la classe che rappresenta il launcher che vogliamo eseguire (sono quelle contenute all’interno del namespace &lt;strong&gt;Microsoft.Phone.Tasks&lt;/strong&gt;). Come parametro possiamo passare un delegate (nell’esempio, ne utilizziamo uno anonimo): si tratta di un’operazione necessaria per tutti quei launcher o chooser che hanno bisogno di alcune informazioni per funzionare correttamente. Nel nostro esempio, impostiamo la proprietà &lt;strong&gt;SearchTerm&lt;/strong&gt; del task, per specificare la posizione che vogliamo cercare nella mappa. Se dobbiamo utilizzare un launcher che non richiede alcuna informazione in input (come il &lt;strong&gt;MarketplaceDetailTask&lt;/strong&gt;), possiamo semplicemente non passare alcun parametro al metodo.&lt;/p&gt;

&lt;p&gt;Se provate questa semplice applicazione sul telefono, vedrete l’applicazione Mappe aprirsi e localizzare la città di Milano nel momento in cui premete il pulsante.&lt;/p&gt;

&lt;h3&gt;I chooser&lt;/h3&gt;

&lt;p&gt;I chooser funzionano in un modo leggermente differente: il modo in cui andremo ad eseguirli è lo stesso deie launcher ma, in questo caso, ci aspettiamo anche un risultato. Come già detto all’inizio del post, l’utilizzo di launcher e chooser con Caliburn è basato sui messaggio: ecco perciò che il modo in cui gestiamo il valore di ritorno è lo stesso che abbiamo visto in precedenza per ricevere un messaggio. Facciamo una prova utilizzando il chooser &lt;strong&gt;PhoneNumberChooserTask&lt;/strong&gt;, che può essere utilizzato per importare il numero di telefono di un contatto dalla rubrica.&lt;/p&gt;

&lt;p&gt;Prima aggiungiamo il solito pulsante nella View:&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;&amp;lt;StackPanel&amp;gt;
    &amp;lt;Button Content=&amp;quot;Open contact&amp;quot; x:Name=&amp;quot;OpenContact&amp;quot; /&amp;gt;
&amp;lt;/StackPanel&amp;gt;&lt;/pre&gt;

&lt;p&gt;Ora diamo uno sguardo al ViewModel:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class MainPageViewModel: Screen, IHandle&amp;lt;TaskCompleted&amp;lt;PhoneNumberResult&amp;gt;&amp;gt;
{
    private readonly IEventAggregator eventAggregator;
 
    public MainPageViewModel(IEventAggregator eventAggregator, INavigationService navigationService)
    {
        this.eventAggregator = eventAggregator;
 
        eventAggregator.Subscribe(this);
    }
 
    public void OpenContact()
    {
        eventAggregator.RequestTask&amp;lt;PhoneNumberChooserTask&amp;gt;();
    }
 
    public void Handle(TaskCompleted&amp;lt;PhoneNumberResult&amp;gt; message)
    {
        MessageBox.Show(message.Result.DisplayName);
    }
}&lt;/pre&gt;

&lt;p&gt;Il modo in cui utilizziamo un chooser è lo stesso che abbiamo visto per il launcher: utilizziamo il metodo &lt;strong&gt;RequestTask&amp;lt;T&amp;gt;()&lt;/strong&gt; dell’oggetto &lt;strong&gt;EventAggregator&lt;/strong&gt;, passando come valore di &lt;strong&gt;T&lt;/strong&gt; il tipo di chooser che vogliamo utilizzare. In questo caso, rispetto a prima, non passiamo alcun parametro, dato che questo chooser non richiede nessuna informazione in ingresso per funzionare. Per gestire il valore di ritorno (quindi il numero della rubrica scelto dall’utente) utilizziamo lo stesso approccio visto nei messaggi: facciamo ereditare il ViewModel dalla classe &lt;strong&gt;IHandle&amp;lt;T&amp;gt;&lt;/strong&gt;, dove &lt;strong&gt;T&lt;/strong&gt; è di tipo &lt;strong&gt;TaskCompleted&amp;lt;T&amp;gt;&lt;/strong&gt;. Questo secondo T, a sua volta, è il tipo restituito dal chooser (nel nostro caso, un oggetto di tipo &lt;strong&gt;PhoneNumberResult&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;Ereditando da questa interfaccia, saremo costretti ad implementare il metodo &lt;strong&gt;Handle()&lt;/strong&gt;, che riceve come parametro il risultato restituito dal chooser. Sta a noi decidere cosa farne: nell’esempio, ci limitiamo a mostrare il valore della proprietà &lt;strong&gt;DisplayName&lt;/strong&gt; (che contiene nome e cognome del contatto).&lt;/p&gt;

&lt;h3&gt;Come gestire correttamente il ciclo di vita dei launcher e chooser&lt;/h3&gt;

&lt;p&gt;C’è un problema nell’usare l’architettura dei messaggi per gestire launcher e chooser. Quando abilitate un ViewModel alla ricezione di messaggi utilizzando il metodo &lt;strong&gt;Subscribe()&lt;/strong&gt;, la sottoscrizione viene mantenuta attiva fintanto che l’istanza del ViewModel viene tenuta in memoria. Nel caso dei launcher e dei chooser questo può causare qualche problema: se ricordate il post precedente, eravamo in grado di sfruttare i messaggi per scambiare informazioni tra due ViewModel; in questo caso, invece, utilizziamo i messaggi per scambiare informazioni all’interno del ViewModel stesso (dato che si occupa sia di inviarlo, che di riceverlo). Se, ad esempio, spostaste il metodo &lt;strong&gt;OpenContact()&lt;/strong&gt; che abbiamo appena visto in un altro ViewModel (ad esempio, una seconda pagina), ma manteneste il &lt;strong&gt;MainPageViewModel&lt;/strong&gt; abilitato alla ricezione di messaggi di tipo &lt;strong&gt;TaskCompleted&amp;lt;PhoneNumberResult&amp;gt;&lt;/strong&gt;, notereste che il &lt;strong&gt;MainPageViewModel&lt;/strong&gt; continuerebbe a rispondere all’attivazione del chooser, anche se venisse scatenata da un altro ViewModel.&lt;/p&gt;

&lt;p&gt;Questo scenario si applica soprattutto quando parliamo del &lt;strong&gt;MainPageViewModel&lt;/strong&gt;, ovvero il ViewModel che è collegato alla pagina principale dell’applicazione: per questo motivo, la sua istanza viene sempre mantenuta attiva, fino al momento in cui l’applicazione non viene chiusa, al contrario di quanto avviene per le altre pagine (se siete nella seconda pagina della vostra applicazione e tornate alla pagina principale, questa, assieme al relativo ViewModel, viene dismessa).&lt;/p&gt;

&lt;p&gt;Il modo migliore per gestire questa casistica è quello di usare gli eventi di navigazione che abbiamo imparato ad utilizzare &lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-navigazione-avanzata-e-deep-link"&gt;in un post precedente&lt;/a&gt; ed ereditare il nostro ViewModel dalla classe &lt;strong&gt;Screen&lt;/strong&gt;: in questo modo possiamo chiamare il metodo &lt;strong&gt;Subscribe()&lt;/strong&gt; della classe &lt;strong&gt;EventAggregator&lt;/strong&gt; nel momento in cui l’utente naviga verso la pagina (sfruttando il metodo &lt;strong&gt;OnActivate()&lt;/strong&gt;) e, viceversa, utilizzare il metodo &lt;strong&gt;Unsubscribe() &lt;/strong&gt;nel momento in cui l’utente lascia la pagina (sfruttando il metodo &lt;strong&gt;OnDeactivate()&lt;/strong&gt;). Con questo approccio, nel momento in cui l’utente si sposta dalla pagina corrente verso un’altra pagina, questa non è più abilitata alla ricezione dei messaggi e, di conseguenza, ignorerà qualsiasi interazione con i launcher e i chooser.&lt;/p&gt;

&lt;p&gt;Ecco un esempio di come appare il ViewModel aggiornato:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class MainPageViewModel: Screen, IHandle&amp;lt;TaskCompleted&amp;lt;PhoneNumberResult&amp;gt;&amp;gt;
{
    private readonly IEventAggregator eventAggregator;
 
    public MainPageViewModel(IEventAggregator eventAggregator)
    {
        this.eventAggregator = eventAggregator;
    }
    protected override void OnActivate()
    {
        eventAggregator.Subscribe(this);
        base.OnActivate();
    }
 
    protected override void OnDeactivate(bool close)
    {
        eventAggregator.Unsubscribe(this);
        base.OnDeactivate(close);
    }
 
    public void OpenContact()
    {
        eventAggregator.RequestTask&amp;lt;PhoneNumberChooserTask&amp;gt;();
    }
 
    public void Handle(TaskCompleted&amp;lt;PhoneNumberResult&amp;gt; message)
    {
        MessageBox.Show(message.Result.DisplayName);
    }
}&lt;/pre&gt;

&lt;p&gt;Come potete notare, non chiamiamo più il metodo &lt;strong&gt;Subscribe()&lt;/strong&gt; della classe &lt;strong&gt;EventAggregator&lt;/strong&gt; nel costruttore, ma lo abbiamoi spostato nel metodo &lt;strong&gt;OnActivate()&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Se volete fare qualche esperimento con quanto appreso in questo post, di seguito trovate il link per scaricare un progetto di esempio.&lt;/p&gt;

&lt;div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:7111eb5e-0223-413e-a93d-5cc6b1d8c9a1" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;p&gt; &lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/CaliburnMicro_LaunchersChoosers.zip" target="_blank"&gt;Scarica il progetto di esempio&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-la-teoria"&gt;Caliburn Micro e Windows Phone – La teoria&lt;/a&gt; (3/18/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-il-primo-progetto"&gt;Caliburn Micro e Windows Phone – Il primo progetto&lt;/a&gt; (3/21/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-collezioni-e-navigazione"&gt;Caliburn Micro e Windows Phone – Collezioni e navigazione&lt;/a&gt; (3/29/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-tombstoning"&gt;Caliburn Micro e Windows Phone – Tombstoning&lt;/a&gt; (4/3/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-messaggi"&gt;Caliburn Micro e Windows Phone – Messaggi&lt;/a&gt; (4/12/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/caliburn-micro-e-windows-phone-utilizzare-i-launcher-e-i-chooser"&gt;&lt;strong&gt;More related document (289)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/qmatteoq/~4/5WWkxJA_iHs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/qmatteoq/~3/5WWkxJA_iHs/caliburn-micro-e-windows-phone-utilizzare-i-launcher-e-i-chooser</link><author>qmatteoq</author><comments>http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-utilizzare-i-launcher-e-i-chooser#feedback</comments><guid isPermaLink="false">http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-utilizzare-i-launcher-e-i-chooser</guid><pubDate>Wed, 24 Apr 2013 10:00:00 GMT</pubDate><category>Windows Phone</category><category>MVVM</category><category>Caliburn</category><feedburner:origLink>http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-utilizzare-i-launcher-e-i-chooser</feedburner:origLink></item><item><title>Slide e demo del DotNetCampus</title><description>&lt;p&gt;Sabato si è svolto a Roma, nella cornice dell’Università di Roma Tre, il &lt;strong&gt;DotNetCampus&lt;/strong&gt;, un evento organizzato da DevLeap in collaborazione con diversi sponsor che mette insieme tante realtà che ruotano attorno al mondo Microsoft: community, MVP, studenti, aziende e quant’altro. Anche noi di &lt;strong&gt;DotNetLombardia&lt;/strong&gt; eravamo là, con un nostro stand e con la presenza mia e di Roberto, con il quale abbiamo proposto sessioni riguardanti Windows Phone e Windows Azure.&lt;/p&gt;  &lt;p&gt;Nello specifico, ho tenuto una sessione dedicata all’accesso ai dati locali in Windows Phone 8: le nuove API per lo storage, i database disponibili e la nuova funzionalità di data sharing, per condividere dati con altre applicazioni.&lt;/p&gt;  &lt;p&gt;La giornata è stata magnifica: tantissima gente, molto interesse verso gli argomenti proposti e tante occasioni, sia per noi speaker e membri delle community che per i partecipanti, di conoscere e incontrare altre persone.&lt;/p&gt;  &lt;p&gt;Di seguito, vi propongo le slide e le demo utilizzate durante la mia sessione. Potete fare riferimento &lt;a href="http://www.qmatteoq.com/blog/post/sqlite-e-windows-phone-un-porting-della-libreria-sqlite-net"&gt;a questo post&lt;/a&gt; per tutti i dettagli su come installare e utilizzare SQLite nella vostra applicazioni Windows Phone 8.&lt;/p&gt;  &lt;p&gt;Per qualsiasi dubbio, potete contattarmi tramite &lt;a href="http://www.qmatteoq.com/contacts"&gt;il form apposito&lt;/a&gt;!&lt;/p&gt;  &lt;div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:f7c5c467-83b8-44a4-9693-cb1bc923102f" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;p&gt; &lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/Local%20storage,%20database%20e%20file%20sharing%20in%20Windows%20Phone%208%20-%20Demo_1.zip" target="_blank"&gt;Scarica la demo&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;   &lt;iframe height="327" src="https://skydrive.live.com/embed?cid=4FCC3142559B8B11&amp;amp;resid=4FCC3142559B8B11%21205206&amp;amp;authkey=ACfOW_fdKlPZxKs&amp;amp;em=2" frameborder="0" width="402" scrolling="no"&gt;&lt;/iframe&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/i-prossimi-eventi-su-windows-phone"&gt;I prossimi eventi su Windows Phone&lt;/a&gt; (2/5/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/due-grandi-eventi-per-il-2012-community-days-e-dotnetcampus"&gt;Due grandi eventi per il 2012: Community Days e DotNetCampus&lt;/a&gt; (12/22/2011)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/prossimi-appuntamenti-community-days-dotnetcampus-intel-meetup-e-altro-ancora"&gt;Prossimi appuntamenti: Community Days, DotNetCampus, Intel MeetUp e altro ancora&lt;/a&gt; (4/29/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/lo-speciale-di-aspitalia-sulle-novita-per-gli-sviluppatori-di-windows-phone-8"&gt;Lo speciale di ASPItalia sulle novità per gli sviluppatori di Windows Phone 8&lt;/a&gt; (10/31/2012)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/windows-phone-8-e-finalmente-realta"&gt;Windows Phone 8 è finalmente realtà!&lt;/a&gt; (10/30/2012)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/slide-e-demo-del-dotnetcampus"&gt;&lt;strong&gt;More related document (290)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/qmatteoq/~4/KRw8u5ktKd0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/qmatteoq/~3/KRw8u5ktKd0/slide-e-demo-del-dotnetcampus</link><author>qmatteoq</author><comments>http://www.qmatteoq.com/blog/post/slide-e-demo-del-dotnetcampus#feedback</comments><guid isPermaLink="false">http://www.qmatteoq.com/blog/post/slide-e-demo-del-dotnetcampus</guid><pubDate>Mon, 15 Apr 2013 14:21:18 GMT</pubDate><category>Windows Phone</category><category>DotnetCampus</category><feedburner:origLink>http://www.qmatteoq.com/blog/post/slide-e-demo-del-dotnetcampus</feedburner:origLink></item><item><title>Caliburn Micro e Windows Phone – Messaggi</title><description>&lt;p&gt;Durante lo sviluppo di un’applicazione con il pattern MVVM capita frequentemente di dover scambiare dati tra un ViewModel e l’altro, oppure di dover creare un canale di comunicazione tra la View e il ViewModel (ad esempio, per avviare un’animazione in seguito ad un’azione che si è scatentata nel ViewModel).&lt;/p&gt;  &lt;p&gt;La soluzione più utilizzata in queste situazioni è lo scambio di messaggi: tutti framework di MVVM espongono una serie di classi ed helper per gestire questo scenario.&lt;/p&gt;  &lt;p&gt;Cos’è un messaggio? Si tratta di una semplice classe, che può avere una o più proprietà, che rappresentano le informazioni da scambiare. Lo scambio di messaggi, solitamente, segue il flusso seguente:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Il ViewModel prepara un messaggio, creando una nuova istanza della classe che lo rappresenta, e lo spedisce; &lt;/li&gt;    &lt;li&gt;Uno o più ViewModel si sottoscrivono per ricevere il messaggio: in tal caso, ogni qualvolta un ViewModel ne spedisce uno di quel tipo specifico, i ViewModel ricevono una notifica, così che possano gestirlo di conseguenza ed eseguire una o più operazioni.. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Vediamo come implementare questo scenario utilizzando Caliburn Micro: andremo a creare due View, con i relativi ViewModel. La prima pagina conterrà un pulsante, che invierà un messaggio contente una stringa (un nome) all’altro ViewModel, così da mostrarlo nella seconda pagina.&lt;/p&gt;  &lt;p&gt;Il primo passo è quello di creare il progetto: seguendo i tutorial precedenti creiamo un’applicazione composta da due pagine con i relativi ViewModel.&lt;/p&gt;  &lt;p&gt;Prima di implementare il codice vero e proprio necessario per scambiare i messaggi, prepariamo tutta l’infrastruttura necessaria. La prima cosa da fare è aggiungere, nella prima pagina, un controllo TextBox e un pulsante: il primo mostrerà l’informazione ricevuta dal messaggio, il secondo invece lo useremo per portare l’utente alla seconda pagina.&lt;/p&gt;  &lt;p&gt;Aprite la pagina principale dell’applicazione (solitamente il file &lt;strong&gt;MainPage.xaml&lt;/strong&gt;) e, all’interno del controllo &lt;strong&gt;Grid&lt;/strong&gt; identificato dal nome &lt;strong&gt;ContentPanel&lt;/strong&gt;, aggiungete il seguente codice XAML:&lt;/p&gt;  &lt;pre class="brush: xml;"&gt;&amp;lt;StackPanel&amp;gt;
    &amp;lt;TextBox x:Name=&amp;quot;Name&amp;quot; /&amp;gt;
    &amp;lt;Button Content=&amp;quot;Go to page 2&amp;quot; x:Name=&amp;quot;GoToPage2&amp;quot; /&amp;gt;
&amp;lt;/StackPanel&amp;gt;&lt;/pre&gt;

&lt;p&gt;Anche in questo caso utilizziamo le convenzioni di Caliburn che abbiamo già imparato a conoscere: il controllo &lt;strong&gt;TextBox &lt;/strong&gt;sarà collegato ad una proprietà chiamata &lt;strong&gt;Name&lt;/strong&gt; nel ViewModel, mentre il pulsante eseguirà il metodo &lt;strong&gt;GoToPage2, &lt;/strong&gt;sempre dichiarato all’interno del ViewModel.&lt;/p&gt;

&lt;p&gt;Ecco invece la definizione del ViewModel:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class MainPageViewModel: Screen 
{ 
    private string name; 
  
    public string Name 
    { 
        get { return name; } 
        set
        { 
            name = value; 
            NotifyOfPropertyChange(() =&amp;gt; Name); 
        } 
    } 
  
    public MainPageViewModel(INavigationService navigationService) 
    { 
        this.navigationService = navigationService; 
    } 
  
    public void GoToPage2() 
    { 
        navigationService.UriFor&amp;lt;SecondPageViewModel&amp;gt;().Navigate(); 
    } 
}&lt;/pre&gt;

&lt;p&gt;Se avete seguito i post precedenti non dovreste notare nulla di particolare: oltre alla proprietà &lt;strong&gt;Name, &lt;/strong&gt;è presente un riferimento alla classe &lt;strong&gt;NavigationService &lt;/strong&gt;per gestire la navigazione.&lt;/p&gt;

&lt;p&gt;Ora passiamo alla seconda pagina. Ecco lo XAML:&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;&amp;lt;StackPanel&amp;gt; 
    &amp;lt;Button Content=&amp;quot;Send message&amp;quot; x:Name=&amp;quot;SendMessage&amp;quot; /&amp;gt; 
&amp;lt;/StackPanel&amp;gt;&lt;/pre&gt;

&lt;p&gt;Inseriamo solamente un pulsante, che eseguirà il metodo &lt;strong&gt;SendMessaage()&lt;/strong&gt; dichiarato nel ViewModel. Ora le cose iniziano a farsi interessanti: ecco la definizione del ViewModel, che contiene l’infrastruttura base per inviare il messaggio.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class SecondPageViewModel: Screen 
{ 
    private readonly IEventAggregator eventAggregator; 
  
    public SecondPageViewModel(IEventAggregator eventAggregator) 
    { 
        this.eventAggregator = eventAggregator; 
    } 
  
    public void SendMessage() 
    { 
        eventAggregator.Publish(new SampleMessage(&amp;quot;Matteo&amp;quot;)); 
    } 
}&lt;/pre&gt;

&lt;p&gt;La classe utilizzata per la gestione dei messaggi si chiama &lt;strong&gt;EventAggregator&lt;/strong&gt;: analogamente a quanto avviene con il NavigationService, si tratta di uno dei servizi integrati in Caliburn. E’ sufficiente, perciò, aggiungere un parametro di tipo &lt;strong&gt;IEventAggregator&lt;/strong&gt; nel costruttore affinchè venga risolto automaticamente. Inviare un messaggio è molto semplice: è sufficiente chiamare il metodo &lt;strong&gt;Publish() &lt;/strong&gt;passando come parametro l’oggetto che rappresenta il messaggio da inviare. Come già anticipato in precedenza, i messaggi sono rappresentati da una semplice classe, che può contenere una o più proprietà. Ecco la definizione della classe &lt;strong&gt;SampleMessage&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class SampleMessage 
{ 
    public string Name { get; set; } 
      
    public SampleMessage(string name) 
    { 
        Name = name; 
    } 
}&lt;/pre&gt;

&lt;p&gt;La classe espone una proprietà chiamata &lt;strong&gt;Name&lt;/strong&gt;, che viene valorizzata tramite una proprietà nel costruttore: in questo modo, nel ViewModel possiamo creare una nuova istanza della classe &lt;strong&gt;SampleMessage &lt;/strong&gt;passando come valore la stringa “Matteo”.&lt;/p&gt;

&lt;p&gt;A questo punto la classe &lt;strong&gt;EventAggregator&lt;/strong&gt;, che rappresenta il nostro “postino”, ha spedito il messaggio. Come facciamo a riceverlo? Dobbiamo tornare nel primo ViewModel ed effettuare alcune modifiche:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class MainPageViewModel: Screen, IHandle&amp;lt;SampleMessage&amp;gt; 
{ 
    private readonly IEventAggregator eventAggregator; 
    private readonly INavigationService navigationService; 
    private string name; 
  
    public string Name 
    { 
        get { return name; } 
        set
        { 
            name = value; 
            NotifyOfPropertyChange(() =&amp;gt; Name); 
        } 
    } 
  
    public MainPageViewModel(IEventAggregator eventAggregator, INavigationService navigationService) 
    { 
        this.eventAggregator = eventAggregator; 
        this.navigationService = navigationService; 
  
        eventAggregator.Subscribe(this); 
    } 
  
    public void GoToPage2() 
    { 
        navigationService.UriFor&amp;lt;SecondPageViewModel&amp;gt;().Navigate(); 
    } 
  
   
    public void Handle(SampleMessage message) 
    { 
        Name = message.Name; 
    } 
}&lt;/pre&gt;

&lt;p&gt;Il primo passaggio è far ereditare il ViewModel dalla classe &lt;strong&gt;IHandle&amp;lt;T&amp;gt;&lt;/strong&gt;, dove T è il tipo di messaggio che vogliamo ricevere. Nell’esempio, dato che il ViewModel della seconda pagina spedisce un messaggio d tipo &lt;strong&gt;SampleMessage&lt;/strong&gt;, lo facciamo ereditare dalla classe &lt;strong&gt;IHandle&amp;lt;SampleMessage&amp;gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Quando ereditiamo da quest’interfaccia siamo obbligati a implementare, all’interno del ViewModel, il metodo &lt;strong&gt;Handle(T message)&lt;/strong&gt;, che riceve come parametro il messaggio spedito dall’altro ViewModel. Nel nostro caso, il parametro è di tipo &lt;strong&gt;SampleMessage: &lt;/strong&gt;ecco perciò che siamo in grado di recuperare il valore della proprietà &lt;strong&gt;Name&lt;/strong&gt; del messaggio e di assegnarlo alla proprietà con lo stesso nome del ViewModel.&lt;/p&gt;

&lt;p&gt;C’è un ulteriore passaggio da mettere in atto prima di provare l’applicazione: è necessario abilitare il ViewModel alla ricezione dei messaggi. Possiamo farlo grazie al metodo &lt;strong&gt;Subscribe()&lt;/strong&gt; esposto dalla classe &lt;strong&gt;EventAggregator: &lt;/strong&gt;così come abbiamo fatto nel secondo ViewModel, dobbiamo aggiungere nel costruttore un parametro di tipo &lt;strong&gt;IEventAggregator&lt;/strong&gt; e chiamare il metodo &lt;strong&gt;Subscribe() &lt;/strong&gt;passando un riferimento al ViewModel che vogliamo registrare (dato che si tratta del ViewModel stesso, possiamo usare la parola chiave &lt;strong&gt;this&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;Il gioco è fatto! Se ora provate l’applicazione e, nella seconda pagina, premete il pulsante &lt;strong&gt;Send message&lt;/strong&gt;, dopodichè con il tasto Back tornate alla pagina precedente, troverete il nome &lt;strong&gt;Matteo&lt;/strong&gt; all’interno del controllo &lt;strong&gt;TextBox.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;Comunicazione tra la View e il ViewModel&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;In alcuni casi può sorgere la necessità di creare un canale di comunicazione tra la View e il ViewModel, per gestire le animazioni o per gestire alcune tipologie di eventi che non supportano il binding.&lt;/p&gt;

&lt;p&gt;L’approccio è lo stesso che abbiamo visto in precedenza: l’unica differenza è che, dato che si tratta di una View e non di un ViewModel, Caliburn Micro non è in grado di risolvere in automatico la dipendenza dalla classe &lt;strong&gt;IEventAggregator&lt;/strong&gt;. Non è sufficiente, perciò, aggiungere un parametro di tipo &lt;strong&gt;IEventAggregator&lt;/strong&gt; al costruttore della pagina: si scatenerà un’eccezione. Dobbiamo utilizzare, perciò, un altro approccio.&lt;/p&gt;

&lt;p&gt;Il primo passo è quello di modificare il bootstrapper, per trasformare l’oggetto di tipo &lt;strong&gt;PhoneContainer&lt;/strong&gt; (che viene utilizzata per registrare e risolvere le varie classi utilizzate nell’applicazione) in una proprietà pubblica:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class Bootstrapper : PhoneBootstrapper 
{ 
    public  PhoneContainer container { get; set; } 
  
    protected override void Configure() 
    { 
        container = new PhoneContainer(RootFrame); 
  
        container.RegisterPhoneServices(); 
        container.PerRequest&amp;lt;MainPageViewModel&amp;gt;(); 
        AddCustomConventions(); 
    } 
  
    static void AddCustomConventions() 
    { 
        //ellided   
    } 
  
    protected override object GetInstance(Type service, string key) 
    { 
        return container.GetInstance(service, key); 
    } 
  
    protected override IEnumerable&amp;lt;object&amp;gt; GetAllInstances(Type service) 
    { 
        return container.GetAllInstances(service); 
    } 
  
    protected override void BuildUp(object instance) 
    { 
        container.BuildUp(instance); 
    } 
}&lt;/pre&gt;

&lt;p&gt;Dopodichè possiamo sfruttare questa proprietà per ottenere un riferimento alla classe &lt;strong&gt;EventAggregator&lt;/strong&gt; nel costruttore del code behind della View:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;private IEventAggregator eventAggregator; 
  
// Constructor 
public MainPage() 
{ 
    InitializeComponent(); 
  
    Bootstrapper bootstrapper = Application.Current.Resources[&amp;quot;bootstrapper&amp;quot;] as Bootstrapper; 
  
    IEventAggregator eventAggregator = 
        bootstrapper.container.GetAllInstances(typeof (IEventAggregator)).FirstOrDefault() as IEventAggregator; 
  
    this.eventAggregator = eventAggregator; 
  
    eventAggregator.Subscribe(this); 
}&lt;/pre&gt;

&lt;p&gt;Come prima cosa otteniamo un riferimento al boostrapper: dato che è dichiarato come risorsa globale dell’applicazione, possiamo usare la collezione &lt;strong&gt;Application.Current.Resources.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dopodichè recuperiamo tutte gli oggetti di tipo &lt;strong&gt;IEventAggregator&lt;/strong&gt; registrati nel container, tramite il metodo&lt;strong&gt; GetAllInstances(): &lt;/strong&gt;dato che ne viene registrata solamente una istanza, recuperiamo solamente il primo risultato tramite l’operazione LINQ &lt;strong&gt;FirstOrDefault()&lt;/strong&gt;. Infine, esattamente come facevamo nel ViewModel, chiamiamo il metodo &lt;strong&gt;Subscribe() &lt;/strong&gt;della classe &lt;strong&gt;EventAggregator&lt;/strong&gt;, passando &lt;strong&gt;this&lt;/strong&gt; come parametro per abilitare la ricezione di messaggi nella pagina stessa.&lt;/p&gt;

&lt;p&gt;A questo punto siamo in grado, anche nel code behind della View, di implementare l’interfaccia &lt;strong&gt;IHandle&amp;lt;T&amp;gt;&lt;/strong&gt; e quindi implementare il metodo &lt;strong&gt;Handle()&lt;/strong&gt;, all’interno del quale gestiremo il messaggio:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public partial class MainPage : PhoneApplicationPage, IHandle&amp;lt;SampleMessage&amp;gt; 
{ 
    private IEventAggregator eventAggregator; 
  
    // Constructor 
    public MainPage() 
    { 
        InitializeComponent(); 
  
        Bootstrapper bootstrapper = Application.Current.Resources[&amp;quot;bootstrapper&amp;quot;] as Bootstrapper; 
  
        IEventAggregator eventAggregator = 
            bootstrapper.container.GetAllInstances(typeof (IEventAggregator)).FirstOrDefault() as IEventAggregator; 
  
        this.eventAggregator = eventAggregator; 
  
        eventAggregator.Subscribe(this); 
    } 
  
    public void Handle(SampleMessage message) 
    { 
        MessageBox.Show(message.Name); 
    }  
}&lt;/pre&gt;

&lt;p&gt;Se, invece, volessimo spedire un messaggio dal code behind è sufficiente chiamare il metodo &lt;strong&gt;Publish()&lt;/strong&gt; della classe &lt;strong&gt;EventAggregator&lt;/strong&gt; passando l’istanza del messaggio:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public partial class MainPage : PhoneApplicationPage 
{ 
    private IEventAggregator eventAggregator; 
  
    // Constructor 
    public MainPage() 
    { 
        InitializeComponent(); 
  
        Bootstrapper bootstrapper = Application.Current.Resources[&amp;quot;bootstrapper&amp;quot;] as Bootstrapper; 
  
        IEventAggregator eventAggregator = 
            bootstrapper.container.GetAllInstances(typeof (IEventAggregator)).FirstOrDefault() as IEventAggregator; 
  
        this.eventAggregator = eventAggregator; 
  
        eventAggregator.Subscribe(this); 
    } 
  
    private void OnSendOtherMessageClicked(object sender, RoutedEventArgs e) 
    { 
        eventAggregator.Publish(new SampleMessage(&amp;quot;Matteo&amp;quot;)); 
    } 
}&lt;/pre&gt;

&lt;p&gt;In questo esempio, alla pressione di un pulsante nell’interfaccia, viene inviato un nuovo messaggio di tipo &lt;strong&gt;SampleMessage&lt;/strong&gt;. Ovviamente, si tratta solamente di un esempio e non di uno scenario reale: in un’applicazione vera avremmo associato l’azione del pulsante ad un comando nel ViewModel tramite l’apposita convenzione.&lt;/p&gt;

&lt;p&gt;Siamo giunti al termine di questo post: non siamo ancora però giunti alla fine, sono ancora tanti gli argomenti da affrontare relativi a Caliburn Micro. Nel frattempo, potete sperimentare con il progetto di esempio allegato.&lt;/p&gt;

&lt;div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:6144e7e2-b308-4afc-b1a4-a5643e391eb6" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;p&gt; &lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/CaliburnMicro_Messaging.zip" target="_blank"&gt;Scarica il progetto di esempio&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-la-teoria"&gt;Caliburn Micro e Windows Phone – La teoria&lt;/a&gt; (3/18/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-il-primo-progetto"&gt;Caliburn Micro e Windows Phone – Il primo progetto&lt;/a&gt; (3/21/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-collezioni-e-navigazione"&gt;Caliburn Micro e Windows Phone – Collezioni e navigazione&lt;/a&gt; (3/29/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-tombstoning"&gt;Caliburn Micro e Windows Phone – Tombstoning&lt;/a&gt; (4/3/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-utilizzare-i-launcher-e-i-chooser"&gt;Caliburn Micro e Windows Phone – Utilizzare i launcher e i chooser&lt;/a&gt; (4/24/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/caliburn-micro-e-windows-phone-messaggi"&gt;&lt;strong&gt;More related document (289)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/qmatteoq/~4/ahwSQ3xSVRM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/qmatteoq/~3/ahwSQ3xSVRM/caliburn-micro-e-windows-phone-messaggi</link><author>qmatteoq</author><comments>http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-messaggi#feedback</comments><guid isPermaLink="false">http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-messaggi</guid><pubDate>Fri, 12 Apr 2013 10:00:00 GMT</pubDate><category>Windows Phone</category><category>Caliburn</category><category>MVVM</category><feedburner:origLink>http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-messaggi</feedburner:origLink></item><item><title>Sviluppare applicazioni per Windows Phone 8: presto in libreria!</title><description>&lt;p&gt;
	Come avrete notato negli ultimi mesi non sono riuscito a mantenere il mio blog aggiornato con la solita costanza. Finalmente posso svelarne il motivo: stavo scrivendo un libro &lt;img alt="Smile" class="wlEmoticon wlEmoticon-smile" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/wlEmoticon-smile_2_91.png" style="border-top-style: none; border-left-style: none; border-bottom-style: none; border-right-style: none" /&gt; Nel mercato italiano mancava ancora una guida dedicata allo sviluppo di applicazioni per Windows Phone 8: ecco perci&amp;ograve; che, grazie alla collaborazione con il blog &lt;a href="http://www.wpmitalia.com/"&gt;Windows Phone Magazine Italia&lt;/a&gt; e con Nokia, &amp;egrave; nata l&amp;rsquo;opportunit&amp;agrave; di scrivere questa guida, che vuole raccogliere un po&amp;rsquo; l&amp;rsquo;esperienza che ho accumulato in questi anni e fornire uno strumento che affronti le tematiche di sviluppo dalla A alla Z e che possa essere adatto sia ai neofiti sia a chi ha gi&amp;agrave; un po&amp;rsquo; di esperienza e vuole approfondire le novit&amp;agrave; della nuova versione.&lt;/p&gt;
&lt;p&gt;
	Nel corso delle 650 e passa pagine che compongono il volume si verr&amp;agrave; gradualmente introdotti alle basi (lo XAML, la creazione del primo progetto, il ciclo di vita delle applicazioni) per poi affrontare argomenti pi&amp;ugrave; complessi e che consentiranno di mettere in pratica la vostra creativit&amp;agrave; e fantasia (le Speech API, NFC, le live tile, ecc.)&lt;/p&gt;
&lt;p&gt;
	Il libr&amp;ograve; sar&amp;agrave; disponibile indicativamente per fine Aprile / inizio Maggio in libreria, come e-book e presso i principali distributori online, come Amazon, e sar&amp;agrave; pubblicato dalla casa editrice &lt;strong&gt;Edizioni Fag Milano&lt;/strong&gt;: mi fa molto piacere segnalare, inoltre, che il libro contiene una prefazione a cura di &lt;a href="https://twitter.com/marcoargenti"&gt;Marco Argenti&lt;/a&gt;, Senior Vice President della Developer Division di Nokia World.&lt;/p&gt;
&lt;p&gt;
	E&amp;rsquo; stato un lavoro impegnativo (soprattutto considerando che ho un lavoro regolare e quindi questo libro &amp;egrave; frutto del mio tempo libero), ma ricco di soddisfazioni: spero che chi di voi lo acquister&amp;agrave; lo trovi interessante tanto quanto &amp;egrave; stato piacevole per me scriverlo!&lt;/p&gt;
&lt;p&gt;
	Sar&amp;agrave; mia premura tenervi aggiornati, attraverso questo blog, sulla disponibilit&amp;agrave; e sul prezzo finale una volta che mi saranno comunicati.&lt;/p&gt;
&lt;p&gt;
	&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/image_5_1.png"&gt;&lt;img alt="image" border="0" height="549" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/image_thumb_1_9.png" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" title="image" width="389" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/lo-speciale-di-aspitalia-sulle-novita-per-gli-sviluppatori-di-windows-phone-8"&gt;Lo speciale di ASPItalia sulle novità per gli sviluppatori di Windows Phone 8&lt;/a&gt; (10/31/2012)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/windows-phone-8-e-finalmente-realta"&gt;Windows Phone 8 è finalmente realtà!&lt;/a&gt; (10/30/2012)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/il-mio-primo-articolo-cartaceo-con-qualche-rettifica"&gt;Il mio primo articolo cartaceo… con qualche rettifica!&lt;/a&gt; (9/5/2012)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/il-libro-di-aspitalia-sullo-sviluppo-di-applicazioni-windows-phone"&gt;Il libro di ASPItalia sullo sviluppo di applicazioni Windows Phone&lt;/a&gt; (6/23/2011)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/windows-phone-developers-tools-beta"&gt;Windows Phone Developers Tools Beta&lt;/a&gt; (7/13/2010)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/supportare-i-dispositivi-windows-phone-8-da-unapplicazione-windows-phone-7.x"&gt;Supportare i dispositivi Windows Phone 8 da un’applicazione Windows Phone 7.x&lt;/a&gt; (12/17/2012)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/sviluppare-applicazioni-per-windows-phone-8-presto-in-libreria"&gt;&lt;strong&gt;More related document (288)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/qmatteoq/~4/4u23CQyBktE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/qmatteoq/~3/4u23CQyBktE/sviluppare-applicazioni-per-windows-phone-8-presto-in-libreria</link><author>qmatteoq</author><comments>http://www.qmatteoq.com/blog/post/sviluppare-applicazioni-per-windows-phone-8-presto-in-libreria#feedback</comments><guid isPermaLink="false">http://www.qmatteoq.com/blog/post/sviluppare-applicazioni-per-windows-phone-8-presto-in-libreria</guid><pubDate>Thu, 11 Apr 2013 11:05:00 GMT</pubDate><category>Windows Phone</category><feedburner:origLink>http://www.qmatteoq.com/blog/post/sviluppare-applicazioni-per-windows-phone-8-presto-in-libreria</feedburner:origLink></item><item><title>Caliburn Micro e Windows Phone – Navigazione avanzata e deep link</title><description>&lt;p&gt;In uno dei post precedenti abbiamo visto come gestire la navigazione in un’applicazione sviluppata con il pattern MVVM sfruttando le funzionalità di Caliburn Micro. In qesto post approfondiremo l’argomento, trattando una serie di scenari più avanzati, come la gestione degli eventi navigazione e il supporto ai deep link, uno dei meccanismi più utilizzati dalle API di Windows Phone per il passaggio di parametri.&lt;/p&gt;  &lt;h3&gt;Deep link&lt;/h3&gt;  &lt;p&gt;Windows Phone ha sempre supportato, sin dalla prima versione, la possibilità di passare parametri da una pagina all’altra tramite le query string che vengono aggiunte all’url di navigazione. Windows Phone 7.5 ha introdotto il concetto di deep link, ovvero la possibilità di sfruttare lo stesso meccanismo anche dall’esterno: il sistema operativo è in grado di aprire un’applicazione specificando sia la pagina a cui portare direttamente l’utente, sia eventuali parametri che aiutino lo sviluppatore a identificare il contesto della richiesta.&lt;/p&gt;  &lt;p&gt;Ci sono tanti esempi di questo meccanismo: quando creiamo una tile secondaria, utilizziamo un deep link per identificare quale tile è stata selezionata; quando inviamo una notifica toast siamo in grado di specificare un deep link, per gestire il tap dell’utente sulla stessa; le nuove API di Windows Phone 8 per il supporto ai comandi vocali usano un deep link per passare all’applicazione il comando pronunciato dall’utente.&lt;/p&gt;  &lt;p&gt;In condizioni normali, intercettare questa informazione in un’applicazone sviluppata utilizzando il pattern MVVM non è banale, dato che comporta due passaggi:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Intercettare l’evento &lt;strong&gt;OnNavigatedTo()&lt;/strong&gt;, che viene scatenato quando l’utente viene portato alla pagina corrente; &lt;/li&gt;    &lt;li&gt;Utilizzare la classe &lt;strong&gt;NavigationContext&lt;/strong&gt; per accedere all’url di navigazione e ai relativi parametri in query string. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Purtroppo, però, sono API che sono accessibili solamente dal code behind di una View, in quanto eredita dalla classe &lt;strong&gt;PhoneApplicationPage&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Fortunatamente Caliburn Micro espone una convenzione molto semplice per gestire per noi questo scenario: è sufficiente dichiarare una proprietà nel ViewModel con lo stesso nome del parametro in query string; Caliburn Micro si occuperà di iniettare automaticamente, in tale proprietà, il valore recuperato dal parametro in query string.&lt;/p&gt;  &lt;p&gt;Proviamo a implementare questo meccanismo utilizzando un’applicazione standard che faccia uso di Caliburn Micro: definiamo una View e un ViewModel e colleghiamoli utilizzando la convenzione standard, dopodichè nello XAML aggiungiamo un pulsante per creare una tile secondaria e un controllo &lt;strong&gt;TextBlock &lt;/strong&gt;per mostrare il valore recuperato dalla query string:&lt;/p&gt;  &lt;pre class="brush: xml;"&gt;&amp;lt;StackPanel&amp;gt;
    &amp;lt;TextBlock Text=&amp;quot;{Binding Name}&amp;quot; /&amp;gt;
    &amp;lt;Button Content=&amp;quot;Create secondary tile&amp;quot; x:Name=&amp;quot;CreateTile&amp;quot; /&amp;gt;
&amp;lt;/StackPanel&amp;gt;&lt;/pre&gt;

&lt;p&gt;Ecco, invece, il relativo ViewModel:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class MainPageViewModel: PropertyChangedBase
{
    private string name;
 
    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            NotifyOfPropertyChange(() =&amp;gt; Name);
        }
    }
 
    public void CreateTile()
    {
                    ShellTileData tile = new StandardTileData
                                     {
                                         Title = &amp;quot;Test&amp;quot;,
                                     };
 
            ShellTile.Create(new Uri(&amp;quot;/Views/MainPage.xaml?Name=Matteo&amp;quot;, UriKind.Relative), tile);
    }
 
}&lt;/pre&gt;

&lt;p&gt;Nel ViewModel abbiamo definito una proprietà di nome &lt;strong&gt;Name &lt;/strong&gt;che, grazie all’utilizzo della convenzione di Caliburn, sarà mostrata all’interno del controllo &lt;strong&gt;TextBlock&lt;/strong&gt;. Sempre utilizzando le onvenzioni, facciamo sì che alla pressione del pulsante venga eseguito il metodo&lt;strong&gt; CreateTile()&lt;/strong&gt;, il quale si occupa di creare una nuova tile secondaria valorizzandone semplicemente il titolo. Potete notare che, nella creazione della tile, passiamo un deep link che contiene un parametro di nome &lt;strong&gt;Name&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ora lanciate l’applicazione e premete il pulsante per creare la tile secondaria: l’applicazione sarà chiusa, per mostrare direttamente la nuova tile nella home. Fateci tap sopra e.. voilà! Il valore del parametro &lt;strong&gt;Name &lt;/strong&gt;(ovvero &lt;strong&gt;Matteo&lt;/strong&gt;) sarò visualizzato all’interno del controllo &lt;strong&gt;TextBlock&lt;/strong&gt;, grazie alla convenzione di Caliburn.&lt;/p&gt;

&lt;h3&gt;Intercettare gli eventi di navigazione&lt;/h3&gt;

&lt;p&gt;Spesso abbiamo la necessità di intercettare gli eventi che il runtime ci mette a disposizione per capire quando l’utente si sta spostando da e verso una pagina. Ad esempio, se vogliamo che i dati della nostra pagina siano ricaricati ogni volta che l’utente ci arriva, non possiamo affidarci al costruttore del ViewModel, perchè questi viene inizializzato solo la prima volta che la pagina viene richiesta (pensiamo ad esempio alla pagina principale che, essendo la prima, rimane sempre in vita fino a che l’applicazione non viene chiusa).&lt;/p&gt;

&lt;p&gt;Così come ho ricordato all’inizio del post, si tratta di uno scenario complesso da gestire in un’applicazione che fa uso di MVVM, data che gli eventi &lt;strong&gt;OnNavigatedTo() &lt;/strong&gt;e&lt;strong&gt; OnNavigatedFrom()&lt;/strong&gt; non sono accessibili dal ViewModel. A questo scopo, Caliburn Micro mette a disposizione una classe da utilizzare all’interno dei ViewModel, che permette di agganciarsi agli stessi eventi a cui normalmente siamo in grado di accedere solamente dal code behind. La classe si chiama &lt;strong&gt;Screen&lt;/strong&gt; e, per utilizzarla, è sufficiente far ereditare il ViewModel dalla stessa.&lt;/p&gt;

&lt;p&gt;La classe &lt;strong&gt;Screen&lt;/strong&gt; implementa una serie piuttoto nutrita di intefacce, che ci permettono di gestire gli eventi di navigazione, come &lt;strong&gt;ViewAware, IActivate&lt;/strong&gt; e &lt;strong&gt;IDeactivated&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class Screen : ViewAware, IScreen, IHaveDisplayName, IActivate, IDeactivate, IGuardClose, IClose, INotifyPropertyChangedEx, INotifyPropertyChanged, IChild
{
 
}&lt;/pre&gt;

&lt;pre class="brush: csharp;"&gt;&lt;font face="Calibri"&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;In più, come potete vedere, la classe &lt;strong&gt;Screen&lt;/strong&gt; implementa anche l’interfaccia &lt;strong&gt;INotifyPropertyChanged&lt;/strong&gt;, di conseguenza non abbiamo la necessità di far ereditare il nostro ViewModel anche dalla classe &lt;strong&gt;PropertyChangedBase, &lt;/strong&gt;avremo comunque accesso all’evento &lt;strong&gt;NotifyOfPropertyChange()&lt;/strong&gt;, indispensabile per supportare il binding.&lt;/p&gt;

&lt;p&gt;Una volta che il ViewModel è opportunamente configurato, possiamo fare l’override di una serie di metodi per gestire i vari eventi di navigazione:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class MainPageViewModel: Screen
{
    protected override void OnViewAttached(object view, object context)
    {
        base.OnViewAttached(view, context);
        Debug.WriteLine(&amp;quot;OnViewAttached&amp;quot;);
    }
 
    protected override void OnInitialize()
    {
        base.OnInitialize();
        Debug.WriteLine(&amp;quot;OnInitialize&amp;quot;);
    }
 
    protected override void OnViewReady(object view)
    {
        base.OnViewReady(view);
        Debug.WriteLine(&amp;quot;OnViewReady&amp;quot;);
    }
 
    protected override void OnActivate()
    {
        base.OnActivate();
        Debug.WriteLine(&amp;quot;OnActivate:&amp;quot;);
    }
 
    protected override void OnViewLoaded(object view)
    {
        base.OnViewLoaded(view);
        Debug.WriteLine(&amp;quot;OnViewLoaded&amp;quot;);
    }
 
    protected override void OnDeactivate(bool close)
    {
        base.OnDeactivate(close);
        Debug.WriteLine(&amp;quot;OnDeactivate&amp;quot;);
    }
}&lt;/pre&gt;

&lt;p&gt;Ecco una descrizione dei vari metodi disponibili:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;OnViewAttached() &lt;/strong&gt;viene eseguito nel momento in cui il ViewModel viene impostato come DataContext della View; &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;OnInitialize()&lt;/strong&gt; viene eseguito quando la View viene caricata; &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;OnViewReady()&lt;/strong&gt; viene eseguito quando la View è pronta per essere visualizzata; &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;OnViewLoaded()&lt;/strong&gt; è chiamato quando la View è stata completamente caricata e tutti i controlli sono stati inizializati; &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;OnActivate()&lt;/strong&gt; è chiamato quando la View viene visualizzata; &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;OnDeactivate()&lt;/strong&gt; è chiamato ogni qualvolta ci spostiamo dalla View corrente; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I due eventi più importanti sono &lt;strong&gt;OnActivate() &lt;/strong&gt;e &lt;strong&gt;OnDeactivate()&lt;/strong&gt;, che corrispondono a &lt;strong&gt;OnNavigatedTo()&lt;/strong&gt; e &lt;strong&gt;OnNavigatedFrom()&lt;/strong&gt; esposti dalla pagina: potete utilizzarli per gestire operazioni che non possono essere automatizzate tramite gli helper e le convenzioni di Caliburn Micro.&lt;/p&gt;

&lt;p&gt;Nello specifico, l’evento &lt;strong&gt;OnActivate() &lt;/strong&gt;è molto importante perchè viene scatenato quando la View è stata completamente caricata e siete in grado di interagire con la stessa: ad esempio, tale evento può essere utilizzato per caricare i dati da mostrare all’interno della View. Pensate al tipico approccio nella definizione di un ViewModel: tipicamente si gestisce, nel costruttore del ViewModel, il caricamento dei dati. Questo approccio ha però un limite, evidente soprattutto al giorno d’oggi con l’introduzione delle parole chiave &lt;strong&gt;async &lt;/strong&gt;e &lt;strong&gt;await &lt;/strong&gt;per gestire le operazioni asincrone. Il costruttore di una classe, infatti, non può essere asincrono. Solitamente si usa l’approccio di demandare l’operazione di caricamento ad un altro metodo, che viene invocato nel costruttore:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public MainPageViewModel()
{
    LoadData();
}
 
private async void LoadData()
{
    MyData = await service.LoadData();
}&lt;/pre&gt;

&lt;p&gt;Qual è il problema di questa soluzione? Che il metodo &lt;strong&gt;LoadData() &lt;/strong&gt;deve essere di tipo &lt;strong&gt;void&lt;/strong&gt;, non può ritornare un &lt;strong&gt;Task&lt;/strong&gt; dato che nel costruttore del ViewModel non possiamo usare la parola chiave &lt;strong&gt;await&lt;/strong&gt;. Il problema è che, in questo metodo, il metodo &lt;strong&gt;LoadData()&lt;/strong&gt; è di tipo “fire and forget”: eseguiamo l’operazione e non aspettiamo che questa sia terminata. In più, non siamo in grado di catturare eventuali eccezioni. Nella maggior parte dei casi questo approccio funzionerà comunque, soprattutto se i dati da caricare non sono molti: prima che l’utente inizi ad interagire con l’interfaccia, i dati saranno probabilmente già pronti per essere consumati.&lt;/p&gt;

&lt;p&gt;Un approccio più efficiente è quello di sfruttare gli eventi di navigazione, spostando il caricamento dei dati all’interno del metodo &lt;strong&gt;OnActivate()&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public MainPageViewModel()
{
 
}
 
protected override async void OnActivate()
{
    MyData = await service.LoadData();
} &lt;/pre&gt;

&lt;p&gt;In questo caso è corretto che il metodo &lt;strong&gt;OnActivate()&lt;/strong&gt; sia di tipo void, perchè le operazioni di attivazione vengono gestite in automatico dal sistema operativo. E’ lo stesso tipo di approccio che, ad esempio, si utilizza con gli event handler che Visual Studio genera quando vogliamo gestire il click di un pulsante (o qualsiasi altro evento esposto da uno dei controlli nello XAML) da code behind.&lt;/p&gt;

&lt;p&gt;Il metodo &lt;strong&gt;OnActivate()&lt;/strong&gt; è molto importante anche per la gestione dei deep link che abbiamo visto in precedenza: infatti si può verificare che, quando il ViewModel viene creato e il costruttore della classe invocato, i parametri presenti in query string non siano ancora stati iniettati nelle corrispondenti proprietà.&lt;/p&gt;

&lt;p&gt;Questo perchè l’evento &lt;strong&gt;OnNavigatedTo()&lt;/strong&gt; della pagina, che viene sfruttato per recuperare i parametri e iniettarli nel ViewModel, si verifica dopo che il costruttore della classe è già stato eseguito. Nell’esempio che abbiamo fatto in precedenza non abbiamo avuto modo di accorgerci del problema grazie al binding e all’implementazione dell’interfaccia &lt;strong&gt;INotifyPropertyChanged: &lt;/strong&gt;nel momento in cui Caliburn ha valorizzato le proprietà del ViewModel con i parametri in query string, grazie al binding il controllo &lt;strong&gt;TextBlock&lt;/strong&gt; si è immediatamente aggiornato per mostrare il nuovo valore.&lt;/p&gt;

&lt;p&gt;Avremmo potuto, invece, notare il problema se avessimo cercato di manipolare la proprietà &lt;strong&gt;Name&lt;/strong&gt; all’interno del costruttore del ViewModel: in tal caso, ci saremmo accorti che la proprietà &lt;strong&gt;Name&lt;/strong&gt; sarebbe stata uguale a &lt;strong&gt;null&lt;/strong&gt;. Il codice seguente avrebbe perciò scatenato un’eccezione:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class MainPageViewModel: PropertyChangedBase
{
    private string name;
 
    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            NotifyOfPropertyChange(() =&amp;gt; Name);
        }
    }
 
    public MainPageViewModel()
    {
        MessageBox.Show(Name);    
    }
 
}&lt;/pre&gt;

&lt;p&gt;La soluzione è quella di manipolare la proprietà &lt;strong&gt;Name&lt;/strong&gt; all’interno dell’evento &lt;strong&gt;OnActivate()&lt;/strong&gt;: in questo modo, ci assicuriamo che il lavoro di Caliburn sia stato completato e che la proprietà contenga effettivamente il valore del parametro contenuto all’interno del deep link. Ecco il codice corretto:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class MainPageViewModel: Screen
{
    private string name;
 
    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            NotifyOfPropertyChange(() =&amp;gt; Name);
        }
    }
 
    public void OnActivate()
    {
        MessageBox.Show(Name);
    }
 
}&lt;/pre&gt;

&lt;p&gt;Come sempre, di seguito trovate il link per scaricare il progetto di esempio relativo a quanto appreso in questo post.&lt;/p&gt;

&lt;div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:b9fc259c-7fdf-49e5-be9c-717c46a0bc0c" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;p&gt; &lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/CaliburnMicro_AdvancedNavigation.zip" target="_blank"&gt;Scarica il progetto di esempiio&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-la-teoria"&gt;Caliburn Micro e Windows Phone – La teoria&lt;/a&gt; (3/18/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-il-primo-progetto"&gt;Caliburn Micro e Windows Phone – Il primo progetto&lt;/a&gt; (3/21/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-collezioni-e-navigazione"&gt;Caliburn Micro e Windows Phone – Collezioni e navigazione&lt;/a&gt; (3/29/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-tombstoning"&gt;Caliburn Micro e Windows Phone – Tombstoning&lt;/a&gt; (4/3/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-messaggi"&gt;Caliburn Micro e Windows Phone – Messaggi&lt;/a&gt; (4/12/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-utilizzare-i-launcher-e-i-chooser"&gt;Caliburn Micro e Windows Phone – Utilizzare i launcher e i chooser&lt;/a&gt; (4/24/2013)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/caliburn-micro-e-windows-phone-navigazione-avanzata-e-deep-link"&gt;&lt;strong&gt;More related document (288)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/qmatteoq/~4/1bCI4z8PQE0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/qmatteoq/~3/1bCI4z8PQE0/caliburn-micro-e-windows-phone-navigazione-avanzata-e-deep-link</link><author>qmatteoq</author><comments>http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-navigazione-avanzata-e-deep-link#feedback</comments><guid isPermaLink="false">http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-navigazione-avanzata-e-deep-link</guid><pubDate>Mon, 08 Apr 2013 11:00:00 GMT</pubDate><category>Windows Phone</category><category>MVVM</category><category>Caliburn</category><feedburner:origLink>http://www.qmatteoq.com/blog/post/caliburn-micro-e-windows-phone-navigazione-avanzata-e-deep-link</feedburner:origLink></item></channel></rss>
