Migrare le proprie applicazioni Windows 8 alla RTM

Print Content | More

Con l’uscita delle versioni RTM di Windows 8 e Visual Studio 2012 è giunto il momento di testare nuovamente le vostre applicazioni Windows 8 e verificare che queste funzionino regolarmente anche con la versione finale della piattaforma.

L’impatto con la RTM è molto meno drastico che in passato: se con il passaggio dalla Consumer Preview alla Release Preview avevo dovuto apportare parecchie modifiche, questa volta è filato tutto liscio e la compilazione è andata a buon fine al primo colpo.

Vi segnalo solo due cose da tenere a mente.

Aggiornare il file di manifest

Grazie a Daniele Bochicchio ho scoperto che il file di manifest di Windows 8 (Package.appxmanifest) contiene un riferimento alla versione del sistema operativo per la quale è compilata l’applicazione. Nel caso di applicazioni realizzate con la Release Preview, il valore di riferimento sarà 6.2.0, che però non viene aggiornato in automatico nel momento in cui aprite il progetto con la RTM di Visual Studio 2012.

Dovete perciò modificare il file manualmente:

  • Da Visual Studio fate clic con il tasto destro sul file Package.appxmanifest e scegliete View code
  • Troverete una sezione del file XML chiamata Prerequisites
<Prerequisites>
  <OSMinVersion>6.2.0</OSMinVersion>
  <OSMaxVersionTested>6.2.0</OSMaxVersionTested>
</Prerequisites>
  • Cambiate il valore 6.2.0 contenuto nei due nodi in 6.2.1, nel seguente modo:
<Prerequisites>
  <OSMinVersion>6.2.1</OSMinVersion>
  <OSMaxVersionTested>6.2.1</OSMaxVersionTested>
</Prerequisites>
Senza questa modifica, la vostra applicazione girerà in una Release Preview Compatibility Mode e non sarà in grado di sfruttare le novità e le modifiche che sono state apportate nella RTM di Windows 8. Nota bene: l’utilizzo di questa compatibility mode non pregiudicherà la certificazione della vostra applicazione, ma è comunque meglio effettuare subito la modifica e assicurarsi che tutto funzioni regolarmente.

Vi suggerisco, infine, la lettura di questo documento realizzato da Microsoft, dedicato alla migrazione delle applicazioni dalla Release Preview alla RTM, con l’indicazione di tutte le modifiche che sono state apportate alle API e ai controlli.

Unable to activate Windows Store application: the app didn’t start

Dopo aver aperto il vostro progetto con Visual Studio 2012 e averlo ricompilato, potreste avere una brutta sorpresa al primo tentativo di avvio: una schermata di errore con il messaggio

Unable to activate Windows Store application. The activation request failed with error ‘The app didn’t start’

In tal caso, la soluzione è molto semplice: chiudete Visual Studio e cancellate le cartelle bin e obj all’interno della vostra soluzione. Riaprite il progetto e questa volta riuscirete a fare il deploy correttamente.


Windows 8 , Microsoft

1 comments

Attivare Windows 8 RTM e testare le proprie applicazioni

Print Content | More

A partire dalle 19 di ieri sera, per chi ha un abbonamento MSDN o TechNet, sono finalmente disponibili le versioni RTM (ovvero quelle finali, uguali in tutto e per tutto a quelle che saranno vendute nei negozi a partire da Ottobre) di Windows 8 e Visual Studio 2012.

La notizia era stata diffusa già da diversi giorni e sono tanti gli sviluppatori che ieri hanno “intasato” i server Microsoft per poter scaricare e installare la nuova versione di Windows.

In questo post non mi soffermerò troppo su Windows 8 in sè, non si tratta in realtà di una novità in senso assoluto, grazie alle preview di questi mesi abbiamo già avuto modo di conoscerlo, imparare ad usarlo e a sviluppare applicazioni. La RTM porta semplicemente “a compimento” quanto avevamo già avuto modo di utilizzare, offrendo un ambiente ancora più stabile e includendo tutti i ritocchi finali che erano stati annunciati negli ultimi mesi (come l’assenza di Aero nel desktop).

Vi segnalo però due informazioni importanti.

Attivare Windows 8

Potreste incappare in qualche spiacevole sorpresa nel tentativo di attivare la vostra versione di Windows: molte persone (me compreso) hanno infatti ricevuto l’errore DNS Name does not exist. Grazie a Simone Viganò (MVP nella categoria Windows Expert-Consumer) esiste un trucco per aggirare il problema.

  1. Aprite un prompt dei comandi con permessi di amministratore
  2. Digitate il comando  slmgr /ipk seguito dal product key che avete ottenuto su MSDN (ad esempio,  slmgr /ipk xxxxx-xxxxx-xxxxx-xxxxx-xxxxx)
  3. Eseguite nuovamente l’attivazione

Questa volta l’operazione andrà a buon fine e potrete sfruttare tutte le potenzialità di Windows 8 (ad esempio, le opzioni di personalizzazione della UI sono bloccate fino a che il sistema operativo non viene attivato).

E se non ho un abbonamento MSDN o TechNet?

Da questo momento, se avete un account sullo Store, potete iniziare a fare il submit delle vostre applicazioni, che però devono essere compilate con la RTM di Windows 8 e Visual Studio 2012. Il problema è che, se non siete in possesso di un abbonamento MSDN o TechNet, dovreste aspettare il 26 Ottobre (data di rilascio al pubblico di Windows 8) per poterlo fare: per venire incontro agli sviluppatori che si trovano in questa situazione Microsoft ha rilasciato una versione evaluation di Windows 8, della validità di 90 giorni, completa di tutte le funzionalità. E’ richiesta solo la registrazione tramite un Microsoft account. Potete perciò scaricarla da questa pagina, installarla e usarla per testare e compilare la vostra applicazione Windows 8 prima di inviarla allo store.

Unico svantaggio: la versione di prova non è in alcun modo aggiornabile ad una versione completa, quindi quando acquisterete la vostra copia di Windows 8 il 26 Ottobre sarete costretti a reinstallarla. Il consiglio, perciò, è quello di usare ad esempio una macchina virtuale e o una partizione separata, e di non usare la versione di prova come sistema operativo principale.

Buona installazione!


Windows 8 , Microsoft

0 comments

MVVM e Windows Phone – I command (5° parte)

Print Content | More

