WindowsPhone

Snoozy sul Windows Phone Marketplace !

1732.primaryImage_193E171C

Da oggi è stata pubblicata sul marketplace di Windows Phone la mia nuova app Snoozy, attraverso la quale i pendolari che vogliono “schiacciare un pisolino” durante il loro tragitto in pullman o in treno verso il proprio luogo di lavoro, non correranno più il rischio di perdere la fermata a cui scendere !

Per maggiori informazioni vi rimando al link sul market.

ioProgrammo : scopriamo come usare l’accelerometro su Windows Phone

4530.4-178g_3BEC838D

Anche questo mese su “ioProgrammo” (n. 178, Settembre 2012) c’è un mio articolo dedicato all’utilizzo dell’accelerometro in Windows Phone.

Si parte dalla teoria del funzionamento di un accelerometro fino ad arrivare alla realizzazione di una semplice applicazione di tilt sensing.

Purtroppo, c’è stato da parte mia un errore nel fornire due figure (precisamente la fig. 3 e la fig. 6) all’editore che nella rivista appaiono completamente nere. Di seguito vi riporto il loro contenuto reale.

Fig. 3 calcolo accelerazione rispetto asse X

Fig. 3 calcolo accelerazione rispetto asse X

Fig. 6 calcolo accelerazioni rispetto assi X e Y

Fig. 6 calcolo accelerazioni rispetto assi X e Y

Anche questa volta…mi raccomando…non perdetevelo !

App Hub in pensione … benvenuto al Dev Center

0550.7838.DC_thumb_18F73BC9_2BE8E43A

Come già annunciato nei giorni scorsi ed a seguito di un blocco temporaneo dei sistemi, Microsoft ha sostituito il vecchio App Hub con il Windows Phone Dev Center.

Sul Windows Phone Developer Blog possiamo leggere qui tutto ciò che riguarda le innovazioni, tra cui :

  • backend più robusto e scalabile;
  • supportp per PayPal e gli sviluppatori in più paesi;
  • nuovi tools per il tracking dei download e delle performance delle nostre app;
  • forum, SDK ed altre info concentrate in un unico punto;

Speriamo che si sia ridotto anche il tempo di certificazione delle app !

MessageBox dal ViewModel senza violare il pattern MVVM

Nel momento in cui decidiamo di realizzare un’applicazione, ad esempio per WP7, utilizzando il pattern MVVM ma senza adottare uno dei framework a disposizione (vedi MVVMLight,Caliburn Micro, …) ci dobbiamo aspettare di dover risolvere alcuni problemi per garantire sempre e comunque il disaccoppiamento tra UI e logica di presentazione e di business che il pattern stesso ci permette di ottenere.

Uno di questi problemi può essere ad esempio la necessità di visualizzare una MessageBox, quindi un componente della UI, a partire da un metodo del ViewModel corrispondente alla pagina nella quale ci troviamo. Tala problematica può essere risolta implementando un servizio che verrà “iniettato” nel ViewModel e che avrà il compito di visualizzare la MessageBox su richiesta.

Poiché dobbiamo garantire che non ci siano dipendenza strette tra il ViewModel e l’implementazione del servizio in questione, bisogna ragionare in termini di interfacce. Possiamo definire, quindi, un’interfaccia per tale servizio in modo da dare la possibilità di implementarla di volta in volta in maniera diversa; nel nostro caso l’implementazione che realizzeremo farà uso della MessageBox dalla quale prendiamo spunto per definire i metodi dell’interfaccia.

public interface IDialogService
{
    DialogResult Show(string messageText);

    DialogResult Show(string messageText, string caption, DialogButton button);
}

L’interfaccia IDialogService espone gli stessi metodi della classe MessageBox (nella quale però sono statici) mentre DialogResult e DialogButton, definiscono rispettivamente i possibili valori restituiti dalla dialog box a seguito dell’interazione con l’utente ed i bottoni che vogliamo visualizzare al suo interno. Per semplicità, sono stati definiti con due enumerativi uguali a quelli corrispondenti per la classe MessageBox (MessageBoxResult e MessageBoxButton).

public class DialogService : IDialogService
{
    #region IDialogService...