Ci siamo lasciati nel post precedente con una domanda: “Come faccio a gestire le interazioni dell’utente con la mia applicazione?”. L’approccio a cui siamo abituati, utilizzando il code behind, è tramite gli event handler: i vari controlli in grado di gestire l’interazione dell’utente (come i Button) espongono una serie di eventi (come Tap o Click), che possiamo sottoscrivere nel code behind per gestirli. Ad esempio, per gestire l’evento Click di un pulsante nello XAML dovremmo dichiarare il nome del metodo da invocare come nell’esempio:

<Button Content="Click me" Click="Button_Click" />

In questo modo Visual Studio genererà per noi un metodo nel code behind per gestire l’evento:

private void Button_Click(object sender, RoutedEventArgs e)
{
    // do something
}

Questo approccio però non può funzionare nel pattern MVVM, perchè il ViewModel non ha un accesso diretto alla View e quindi non può referenziarsi direttamente al controllo Button e gestire l’evento. Per questo motivo lo XAML mette a disposizione i Command, che rappresentano i comandi che vengono eseguiti quando l’utente interagisce con il controllo (in quelli che ereditano dalla classe ButtonBase si traduce nella pressione dello stesso).

La differenza rispetto ad un event handler è che il command è un oggetto, che implementa l’interfaccia ICommand. Essendo un oggetto, è possibile collegarlo alla proprietà Command del controllo tramite binding e, di conseguenza, possiamo definirlo all’interno del ViewModel.

I vari toolkit dedicati a MVVM contengono solitamente un’implementazione dell’interfaccia ICommand da utilizzare: MVVM Light non fa eccezione e offre la classe RelayCommand. Vediamo come utilizzarla per gestire il click di un pulsante. Ecco l’esempio di un RelayCommand definito nel ViewModel:

private RelayCommand _buttonClick;

public RelayCommand ButtonClick
{
    get
    {
        return _buttonClick
            ?? (_buttonClick = new RelayCommand(
                                  () =>
                                      {
                                          MessageBox.Show("Button clicked!");
                                      }));
    }
}

Nel momento in cui viene creata l’istanza della classe del RelayCommand dobbiamo passare come parametro la funzione da eseguire allo scatenarsi dell’evento sotto forma di Action: nell’esempio utilizziamo il meccanismo degli anonymous delegate, ma nulla vieta di dichiarla separatamente.

A questo punto il collegamento con la view è molto semplice e segue lo stesso meccanismo che abbiamo visto in precedenza per le proprietà semplici: dobbiamo associare tramite binding la proprietà ButtonClick alla proprietà Command del controllo Button, come nell’esempio.

<Button Content="Click me" Command="{Binding Path=ButtonClick}" />

Il gioco è fatto: alla pressione del pulsante la funzione dichiarata nel RelayCommand sarà eseguita e verrà mostrato a video il messaggio.

Command con parametri

Può capitare la necessità di passare un parametro di input al comando come, ad esempio, il valore della proprietà di un altro controllo. Per questo scopo esiste una variante della classe RelayCommand, definita come RelayCommand<T>, dove T è il tipo di oggetto che viene passato come parametro. La definizione del RelayCommand diventa quindi la seguente:

private RelayCommand<string> _buttonClickedWithParameter;

public RelayCommand<string> ButtonClickedWithParameter
{
    get
    {
        return _buttonClickedWithParameter
            ?? (_buttonClickedWithParameter = new RelayCommand<string>(
                                  p =>
                                      {
                                          MessageBox.Show(p);
                                      }));
    }
}

L’unica differenza rispetto a prima è che la funzione da eseguire non è più una Action, ma una Action<T>, dove T è il parametro che è stato passato all’oggetto. Nell’esempio, il comando ButtonClickedWithParameter accetta un parametro di tipo string, che viene reso disponibile alla funzione nella dichiarazione dell’anonymous method (l’oggetto p).

Per passare il parametro al comando tramite lo XAML si utilizza la proprietà CommandParameter del controllo, in combinazione con la proprietà Command per associare il comando, come nell’esempio:

<Button Content="Click me with parameter" Command="{Binding Path=ButtonClickedWithParameter}" CommandParameter="Clicked" />

Nell’esempio il parametro che viene passato al comando è il testo Clicked, che viene poi recuperato dalla funzione e mostrato a video tramite una MessageBox.

I command e la funzione CanExecute

L’oggetto RelayCommand supporta un secondo parametro opzionale, oltre alla funzione da eseguire quando il comando viene eseguito: si tratta della funzione CanExecute, che permette di determinare se il comando deve essere abilitato o meno. Si tratta di una funzionalità molto interessante, perchè, anche visivamente, il controllo si comporterà di conseguenza in base al valore di questa funzione: se il comando è disabilitato, anche il pulsante apparirà disattivato e quindi l’utente non potrà cliccarci sopra.

L’utilizzo è piuttosto semplice: dobbiamo passare come parametro una funzione che restituisca un valore booleano. Quando questo è a true, il pulsante è abilitato e il comando può essere eseguito; quando è a false, invece, il pulsante è disabilitato.

L’oggetto RelayCommand espone poi il metodo RaiseCanExecuteChanged, da invocare ogni qualvolta abbiamo fatto una modifica che comporta una variazione nella funzione e, di conseguenza, un possibile cambiamento nello stato del pulsante.

Vediamo come mettere insieme tutti questi concetti in un esempio concreto: realizziamo un pulsante che viene attivato solo quando un controllo di tipo CheckBox è stato abilitato.

Nel ViewModel andiamo ad inserire una nuova proprietà, che sarà messa in binding con la proprietà IsChecked del controllo CheckBox.

private bool _isChecked;

public bool IsChecked
{
    get { return _isChecked; }
    set
    {
        if (_isChecked != value)
        {
            _isChecked = value;
            RaisePropertyChanged(() => IsChecked);
        }
    }
}

Dopodichè andiamo a creare un RelayCommand che viene inizializzato con due parametri: il primo è la funzione da eseguire, il secondo quella da valutare per determinare se il comando deve essere attivo o meno.

private RelayCommand _buttonClickedCanExecute;

public RelayCommand ButtonClickedCanExecute
{
    get
    {
        return _buttonClickedCanExecute
               ?? (_buttonClickedCanExecute = new RelayCommand(
                                                  () =>
                                                      {
                                                          MessageBox.Show("Clicked");
                                                      },
                                                  () =>
                                                      {
                                                          return IsChecked;
                                                      }
                                                  ));
    }
}

 

La funzione CanExecute deve ritornare un valore booleano, facciamo ritornare perciò direttamente il valore della proprietà IsChecked. Ora possiamo collegare i controlli nello XAML con le proprietà del view model che abbiamo definito:

<Button Content="Click me with can execute" Command="{Binding Path=ButtonClickedCanExecute}" />
<CheckBox Content="Enable button" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" />

Come vedete, allo XAML la funzione CanExecute è completamente trasparente: il comando ButtonClickedCanExecute è semplicemente in binding con la proprietà Command del controllo Button.

Manca un ultimo passaggio: dobbiamo comunicare al RelayCommand quando la funzione CanExecute deve essere nuovamente valutata (nel nostro esempio, deve essere verificato se la proprietà IsChecked è cambiata). Per farla andiamo a chiamare il metodo RaiseCanExecuteChanged ogni qualvolta il valore della proprietà IsChecked cambia. Di conseguenza, ecco come diventerà la sua dichiarazione nel ViewModel:

private bool _isChecked;

public bool IsChecked
{
    get { return _isChecked; }
    set
    {
        if (_isChecked != value)
        {
            _isChecked = value;
            RaisePropertyChanged(() => IsChecked);
            ButtonClickedCanExecute.RaiseCanExecuteChanged();
        }
    }
}

Lanciando il progetto di test che accompagna questo post potete vedere il codice all’opera:

screenshot1screenshot2

In conclusione

Con questo possiamo considerare concluse le “basi” necessarie per comprendere e applicare il pattern MVVM. Più avanti vedremo qualche scenario avanzato per approfondire la conoscenza acquisita: ad esempio, come gestire la navigazione tra pagine o come usare la dependency injection per risolvere le dipendenze dei view model.


Windows Phone , MVVM

2 comments

Goodbye AppHub, welcome Windows Phone Dev Center

Print Content | More

image

“Interrompo” la pubblicazione dei post dedicati a MVVM per segnalare una notizia molto importante: nella giornata di ieri AppHub è stato fuori uso per diverse ore per una manutenzione programmata. Una volta tornato online, sono molte le novità che si sono presentate ai visitatori.

La prima che salta subito all’occhio è la separazione in due portali separati: se una volta AppHub era il portale unico di gestione sia per le applicazioni Windows Phone che per i giochi XBox, ora i due siti sono stati separati, dando origine al Windows Phone Dev Center, il cui nuovo indirizzo è https://dev.windowsphone.com

La seconda novità immediatamente visibile è il nuovo restilying grafico e architetturale: dal punto di vista dell’interfaccia, la dashboard per la gestione della pubblicazioni delle applicazioni è stata rinnovata e ora è in grado di mostrare più informazioni. Anche il “core” del portale ha subito una completa riscrittura, con lo scopo di risolvere tutti i bug e i problemi di latenza e disponibilità riscontrati nei mesi precedente.

Di conseguenza, anche il flusso di pubblicazione di un’applicazione è totalmente diverso rispetto al precedente: a breve pubblicherò un post dettagliato per spiegare la nuova procedura.

Per ora vediamo più genericamente alcune delle novità, che sono state annunciate direttamente dal team tramite un post sul blog ufficiale.

Migliorato il sistema di pagamento

Uno degli aspetti che ha beneficiato maggiormente di questo restyiling è la parte dedicata ai pagamenti, con una serie di novità che faranno felici molti sviluppatori. La prima è l’aggiunta del supporto a Paypal, sia come metodo di pagamento per l’acquisto della sottoscrizione annuale, sia come metodo di riscossione per ricevere gli introiti dalla vendita delle proprie applicazioni.

Un’altra novità molto gradita riguarda le pratiche burocratiche necessarie a ricevere i pagamenti: il portale è ora dotato di un comodo wizard che si occupa di generare e inviare in automatico, in maniera elettronica, il modulo W-8 (relativo al pagamento delle tasse per le persone non residenti negli Stati Uniti). In passato, invece, la procedura era molto più complessa e richiedeva l’invio di diversi documenti legali negli Stati Uniti tramite posta.

E’ possibile che, se avevate già compilato la sezione dedicata al pagamento delle tasse, le informazioni da voi inserite siano andate perdute. In tal caso, dovete ripetere la procedura usando il nuovo wizard automatico.

Un’altra novità importante è la possibilità di impostare fasce di prezzo diverse a seconda del paese, mentre in passato era possibile selezionare un unico prezzo, che veniva poi automaticamente convertito nelle varie valute.

Infine, è stata attivata l’infrastruttura necessaria per gestire l’in-app purchase, ovvero la possibilità di effettuare acquisti direttamente dall’applicazione: si tratta di una delle novità che farà parte di Windows Phone 8.

Novità nei report

Anche la parte di reportistica è stata migliorata, tramite l’aggiunta di molte più informazioni rispetto al passato: ad esempio, adesso siamo in grado di filtrare le statistiche sui download anche per tipologia (Beta, Trial o A Pagamento).

E’ stata aggiunta inoltre una nuova sezione chiamata My Money, che racchiude tutti i record relativi ai pagamenti e ai soldi guadagnati tramite la vendita delle proprie applicazioni.

Novità nei meccanismi di distribuzione

Anche le tipologie di distribuzione delle applicazioni hanno subito delle modifiche importanti: innanzitutto è sparito il marketplace privato. Concettualmente esiste ancora, ma non ha più un nome definito come in passato: semplicemente, nella fase di submit di un’applicazione è apparsa l’opzione Hide from users browsing or searching the Store quando si seleziona la pubblicazione sullo store pubblico.

L’altra novità riguarda il marketplace beta: il numero di beta tester che possono essere abilitati al download della nostra app è stato portato da 100 a 10.000.

Infine, è stata aggiunta un’opzione, sempre in fase di pubblicazione, per escludere automaticamente i paesi che impongono linee guida particolarmente restrittive sui contenuti.

In conclusione

AppHub è sempre stato un po’ il “punto debole” del mondo Windows Phone, a causa dei numerosi bug e problemi che lo affliggevano. Il primo impatto con il nuovo Windows Phone Dev Center è decisamente positivo: la nuova interfaccia è molto più agevole e funzionale e anche la velocità di caricamento è aumentata notevolmente. Ottimo lavoro Microsoft!


Windows Phone , Microsoft , App Hub

0 comments

MVVM e Windows Phone – Two way binding (4° parte)

Print Content | More

Proseguiamo il tutorial su MVVM e Windows Phone parlando di un aspetto molto importante: il two way binding, ovvero il meccanismo con cui siamo in grado di ricevere l’input dell’utente.

Two way binding