    public DialogResult Show(string messageText)
    {
        MessageBox.Show(messageText);
        return DialogResult.OK;
    }

    public DialogResult Show(string messageText, string caption, DialogButton button)
    {
        return this.MessageBoxToDialogResult(MessageBox.Show(messageText, caption, this.DialogToMessageBoxButton(button)));
    }

    private DialogResult MessageBoxToDialogResult(MessageBoxResult messageBoxResult)
    {
        return (DialogResult)messageBoxResult;
    }

    private MessageBoxButton DialogToMessageBoxButton(DialogButton dialogButton)
    {
        return (MessageBoxButton)dialogButton;
    }

    #endregion
}

L’implementazione DialogService non solo implementa i metodi esposti dall’interfaccia ma utilizza due metodi privati per mappare i DialogResult e DialogButton sui corrispondenti MessageBoxResult e MessageBoxButton. In questo caso, la mappatura è banalmente un cast per come abbiamo definito gli enumerativi; in altri casi potrebbe essere più complessa.

L’utilizzo di questo servizio sarà possibile iniettandolo nel ViewModel attraverso il costruttore.

private IDialogService dialogService;

public ViewModel(IDialogService dialogService)
{
    this.dialogService = dialogService;
}

Infine, sarà utilizzabile direttamente in un qualsiasi metodo del ViewModel.

this.dialogService.Show("Messaggio da visualizzare");

XAML e Binding : l’utilità della proprietà UpdateSourceTrigger

Supponiamo di voler effettuare il binding tra la proprietà Text di una TextBox della nostra UI ed una proprietà di tipo String definita nel ViewModel associato alla nostra pagina. Impostando la modalità di binding a TwoWay, ci rendiamo subito conto che il set della proprietà del ViewModel avviene solo ed esclusivamente quando il campo di testo perde il fuoco (quindi sul lost focus).

<TextBox x:Name="MyTextBox" Text="{Binding MyText, Mode=TwoWay}"/>

 

public string MyText
{
get { return this.myText; }
set
{
if (this.myText!= value)
{
this.myText= value;
this.OnPropertyChanged("MyText");
}
}
}

Talvolta questo non è il comportamento desiderato ed abbiamo la necessità che la nostra proprietà del ViewModel venga aggiornata ogni qual volta cambia il testo all’interno del campo.

La spiegazione di questo comportamento sta nel valore di default che la proprietàUpdateSourceTrigger del binding assume nel caso di una TextBox. LaUpdateSourceTrigger determina il momento in cui la sorgente del binding (binding source) viene aggiornata dalla destinazione del binding (binding target) nel caso di modalità two-way. Nel nostro caso il binding source è la proprietà del nostro ViewModel (ossia MyText) mentre il binding target è la proprietà Text della nostra TextBox (ricordiamo che è la proprietà di default del binding in una TextBox, ecco perchè non compare nella markup expression dell’esempio).

I possibili valori dell’enumerativo assegnabili alla UpdateSourceTrigger sono :

  • Default : il binding source è aggiornato quando il valore del binding target cambia;
  • Explicit : il binding source è aggiornato solo quando viene invocato in maniera esplicita il metodo BindingExpression.UpdateSource();

Per ogni controllo della UI il valore è tipicamente Default e nel caso della TextBox, in particolare, significa che il corrispondente binding source verrà aggiornato al lost focus.

Per cambiare il comportamento basta specificare nella markup expression di binding l’UpdateSourceTrigger ad Explicit.

<TextBox x:Name="MyTextBox"
         Text="{Binding MyText, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
         TextChanged="MyTextBox_TextChanged"/>

Come si evince dallo XAML è però necessario un ulteriore passo ossia quello di registrare l’evento di TextChanged della TextBox ed all’interno dell’event handler ricavere la binding expression per invocare su di essa l’esplicito aggiornamento del binding source.

private void MyTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    this.MyTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}

Da codice, attraverso il metodo GetBindingExpression() sul controllo della UI è possibile ricavare l’espressione di binding per una specifica dependecy property (nel nostro caso la proprietà Text). Sull’espressione è poi possibile forzare l’aggiornamento del binding source attraverso il metodo UpdateSource().