Il two way binding in realtà non è una prerogativa di MVVM, ma è una caratteristica del binding di Silverlight: quando effettuiamo un binding tra un controllo e un oggetto, come impostazione di default, viene application il one way binding, ovvero ogni qualvolta lo stato dell’oggetto cambia il controllo viene aggiornato per riflettere il cambiamento. Non vale però il contrario: se il controllo dovesse modificare in qualsiasi momento lo stato dell’oggetto, il codice non se ne accorgerebbe. Il two way binding serve proprio a questo: il canale di comunicazione diventa bidirezionale e l’oggetto è in grado di cambiare il suo stato in seguito ad un intervento del controllo.

Il two way binding è fondamentale nel pattern MVVM perchè è il modo in cui possiamo ricevere l’input di un utente: se, ad esempio, abbiamo un controllo TextBox e vogliamo, nel view model, recuperare il testo inserito dall’utente dobbiamo creare una proprietà di tipo string e metterla in two way binding con la proprietà Text del controllo. Dopodichè, nel ViewModel, possiamo utilizzare il valore di questa proprietà per effettuare le successive elaborazioni.

Ma vediamo un esempio concreto applicato al nostro RSS reader: vogliamo intercettare la selezione di una delle notizie dalla ListBox e mostrare a video il titolo dell’elemento selezionato.

La prima cosa da fare è, nel nostro ViewModel, andare a definire una proprietà che sarà messa in binding con la proprietà SelectedItem della ListBox e che conterrà il riferimento all’oggetto selezionato.

private FeedItem _selectedItem;

public FeedItem SelectedItem
{
    get { return _selectedItem; }
    set
    {
        if (_selectedItem != value)
        {
            _selectedItem = value;
            RaisePropertyChanged(() => SelectedItem);
        }
    }
}

Ora possiamo metterla in binding con la proprietà SelectedItem del controllo ListBox usando il two way binding nel seguente modo:
<ListBox ItemsSource="{Binding Path=FeedItems}" SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Path=Title}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Come vedete è molto semplice attivare il two way binding: è sufficiente specificare Mode=TwoWay all’interno dell’espressione di binding e il gioco è fatto. Ora, ogni qualvolta la proprietà SelectedItem cambierà (perchè l’utente ha selezionato un nuovo elemento all’interno della lista) anche il valore della relativa proprietà nel ViewModel cambierà. Possiamo perciò andare ad intercettare il get della proprietà per raggiungere il nostro scopo, ovvero mostrare a video il titolo dell’elemento selezionato. La nostra proprietà nel ViewModel diventa perciò:

private FeedItem _selectedItem;

public FeedItem SelectedItem
{
    get { return _selectedItem; }
    set
    {
        if (_selectedItem != value)
        {
            _selectedItem = value;
            MessageBox.Show(_selectedItem.Title);
            RaisePropertyChanged(() => SelectedItem);
        }
    }
}

Prima di scatenare l’evento RaisePropertyChanged mostriamo a video il titolo usando una semplice MessageBox. In un’applicazione reale (e riprenderemo questo concetto in uno dei prossimi post) molto probabilmente, in questa situazione, avremmo scatenato l’evento di navigazione verso la pagina di dettaglio.

Nella prossima puntata

Se siete alle prime armi e state sviluppando un’applicazione con il pattern MVVM una delle domande che prima o poi vi dovrete porre sarà: “Come gestisco le interazioni dell’utente con l’applicazione?”  (ad esempio, la pressione di un pulsante). La risposta nel prossimo post! Nel frattempo, potete scaricare e giocare con il progetto di esempio aggiornato.


Windows Phone , MVVM

0 comments

MVVM e Windows Phone – La view (3° parte)

Print Content | More

Dopo aver introdotto le basi teoriche del pattern MVVM (nel primo post) e aver realizzato il model e il view model (nel secondo post), siamo pronti per entrare nel “vivo” del pattern, andando a vedere come gestire il collegamento tra la view e il relativo view model. Ci sono diversi approcci per raggiungere il risultato: quello di cui vi parlerò in questo post è tramite il ViewModelLocator.

Il ViewModelLocator

Il ViewModelLocator è una classe che si occupa di “servire” i view model quando richiesti, esponendo una proprietà per ognuno dei view model di cui dispone il progetto. Il ViewModelLocator viene definito come risorsa globale dell’applicazione (all’interno quindi del file App.xaml), dopodichè ogni vista andrà a impostare come DataContext generale il suo specifico view model dichiarato nel ViewModelLocator.

Rispetto ad altri approcci, lo svantaggio del ViewModelLocator è che costituisce una classe in più da mantenere; il vantaggio, però, è che siamo in grado di gestire con molta facilità le dipendenze che un view model può avere (ad esempio, eventuali parametri nel costruttore).

La struttura del ViewModelLocator è molto semplice: dopo aver creato una nuova classe con il nome che preferiamo (va benissimo ViewModelLocator), dobbiamo dichiarare una proprietà pubblica per ognuno dei view model. Riprendendo l’applicazione per leggere un feed reader che stiamo sviluppando, il ViewModelLocator, inizialmente, conterrà solamente un view model (MainViewModel), associato all’unica view disponibile (MainPage.xaml).

public class ViewModelLocator
{
    private MainViewModel _mainViewModel;

    public MainViewModel MainViewModel
    {
        get { return _mainViewModel ?? (_mainViewModel = new MainViewModel()); }
    }
}

Nel momento in cui dovremo aggiungere nuovi view model nell’applicazione (ad esempio, perchè creiamo una vista per leggere il dettaglio di una notizia), dovremo andare a inserire una nuova proprietà.

A questo punto dobbiamo dichiarare il ViewModelLocator come risorsa globale, affinchè tutte le viste possano accedervi direttamente dallo XAML. Per farlo è sufficiente portarci nel file App.xaml e, nella sezione Application.Resources, aggiungere il ViewModelLocator con una chiave univoca.

<Application.Resources>
    <ViewModels:ViewModelLocator x:Key="ViewModelLocator" />
</Application.Resources>

Ovviamente dovrete prima importare il namespace del vostro ViewModelLocator nello XAML per potervi accedere, come nell’esempio seguente:

xmlns:ViewModels="clr-namespace:MVVM_FeedReader.ViewModels

La View

A questo punto possiamo andare a realizzare l’interfaccia grafica della nostra applicazione. Il primo step è collegare il view model alla view: per farlo, andiamo a sfruttare il ViewModelLocator appena definito e la proprietà DataContext. Se avete famigliarità con il binding del mondo XAML, saprete già cosa fa questa proprietà: una volta impostato una classe come DataContext di un controllo, il controllo stesso e tutti i suoi figli (seguendo la struttura ad albero dello XAML) potranno accedere alle proprietà pubblica di quella classe. Ecco perchè andiamo a definire il view model come DataContext dell’intera pagina, in modo che tutti i controlli che inseriremo possano avere accesso alle varie proprietà.

<phone:PhoneApplicationPage.DataContext>
    <Binding Source="{StaticResource ViewModelLocator}" Path="MainViewModel" />
</phone:PhoneApplicationPage.DataContext>

Utilizzando questa dichiarazione andiamo a definire il DataContext utilizzando come sorgente il ViewModelLocator e come valore dell’attributo Path il view model corrispondente alla view che stiamo realizzando.

A questo punto il gioco è fatto: possiamo realizzare la UI inserendo tutti i controlli che vogliamo e, tramite il binding, utilizzare le proprietà definite nel nostro view model per mostrare i dati.

Ad esempio, dato il view model che abbiamo visto nel post precedente, ecco come creare una ListBox che venga popolata dalla proprietà FeedItems (se ricordate si trattava di una collezione di tipo ObservableCollection<FeedItem>).

<ListBox ItemsSource="{Binding Path=FeedItems}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Path=Title}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Come vedete, non è più necessario dal code behind valorizzare la proprietà ItemsSource tramite un riferimento alla ListBox, ma facciamo tutto direttamente nello XAML, lasciando il code behind “intatto”.

Qualche scenario avanzato

Nel prossimo post vedremo come gestire gli eventi e l’interazione con l’utente. Nel frattempo, potete scaricare il progetto di esempio utilizzato fino ad ora: nei prossimi post lo espanderemo aggiungendo nuove funzioni.


Windows Phone , MVVM

3 comments

MVVM e Windows Phone – Model e ViewModel (2° parte)

Print Content | More

Dopo aver visto le basi teoriche vediamo come iniziare a strutturare un progetto in modo da sfruttare il pattern MVVM, utilizzando come riferimento lo stesso descritto nel post precedente: un’applicazione per consumare un feed RSS.

Nota bene! La procedura di cui parlerò in questo e nei prossimi post vuole essere semplicemente una descrizione dell’approccio da me utilizzato e con cui sono abituato a lavorare. Non è l’unico approccio esistente e non è detto che sia il migliore.

Il primo passo è quello di creare un progetto Windows Phone “vuoto”, utilizzando il template Windows Phone Application di Visual Studio. Dopodichè andiamo a creare alcune cartelle per inserire le nostre classi secondo la struttura del pattern: è mia abitudine creare una cartella Views (per i file XAML), ViewModels (per i view models), Services (per i servizi che si occupano di gestire i dati) e Entities (per le classi che rappresentano le entità con cui lavoreremo).

Il secondo passo è quello di installare MVVM Light, il toolkit di Laurent Bugnion che offre una serie di helper e utility che semplificheranno notevolmente il nostro lavoro. Il modo più semplice per farlo è quello di utilizzare NuGet: troverete due versioni della libreria, una tradizionale e una contrassegnata dall’etichetta Libraries only. Vi consiglio di installare la seconda, che si limita ad aggiungere una reference alle DLL necessarie.

Realizziamo il servizio

Il primo passo è realizzare il model, ovvero i servizi che si occuperanno di recuperare il feed RSS (quindi un file XML “piatto”) e di tradurlo in oggetti .NET, che saremo in grado di manipolare. Il servizio non è nient’altro che una classe, che conterrà uno o più metodi per effettuare operazioni sull’RSS. Prima però abbiamo bisogno di realizzare una classe in grado di mappare ogni singola notizia contenuta nel nostro feed RSS.

public class FeedItem
{
    public string Title { get; set; }
    public string Description { get; set; }
    public Uri Url { get; set; }
}

Ovviamente si tratta di una versione molto semplificata: in un’applicazione reale potrebbero essere molte di più le informazioni da memorizzare. Una volta definita l’entità dobbiamo realizzare un servizio in grado di tradurre l’RSS in una collezione di oggetti di tipo FeedItem. Con il vecchio approccio il codice per recuperare le notizie sarebbe stato inserito direttamente nel code behind e richiamato in fase di caricamento della pagina (ad esempio, nel costruttore della classe MainPage). Con l’approccio MVVM, invece, andiamo a realizzare una classe ad hoc per effettuare queste operazione che, nell’esempio, viene chiamata FeedService e inclusa nella cartella Services.

La definizine del servizio, nel nostro esempio, è molto semplice e si limita a contenere un unico metodo che, sfruttando LINQ to XML, è in grado di elaborare l’RSS scaricato:

public class FeedService
{
    public void GetNews()
    {
        WebClient client = new WebClient();
        client.DownloadStringCompleted += (obj, args) =>
            {
                XDocument doc = XDocument.Parse(args.Result);
                var result = doc.Descendants("rss").Descendants("channel").Elements("item").Select(x => new FeedItem
                    {
                        Title = x.Element("title").Value,
                        Description = x.Element("description").Value,
                    }).ToList();

                OnGetNewsCompleted(new GetNewsCompletedEventArgs(result));

            };

        client.DownloadStringAsync(new Uri("http://feeds.feedburner.com/qmatteoq"));
    }

    public event EventHandler<GetNewsCompletedEventArgs> GetNewsCompleted;

    public void OnGetNewsCompleted(GetNewsCompletedEventArgs e)
    {
        EventHandler<GetNewsCompletedEventArgs> handler = GetNewsCompleted;
        if (handler != null) handler(this, e);
    }
}

Dato che per scaricare il feed RSS da Internet utilizziamo la classe WebClient, che è asincrona, utilizziamo il meccanismo degli event handler per gestire l’operazione: lo sviluppatore invocherà il metodo GetNews e si sottoscriverà all’evento GetNewsCompleted, che sarà scatenato nel momento in cui il download del file XML è terminato e, grazie a LINQ to XML, lo abbiamo convertito in oggetti di tipo FeedItem.

Il codice appena presentato dovrebbe essere semplice da capire: una volta scaricato il file RSS (nel momento in cui, perciò, l’evento DownloadStringCompleted viene scatenato) tramite LINQ to XML andiamo a recuperare i nodi title e description di ogni nodo item, che rappresenta la singola notizia. Una volta che abbiamo completate questa operazione, tramite l’event invocator OnGetNewsCompleted, andiamo a scatenare l’evento GetNewsCompleted, in modo che il client sia in grado, tramite i parametri di ritorno, di recupare le notizie sotto forma di collezione IEnumerable<FeedItem>.

Come vedete, il servizio non restituisce un tipo di collezione specifico, ma una generica IEnumerable: sarà compito del view model elaborare questa collezione nel modo più consono affinchè possa essere presentato dalla view.

Realizziamo il view model

Ora possiamo passare a realizzare il view model che, come anticipato nel post precedente, fa da tramite tra il model e la view: si occupa di prendere i dati "grezzi” (nel nostro caso, la collezione di oggetti di tipo FeedItem) e di elaborarli affinchè possano essere presentati dalla View.

Con l’approccio tradizionale, ovvero nel code behind, dopo aver recuperato l’elenco delle notizie lo avremmo, ad esempio, assegnato alla proprietà ItemsSource di una ListBox, come nell’esempio:

public partial class MainPage : PhoneApplicationPage
{
    // Constructor
    public MainPage()
    {
        InitializeComponent();
        IEnumerable<FeedItem> feedItems = GetNews();
        NewsList.ItemsSource = feedItems;
    }
}

L’approccio basato su MVVM richiede però che il collegamento tra proprietà e controlli venga gestito tramite il binding: questo perchè nel view model non abbiamo accesso diretto ai controlli come avviene nel code behind; per questo motivo dobbiamo costruire le nostre proprietà supportando il meccanismo previsto dall’interfaccia INotifyPropertyChanged, affinchè ogni variazione venga automaticamente gestita dalla view. A questo scopo ci viene in aiuto MVVM Light, offrendoci una classe base da cui far ereditare i nostri view model, chiamata ViewModelBase. La caratteristica di questa classe che andremo ad usare con maggiore frequenza è l’evento RaisePropertyChanged, da scatenare ogni qualvolta il valore della proprietà è cambiato.

Il modo in cui andremo a scrivere le proprietà sarà perciò leggermente diverso da quello a cui siamo abituati. Ipotizziamo di voler definire una proprietà per memorizzare la lista di notizie da mostrare nella view. In altre situazioni l’avremmo semplicemente dichiarata nel seguente modo:

public ObservableCollection<FeedItem> FeedItems { get; set; }

Per poter supportare pienamente il binding, invece, dobbiamo dichiararla nel seguente modo:

private ObservableCollection<FeedItem> _feedItems;

public ObservableCollection<FeedItem> FeedItems
{
    get { return _feedItems; }
    set
    {
        if (_feedItems != value)
        {
            _feedItems = value;
            RaisePropertyChanged(() => FeedItems);
        }
    }
} 

Il risultato sarà esattamente lo stesso: la differenza è che, ogni qualvolta il valore della proprietà FeedItems cambia, lo notifichiamo a tutti controlli in binding con la stessa scatenando l’evento RaisePropertyChanged. Quello che ci resta da fare in questo semplice view model è, in fase di inizializzazione, collegarci al servizio realizzato in precedenza per ottenere le notizie pubblicate nel feed RSS. Ecco come appare, perciò, il view model nella sua interezza:

public class MainViewModel: ViewModelBase
{
    private ObservableCollection<FeedItem> _feedItems;

    public ObservableCollection<FeedItem> FeedItems
    {
        get { return _feedItems; }
        set
        {
            if (_feedItems != value)
            {
                _feedItems = value;
                RaisePropertyChanged(() => FeedItems);
            }
        }
    } 

    public MainViewModel()
    {
        FeedService feedService = new FeedService();
        feedService.GetNewsCompleted += (obj, args) =>
            {
                FeedItems = args.FeedItems.ToObservableCollection();
            };
        feedService.GetNews();
    }
}

Nel costruttore non facciamo altro che inizializzare il nostro servizio e chiamare il metodo GetNews: nell’event handler che gestisce l’evento GetNewsCompleted andiamo a convertire il risultato del servizio (una collezione di tipo IEnumerable<FeedItem>) in una ObservableCollection<FeedItem>, che è un tipo di collezione molto più adatta nello scenario tipico di un view model in quanto i controlli in binding con tale collezione saranno aggiornati in automatico ad ogni cambiamento (aggiunta o rimozione di un elemento, modifica dell’ordine, ecc.). E’ importante sottolineare che ToObservableCollection() è un extension method scritto ad hoc, non fa parte del framework .NET: potrete trovarlo il codice nel progetto di esempio che pubblicherò alla fine di questi post dedicati a MVVM.

Nella prossima puntata

In questo post abbiamo realizzato i primi due “pezzi” della nostra applicazione. Al momento, però, non siamo entrati particolarmente nel vivo di MVVM: ci siamo limitati a realizzare due classi con pochi punti in comune e non abbiamo ancora avuto modo di vedere i frutti del nostro lavoro grazie ad un’interfaccia grafica ad hoc. Nel prossimo post vedremo invece come collegare la view al view model e come far si che la UI sia in grado di mostare le proprietà che abbiano definito nel view model.


Windows Phone , MVVM

3 comments

MVVM e Windows Phone – Introduzione (1° parte)

Print Content | More

Mi è capitato spesso e volentieri nei miei post di parlare di Model-View-ViewModel (d’ora in poi, semplicemente MVVM), il pattern sicuramente più diffuso nel mondo Silverlight / WPF / Windows Phone / Windows 8. Si tratta di un approccio allo sviluppo che, inizialmente, può spaventare ma che, superato lo scoglio iniziale, da molte soddisfazioni e consente sicuramente di scrivere codice più pulito, più facile da mantenere e da evolvere.

Non ne ho mai parlato però approfonditamente nei miei post: sono un grande sostenitore del pattern MVVM, ma credo anche che sia “pericoloso” inserirlo all’interno di articoli o sessioni (a meno che non sia strettamente collegato all’argomento di cui si vuole parlare); il rischio è che le persone che non conoscono il pattern non siano poi in grado di comprendere anche il messaggio che si vuole veicolare.

Il rischio che però si corre è quello di creare uno scarto tra ciò che viene spiegato e ciò che poi viene utilizzato nel mondo reale: da questa mia considerazione nasce questa serie di post, dedicata al pattern MVVM e a come utilizzarlo nelle applicazioni Windows Phone (e Windows 8). Non mi considero affatto un guru di MVVM, ci sono persone (come Mauro) estremamente più competenti di me: questi post vogliono essere semplicemente una introduzione a MVVM, per farvi scoprire l’approccio che regolarmente utilizzo nelle applicazioni, con lo scopo di darvi l’opportunità di prendere famigliarità con questo pattern e a superare le difficoltà che si possono presentare all’inizio.

Partiamo perciò con qualche concetto teorico, per capire cos’è MVVM e quali sono i vantaggi nell’utilizzarlo.

Perchè MVVM?

Come anticipato all’inizio dell’articolo, è bene precisare che MVVM non è una tecnologia, una libreria o un toolkit, ma è un pattern, ovvero un approccio allo sviluppo, una metodologia per organizzare il proprio codice e che cambia radicalmente il modo in cui siamo abituati a scrivere applicazioni. In rete esistono diverse librerie dedicate a MVVM (come MVVM Light Toolkit, che useremo abbondantamente nei prossimi post), che però non costituiscono il pattern ma semplicemente aiutano ad implementarlo, offrendo una serie di helper e utility.

Gli obiettivi di questo pattern sono analoghi a quelli di tanti altri pattern diffusi nel mondo dello sviluppo, come MVC (Model-View-Controller) e MVP (Model-View-Presenter). Il vantaggio principale è la separazione dei ruoli: quando creiamo applicazioni Windows Phone in maniera tradizionale, nel code behind andiamo a inserire il codice più disparato: logica, interazione con la UI, gestione delle animazioni, ecc. Questa “confusione” rende il codice difficile da mantenere e, soprattutto, poco testabile: se vogliamo scrivere degli unit test per verificare la correttezza del nostro codice siamo costretti a creare un riferimento all’applicazione vera e propria, a simulare le interazioni dell’utente (ad esempio, la pressione di un pulsante) e così via. Il pattern MVVM, invece, consente di separare i ruoli dell’applicazione in tre aspetti ben distinti, che approfondiremo a breve.

Da questa separazione, di conseguenza, emergono gli altri vantaggi nell’adottare questo pattern:

  • Il codice è più facile da mantenere, in quanto siamo facilmente in grado di individuare il responsabile di un malfunzionamento, a seconda della tipologia di problema.
  • E’ più facile per un designer lavorare sull’interfaccia dell’applicazione, in quanto UI e logica sono separate. In quest’ottica risulta anche molto più semplice, grazie al supporto di Blend per la modalità design, sostituire i servizi reali con dei servizi fittizi, che danno la possibilità al designer di lavorare sulla grafica senza doversi preoccupare di mettere in piedi tutto il necessario per avere dei dati di esempio (pensiamo ad esempio ad applicazioni popolate da servizi web o WCF).

Vediamo ora quali sono le componenti in cui viene suddivisa l’applicazione utilizzando il pattern MVVM, prendendo come esempio di riferimento una semplice applicazione in grado di visualizzare il feed RSS di un sito.

Model

La componente model rappresenta il modello di dati dell’applicazione: concettualmente, sono tutti quei servizi che si occupano di recuperare i dati grezzi che saranno utilizzati. Nella nostra applicazione di riferimento, il model è costituito dalle entità che mappano i contenuti del feed RSS e dai servizi in grado di recuperare dalla rete l’RSS e di trasformarlo in oggetti .NET e quindi in grado di essere manipolati e utilizzati all’interno dell’applicazione.

Il model deve essere completamente “ignorante” di come vengono presentati i dati: nel limite del possibile, come sviluppatori dovremmo essere in grado di riutilizzare il model in un’altra applicazione senza troppi sforzi, proprio perchè deve essere completamente slegato da come i dati vengono presentati.

View

La view è rappresentata dalla UI dell’applicazione, che si occupa di mostrare i dati dell’applicazione in maniera comprensibile all’utente e di gestire tutte le interazioni e le animazioni: la view, al contrario del model, deve essere specifica per l’applicazione a cui stiamo lavorando e, difficilmente, può essere riutilizzata in un’altro prodotto. L’esempio più attuale è il porting di un’applicazione da Windows Phone a Windows 8: la UI, per forza di cose, sarà diversa, dato che le due piattaforme, pur condividendo lo stile Metro, prevedono paradigmi e modalità di interazione differenti.

Nel contesto di un’applicazione Windows Phone o Windows 8, la view è rappresentata dai file XAML che definiscono l’interfaccia. In linea di massima, l’approccio MVVM porta ad avere il code behind praticamente vuoto, in quanto la logica dell’applicazione è slegata dalla view: tipicamente, l’unica logica che il pattern ammette nel code behind è quella relativa ad aspetti legati alla UI, come l’avvio di animazioni.

ViewModel

Il ViewModel è ciò che fa da collante tra la view e il model: si occupa di prendere i dati grezzi restituiti dal model e di prepararli affinchè la view sia in grado di visualizzarli. Ciò che rende possibile il collegamento tra i due mondi è il binding: tutte le proprietà del ViewModel vengono collegate all’interfaccia sfruttando il binding del mondo XAML, ovverò la possibilità di creare un canale di comunicazione tra l’interfaccia e gli oggetti nel codice. L’altra caratteristica fondamentale che deve avere il ViewModel è il supporto all’interfaccia INotifyPropertyChanged: in questo modo, ogni volta che una delle proprietà viene modificata i controlli della UI che sono in binding con la stessa sono automaticamente aggiornati per mostrare il nuovo stato.

In conclusione

In questo primo post abbiamo introdotto il pattern MVVM e ne abbiamo definito i principali aspetti teorici: nei prossimi post scenderemo un po’ più in dettaglio e vedremo come realizzare, nel concerto, il nostro feed reader sfruttando i concetti appresi.


Windows Phone , MVVM

0 comments

Windows 8, applicazioni Metro style, navigazione e MVVM

Print Content | More

Tranquilli, non ho tradito Windows Phone per Windows 8 Smile Windows Phone al momento si trova in una situazione un po’ di stallo: la versione 7.5 è ormai sul mercato da più di un anno, perciò diventa sempre più difficile trovare qualcosa di nuovo su cui bloggare a riguardo. Si tratta però di uno stallo temporaneo: nel corso dell’estate Microsoft rilascerà la prima beta del’SDK di Windows Phone 8, allora vedrete che i post su Windows Phone torneranno in gran numero Smile

In più, alla luce dei recenti annunci, imparare a conoscere WinRT è sicuramente un ottimo trampolino di lancio per preparsi al futuro.

Ma veniamo al dunque: oggi vi voglio parlare di un servizio che vi semplificherà la navigazione da una pagina all’altra nella vostra applicazione XAML / C# sviluppata utilizzando il pattern MVVM. Questo servizio arriva direttamente dalla mia esperienza di sviuppo per Windows Phone; una delle sfide da affrontare nell’utilizzo del pattern MVVM è che solitamente la navigazione verso un’altra pagina viene avviata da qualcosa che si è verificato in un ViewModel: il variare di una proprietà (ad esempio, l’elemento selezionato di una lista) o l’utilizzo di un comando (ad esempio, la pressione di un pulsante). Il problema è che il NavigationService è accessibile solo dal code behind, in quanto fa parte delle proprietà esposte dalla classe PhoneApplicationPage, dalla quale derivano tutte le pagine di Windows Phone.

Per risolvere questo inghippo ci sono diverse strategie: quella da me utilizzata sfrutta un’implementazione di un NavigationService illustrata in un post di Laurent Bugnion. Questo servizio non fa altro che da wrapper al NavigationService reale, offrendo la possibilità in un ViewModel di avviare una navigazione semplicemente inizializzando questo servizio all’interno dello stesso.

Veniamo ora all’applicazione Windows 8: il NavigationService di Windows Phone, così com’è, non è in grado di funzionare, dato che questi utilizza la proprietà Application.Current.RootVisual per accedere al frame principale dell’applicazione e, di conseguenza, gestire gli eventi di navigazione. Tale proprietà non è disponibile in WinRT: ecco perciò che è stato necessario trovare una soluzione alternativa.

La mia prima soluzione, funzionale ma non molto elegante, è stata quella di esporre come proprietà pubblica il rootFrame che viene inizializzato nel file App.xaml.cs: è tramite l’inizializzazione di questa classe che abbiamo la possibilità, nel code behind di una pagina, di avviare una navigazione tramite il metodo Frame.Navigate. In questo modo, l’implementazione del NavigationService era sostanzialmente la stessa di Windows Phone, con la differenza che utilizzavo la proprietà appena definita per accedere al frame e gestire gli eventi di navigazioneal posto di usare Application.Current.RootVisual, come nell’esempio:

 _mainFrame = (Application.Current as App).rootFrame;

 

Il mio amico Joost van Shaik, MVP anche lui nella categoria Windows Phone Development, partendo dal mio approccio è riuscito ad elaborare una soluzione molto più elegante: il costruttore del NavigationService accetta ora come parametro in fase di inizializzazione l’oggetto frame da utilizzare. Sfruttando poi il meccanismo della dependency injection siamo in grado, nell’App.xaml.cs, di registrare all’avvio il NavigationService opportunamente inizializzato con il rootFrame e di utilizzare questa istanza in tutti i nostri view models, mantenendo perciò sempre attivo il riferimento al frame.

Ecco il codice del NavigationService:

public class NavigationService : INavigationService
{
public NavigationService(Frame mainFrame)
{
  _mainFrame = mainFrame;
}

private Frame _mainFrame;

public event NavigatingCancelEventHandler Navigating;

public void NavigateTo(Type type)
{
    _mainFrame.Navigate(type);
}

public void NavigateTo(Type type, object parameter)
{
    _mainFrame.Navigate(type, parameter);
}

public void GoBack()
{
  if (_mainFrame.CanGoBack)
  {
    _mainFrame.GoBack();
  }
}

Rispetto al NavigationService di Windows Phone illustrato nel post di Laurent Bugnion le uniche differenze sono:

  • Il tipo di parametro passato al metodo NavigateTo, dato che il metodo Frame.Navigate di Windows 8 richiede il tipo della pagina verso cui ci vogliamo spostare, al contrario di quello di Windows Phone che accetta un URL.
  • La presenza di un overload del metodo NavigateTo, dato che Windows 8 supporta la possibilità di portare un oggetto da una pagina all’altra, al contrario di Windows Phone che supporta solo il passaggio di parametri tramite query string.

Ecco un esempio di come avviene questa inizializzazione utilizzando uno dei dependency injection container disponibile per WinRT, chiamato MetroIoc. La registrazione avviene all’interno del metodo OnLaunched del file App.xaml.cs, che viene invocato nel momento in cui l’applicazione viene avviata dalla tile principale o da una di quelle secondarie (se supportate).

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    var rootFrame = new Frame();
    // Do not repeat app initialization when already running, just ensure that
    // the window is active
    if (args.PreviousExecutionState == ApplicationExecutionState.Running)
    {
        Window.Current.Activate();
        return;
    }

    if (args.PreviousExecutionState == ApplicationExecutionState.Terminated || args.PreviousExecutionState==ApplicationExecutionState.NotRunning)
    {
        ioc.RegisterInstance(typeof (INavigationService), new NavigationService(rootFrame));
    }
    
    if (!rootFrame.Navigate(typeof(MainPage)))
    {
        throw new Exception("Failed to create initial page");
    }

    // Place the frame in the current Window and ensure that it is active
    Window.Current.Content = rootFrame;
    Window.Current.Activate();
}

A questo punto all’interno dei vostri view model, previa inizializzazione del NavigationService (tramite dependency injection oppure in maniera tradizionale) potete avviare la navigazione semplicemente chiamando il metodo NavigateTo, come nell’esempio:

public MainViewModel(INavigationService navigationService)
{
    navigationService.NavigateTo(typeof(DetailPage));
}

Happy coding!


Windows Phone , Windows 8 , Microsoft , WinRT

0 comments

Una nuova avventura (in inglese)

Print Content | More

Con il mio amico Ugo è almeno un anno che si parlava di aprire un blog in inglese. Le motivazioni erano tante: la voglia di “varcare” i confini nazionali, di migliorare la propria capacità di scrivere in inglese e la possibilità di poter aiutare non solo gli sviluppatori nazionali, ma anche quelli oltre confine.

Il tempo, però si sa, è tiranno e lavoro, famiglia e gli impegni community hanno sempre fatto posticipare questa decisione, anche solo per la mancanza di tempo nel mettere in piedi tutta l’infrastruttura necessaria per attivare il blog.

Qualche settimana fa Ugo è riuscito a superare tutti questi ostacoli e ha finalmente inaugurato il suo blog in inglese: grazie perciò al suo supporto sia “psicologico” (il suo impegno nel riuscire a concretizzare questo desiderio mi ha dato la spinta per vincere la pigrizia) che tecnico (si è occupato lui dell’installazione del blog engine e di tutti i plugin più utili) ho trovato finalmente l’opportunità di iniziare questa nuova avventura.

Apre perciò ufficialmente i battenti il mio blog in inglese all’indirizzo http://wp.qmatteoq.com: nuovo blog engine, nuova veste grafica e nuovi contenuti. Il blog non sarà infatti un mero “porting” con relativa traduzione del mio blog in italiano, ma cercherò di offrire contenuti specifici che possano essere utili anche per gli sviluppatori d’oltreoceano.

Non temete però: il blog in italiano non sarà abbandonato, anzi, continuerà a essere il “centro” delle mie attività community.

Un grazie a tutte le persone che incontro durante gli eventi, che mi contattano via mail e che mi aiutano a tenere sempre viva e forte la mia passione.


Windows 8 , Windows Phone

0 comments