Isolated Storage: memorizziamo i settings della nostra applicazione – Parte 3: implementiamo il pulsante di conferma

Print Content | More

In questo ultimo post dedicato al salvataggio delle impostazioni della nostra applicazioni vedremo come coniugare quello che abbiamo visto nel primo post con la soluzione implementata nel post precendete: utilizzeremo sempre una classe esterna per gestre i nostri settings, ma andremo ad implementare un pulsante di conferma, che deve essere premuto affinchè le modifiche vengano salvate.

Il form

Il form sarà sempre lo stesso utilizzato nei due esempi precedenti: la differenza, rispetto alla soluzione precedente, è che questa volta rimuoveremo dallo XAML tutti gli attributi relativi al binding, dato che non vogliamo più che le impostazioni vengano salvate immediatamente ad ogni modifica.

L’unica novità è che utilizzeremo l’Application Bar di Windows Phone 7, nella quale andremo ad inserire i due pulsanti Save e Cancel.

Ecco perciò il codice XAML del nostro form:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <!--TitlePanel contains the name of the application and page title-->
    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
        <TextBlock x:Name="ApplicationTitle" Text="Settings Biding" Style="{StaticResource PhoneTextNormalStyle}"/>
        <TextBlock x:Name="PageTitle" Text="Settings" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>

    <!--ContentPanel - place additional content here-->
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <StackPanel Margin="5">
            <TextBlock Text="Name"></TextBlock>
            <TextBox x:Name="txtName"></TextBox>
            <TextBlock Text="Sex"></TextBlock>
            <StackPanel Orientation="Horizontal">
                <RadioButton x:Name="rMale" GroupName="Sex" Content="Male"></RadioButton>
                <RadioButton x:Name="rFemale" GroupName="Sex" Content="Female"></RadioButton>
            </StackPanel>
            <TextBlock Text="Knowledge"></TextBlock>
            <StackPanel Orientation="Horizontal">
                <CheckBox x:Name="cbAsp" Content="ASP.NET" ></CheckBox>
                <CheckBox x:Name="cbSilverlight" Content="Silverlight"></CheckBox>
            </StackPanel>
        </StackPanel>
    </Grid>
</Grid>

<!--Sample code showing usage of ApplicationBar-->
<phone:PhoneApplicationPage.ApplicationBar>
    <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
        <shell:ApplicationBarIconButton IconUri="/Images/ApplicationBar.Check.png" Text="Save" Click="ApplicationBarIconButton_Click"/>
        <shell:ApplicationBarIconButton IconUri="/Images/ApplicationBar.Cancel.png" Text="Cancel" Click="ApplicationBarIconButton_Click_1"/>
    </shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>

Il codice

Grazie alla classe AppSettings che abbiamo creato, il codice di salvataggio e lettura dei settings da inserire nel code behind è molto più semplice: dato che abbiamo creato una proprietà per ogni settings, ci basterà

  • in fase di inizializzazione della pagina, associare ogni proprietà all’attributo del relativo controllo che ne definisce lo stato (quindi la proprietà NameSetting verrà associata all’attributo Text, la proprietà MaleSetting all’attributo IsChecked e così via).
  • quando viene premuto il pulsante di conferma, salvare lo stato del controllo nella relativa proprietà.

Ecco perciò il codice che andiamo ad inserire quando la pagina viene istanziata:

public SettingsWithConfirm()
{
    InitializeComponent();

    AppSettings settings = new AppSettings();
    //Name
    txtName.Text = settings.NameSetting;

    //Sex
    rMale.IsChecked = settings.MaleSetting;
    rFemale.IsChecked = settings.FemaleSetting;

    //Knowledge
    cbAsp.IsChecked = settings.AspNetSetting;
    cbSilverlight.IsChecked = settings.SilverlightSetting;
}

Questo invece è il codice che andiamo ad eseguire quando premiamo il pulsante Save nella Application Bar:

private void ApplicationBarIconButton_Click(object sender, EventArgs e)
{
    AppSettings settings=new AppSettings();
    
    //Name
    settings.NameSetting = txtName.Text;

    //Sex
    settings.MaleSetting = (bool) rMale.IsChecked;
    settings.FemaleSetting = (bool) rFemale.IsChecked;

    //Knowledge
    settings.AspNetSetting = (bool) cbAsp.IsChecked;
    settings.SilverlightSetting = (bool) cbSilverlight.IsChecked;

    NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}

Non si tratta sicuramente del codice più efficiente in assoluto, dato che stiamo implementando della logica relativa ai dati nel code behind: non è sbagliato, ma l’applicazione risultante sarà difficile da testare e da manuntenere nel tempo. E’ un codice però sicuramente più pulito ed elegante rispetto a quello visto nel primo post, dato che siamo comunque riusciti a demandare ad una classe esterna (AppSettings.cs) tutta la logica di salvataggio e caricamento dei settings.

Conclusione

Abbiamo visto una panoramica piuttosto approfondita di come gestire i settings della nostra applicazione usando la classe IsolatedStorageSettings: nel primo post abbiamo utilizzato una soluzione molto semplice, che ci ha permesso di famigliarizzare con il suo funzionamento. Nel post seguente, abbiamo implementato una soluzione più efficiente, che ci ha permesso di spostare la gestione dei settings in una classe esterna e di sfruttare il binding di Silverlight, così da salvare immediatamente qualsiasi modifica alle impostazioni. Infine, in questo terzo e ultimo post abbiamo usato la stessa architettura per implementare una soluzione ibrida: utilizziamo sempre una classe esterna, ma questa volta le impostazioni vengono salvate solo dopo aver premuto un pulsante di conferma.


Windows Phone , Microsoft , Isolated Storage

2 comments

Isolated Storage: memorizziamo i settings della nostra applicazione – Parte 2: una soluzione più elegante

Print Content | More

Nel post precendete abbiamo famigliarizzato con la classe IsolatedStorageSettings, che ci permette di gestire in maniera semplice le impostazioni della nostra applicazione: il metodo che però abbiamo visto non era dei più efficienti, dato che tutto il codice per gestire le impostazioni era memorizzato nel code behind, il che rende l’applicazione difficilmente testabile e più difficile da mantenere.

In questo post vedremo una soluzione più elegante ed efficiente, che prevede l’implementazione della gestione delle impostazioni in una classe separata. Sfruttando questa classe, andremo ad implementare due soluzioni diverse:

  • Una che sfrutta il binding di Silverlight e che ci permette di memorizzare instantanemente qualsiasi modifica ad una delle impostazioni. Sfruttando questa soluzione, non scriveremo neanche una riga di codice nel code behind della nostra pagina contenete il form.
  • Una che richiede comunque la scrittura di codice nel code behind, ma che ci permette di implementare un pulsante di Conferma per evitare che le modifiche vengano salvate instantaneamente. Il risultato sarà analogo a quello ottenuto nell’applicazione realizzata nel post precedente.

Per realizzare tale soluzione, sfrutteremo i consigli che Microsoft stessa fornisce in questa guida.

Definiamo la classe AppSettings

La prima cosa da fare è realizzare la classe AppSettings, ovvero la classe “esterna” al form che utilizzeremo per leggere e scrivere le nostre impostazioni. In questa classe, a differenza di quanto fatto nell’esempio precedente, andremo a creare un elemento nel dictionary settings per ognuna delle impostazioni disponibili, anche se sono a scelta mutuamente esclusiva. Questo significa che se nell’esempio precedente avevamo una sola chiave Sex in cui memorizzavamo la scelta Male or Female, adesso avremo una chiave specifica per il radio button Male e una per il radio button Female.

Per gestire tutto ciò, per ogni settings, andremo a creare, a livello di classe, due costanti:

  • Una che contiene il nome della chiave.
  • Una che contiene il valore di default.

Ecco un esempio relativo alle impostazioni Name e Sex:

private const string NameSettingKeyName = "Name";
private const string MaleSettingKeyName = "Male";
private const string FemaleSettingKeyName = "Female";

private const string NameSettingDefault = "";
private const bool MaleSettingsDefault = false;
private const bool FemaleSettingDefault = false;

Avremmo potuto definire queste informazioni direttamente nelle proprietà che andremo a creare per gestire le impostazioni: in questo modo però, se dobbiamo cambiare il nome di una chiave, possiamo farlo in maniera più semplice e veloce.

Avremo bisogno inoltre di 3 metodi per poter lavorare con le nostre impostazioni:

  • Uno per memorizzare un’impostazione nel dictionary.
  • Uno per recuperare un’impostazione dal dictionary.
  • Uno per salvare le modifiche al dictionary.

Vediamoli uno per uno.

Il salvataggio

public bool AddOrUpdateValue(string key, object value)
{
    bool valueChanged = false;

    try
    {
        // if new value is different, set the new value.
        if (settings[key] != value)
        {
            settings[key] = value;
            valueChanged = true;
        }
    }
    catch (KeyNotFoundException)
    {
        settings.Add(key, value);
        valueChanged = true;
    }
    catch (ArgumentException)
    {
        settings.Add(key, value);
        valueChanged = true;
    }
    catch (Exception e)
    {
        Debug.WriteLine("Exception while using IsolatedStorageSettings: " + e.ToString());
    }

    return valueChanged;
}

Il metodo accetta come parametri di input una chiave e il relativo valore: la prima operazione che andiamo a fare è, nel caso in cui esista già quella chiave e il valore sia diverso da quello già memorizzato, sovrascrivere il valore corrente.

Tale operazione potrebbe scatenare un’eccezione, dato che la chiave potrebbe non esistere se è la prima volta che la memorizziamo: in tal caso, intercettando le tue tipologie di eccezioni che si possono scatenare in un caso come questo, aggiungiamo il nuovo elemento al dictionary tramite il metodo Add.  Se invece si verifica un’eccezione non prevista, scriviamo un messaggio nella Output Window di Visual Studio e ritorniamo false come risultato dell’operazione.

Il caricamento

public valueType GetValueOrDefault<valueType>(string key, valueType defaultValue)
{
    valueType value;

    try
    {
        value = (valueType)settings[key];
    }
    catch (KeyNotFoundException)
    {
        value = defaultValue;
    }
    catch (ArgumentException)
    {
        value = defaultValue;
    }
    catch (InvalidCastException)
    {
        value = defaultValue;
    }

    return value;
}

Questo metodo, sfruttando il tipo di ritorno valueType, ci permette di gestire settings che manipolano dati di tipo diverso. Il form che abbiamo realizzato ne è un chiaro esempio: la proprietà Name viene gestita con un Textbox (quindi di tipo string), mentre la proprietà Sex con due RadioButton (quindi di tipo bool).

Per il resto, il codice è molto semplice: recuperiamo dal dictionary settings l’elemento con la chiave specificata (key). Se dovesse scatenarsi un’eccezione, vuol dire che l’elemento non esiste, perciò ne recuperiamo il valore di default dalla costante.

Memorizziamo le impostazioni

Per comodità, definiamo anche un metodo che non fa altro che richiamare la funzione Save dell’oggetto settings:

private void Save()
{
    settings.Save();
}

Il vantaggio di utilizzare questa architettura è che, nel caso in cui dovessimo cambiare il nome del nostro oggetto di tipo IsolatedStorageSettings, ci basterebbe intervenire su questo metodo: se avessimo chiamato la funzione settings.Save() direttamente nelle singole proprietà che andremo a creare, avremmo dovuto modificarle tutte.

Definiamo i singoli settings

Ora siamo pronti per definire ogni singola impostazione sotto forma di proprietà: abbiamo infatti a disposizione i metodi che ci servono per scrivere, leggere e salvare le impostazioni. Vediamo il codice di esempio dell’impostazione Name.

public string NameSetting
{
    get { return GetValueOrDefault<string>(NameSettingKeyName, NameSettingDefault); }
    set
    {
        AddOrUpdateValue(NameSettingKeyName, value);
        Save();
    }
}

Il metodo get (invocato quando leggiamo la proprietà) chiama il metodo da noi definito GetValueOrDefault<>, specificando il tipo di ritorno come value type (in questo caso string) e come parametri il nome della chiave e il valore di default in caso non esista (entrambi i quali vengono letti dalle costanti che abbiamo creato all’inizio).

Il metodo set (invocato quando scriviamo la proprietà) chiama il metodo da noi definito AddOrUpdateValue, passandogli il nome della chiave (sempre tramite la costante da noi creata) e l’attributo value, che corrisponde al valore che vogliamo scrivere (se scriviamo ad esempio NameSetting = “Matteo”, “Matteo” rappresenta il value). Dopodichè, richiamiamo il metodo Save per salvare permanentemente le impostazioni nell’Isolated Storage.

Ad ogni singola impostazione corrisponde una proprietà, le quali sono definite tutte in questo modo: gli unici parametri che cambieranno saranno ovviamente il tipo di ritorno e i nomi delle costanti che contengono la chiave e il valore di default.

E ora… binding!

Ora abbiamo tutto quello che ci serve per collegare direttamente i nostri controlli XAML che gestiscono le varie impostazioni con le proprietà che abbiamo creato sfruttando il binding di Silverlight. Per prima cosa, dobbiamo definire la classe che abbiamo creato come risorsa della pagina. Dobbiamo perciò dire all’applicazione dove si troverà la nostra risorsa: per fare questo, dobbiamo aggiungere il namespace come attributo xmlns del nodo PhoneApplicationPage, che è  quello principale che contiene tutto il markup della nostra pagina, e specificare il tag con cui andremo a identificare questo controllo.

Ecco un esempio dell’attributo che dobbiamo aggiungere:

xmlns:local="clr-namespace:SettingsBinding.Classes

Nel nostro caso, SettingsBinding.Classes è il namespace che contiene la nostra classe AppSettings. Se apriamo il progetto di esempio allegato a questo post, capiremo facilmente il perchè di questo namespace: il nome dell'applicazione è SettingsBinding e la classe AppSettings è contenuta all’interno della cartella Classes. In linea di massima, per capire cosa inserire qui dentro, ci basta aprire il file cs della nostra classe e copiare il namespace.

Ora che abbiamo aggiunto questo attributo, possiamo sfruttare le risorse contenute nel namespace tramite il tag <local:xxx></local:xxx>, dove xxx è il nome della classe che vogliamo utilizzare. Ecco perciò che per usare la classe AppSettings dobbiamo inserire il seguente XAML:

<phone:PhoneApplicationPage.Resources>
    <local:AppSettings x:Key="appSettings"></local:AppSettings>
</phone:PhoneApplicationPage.Resources>

A questo punto possiamo utilizzare le proprietà della classe AppSettings (che corrispondono alle varie impostazioni) direttamente nello XAML. Ora vedremo qualche esempio: il fulcro però sarà sempre lo stesso, ovvero andremo a fare il binding con l’attributo del controllo XAML il cui valore cambia nel momento in cui interagiamo con esso. Se si tratta di una Textbox, ad esempio, faremo il binding con la proprietà Text; se si tratta di un RadioButton o di un CheckBox, faremo il binding con la proprietà IsChecked e così via.

<TextBox x:Name="txtName" Text="{Binding Source={StaticResource appSettings}, Path=NameSetting, Mode=TwoWay}"></TextBox>
<StackPanel Orientation="Horizontal">
    <RadioButton x:Name="rMale" GroupName="Sex" Content="Male" IsChecked="{Binding Source={StaticResource appSettings}, Path=MaleSetting, Mode=TwoWay}"></RadioButton>
    <RadioButton x:Name="rFemale" GroupName="Sex" Content="Female" IsChecked="{Binding Source={StaticResource appSettings}, Path=FemaleSetting, Mode=TwoWay}"></RadioButton>
</StackPanel>

Come potete vedere, la sintassi è sempre la stessa; in tutti e tre gli esempi andiamo a impostare tre attributi del binding:

  • Source: la sorgente, ovvero la risorsa appSettings che abbiamo definito sopra, che è di tipo StaticResource.
  • Path: il percorso, ovvero nel nostro caso la proprietà della classe appSettings collegata al nostro controllo.
  • Mode: la modalità di binding, nel nostro caso sarà sempre TwoWay (ovvero le due proprietà si influenzano a vicenda, una modifica all’una si ripercuote sull’altra e viceversa).

Il gioco è fatto

Il gioco è fatto: ora proviamo a lanciare la nostra applicazione nell’emulatore, modifichiamo le varie impostazioni e usciamo con il tasto Back (non la sospendiamo perciò, ma la chiudiamo definitivamente). Ora lanciamo nuovamente il debug (o rilanciamo l’applicazione direttamente dall’emulatore, non è necessario riattacare il debugger di Visual Studio per i nostri scopi) e potremo notare che le impostazioni saranno esattamente come le abbiamo lasciate.

E’ stato un lavoro duro, ma ce l’abbiamo fatta. Il tutorial può apparire abbastanza complesso, ma una volta capito il meccanismo è piuttosto semplice. Tra l’altro, come abbiamo visto, i metodi che abbiamo scritto nella classe AppSettings non contengono riferimenti a controlli specifici: i metodi AddOrUpdateValue e GetValueOrDefault sono generici e perciò possiamo riutilizzare la classe in qualsiasi applicazione che andremo a realizzare. Dobbiamo semplicemente ricordarci di definire due costanti (una con la chiave e una con il valore di default) per ognuno dei nostri settings e definirne la proprietà da mettere in binding con il controllo.

Nel prossimo post concluderemo il discorso sulla classe IsolatedStorageSettings mostrando come possiamo utilizzare questa classe anche per implementare lo scenario visto nel primo post, ovvero la possibilità di aggungere un pulsante di conferma prima di salvare le nostre impostazioni.


Windows Phone , Microsoft , Isolated Storage

4 comments

WPC Tech Days: un’occasione di formazione su Windows Phone (e non solo)

Print Content | More

368x242

Mi permetto di “interrompere” il tutorial sull’Isolated Storage per parlarvi dei Tech Days, l’appuntamento che avrà inizio domani ad Assago rivolto a tutti gli sviluppatori italiani. Si tratta probabilmente della più grande conferenza ufficiale italiana targata Microsoft, che si articolerà in 3 giorni di sessioni (tecniche e non) sugli argomenti più disparati, sia legati al mondo IT (virtualizzazione, Window Server, Exchange Online, ecc.) che al mondo dello sviluppo (Azure, Windows Phone, Entitiy Framework, ecc.).

Prima di tutto, voglio augurare un grosso in bocca al lupo ai tanti amici (MVP e non) che parteciperanno come speaker alla conferenza!

Non sto qui a parlarvi in dettaglio di tutte le sessioni che verranno proposte: a questo proposito vi rimando all’agenda pubblicata sul sito ufficiale.

Quello che vorrei fare in questo post è segnalarvi tutte le sessioni di interesse per chi come me si occupa di sviluppo di applicazioni per Windows Phone 7. Prima di lasciarvi all’elenco, vi segnalo che Mercoledì 24 Novembre sarò presente anche io durante i coffee break e la pausa pranzo nell’area dedicata all’Ask the expert per rispondere alle vostre domande su Windows Phone.

23 Novembre: 14 – 15:15
Blend 4 for developers

Non è una sessione specifica della track su Windows Phone, ma i temi che verranno trattati sono di sicuro interesse anche per chi sviluppa applicazioni mobile: il mio amico e collega Corrado infatti parlerà di come Blend può essere d’aiuto non solo ai designer, ma anche agli sviluppatori di applicazioni Silverlight e WPF. Inoltre Corrado, negli ultimi mesi, si è occupato in Gaia proprio di applicazioni Windows Phone e porterà quindi tutta la sua esperienza in questo campo.

23 Novembre: 15:30 – 16:45
Architettura e Introduzione allo sviluppo per Windows Phone 7

Sessione introduttiva a cura di Lorenzo Barbieri su cosa significa sviluppare applicazioni per Windows Phone 7 utilizzando XNA e Silverlight all’interno di Visual Studio.

23 Novembre: 9 – 10:15
Expression Blend for Windows Phone 7

Una sessione rivolta soprattutto a chi si occupa di design: Roberto Cavallini spiegherà cosa significa utilizzare Expression Blend per realizzare la UI delle applicazioni Windows Phone.

24 Novembre: 9 - 10:15
Migliorare le proprie applicazioni con i servizi "in the cloud" di Windows Phone 7

In questa sessione Michele Locuratolo (MVP nella categoria Windows Phone Development) parlerà di tutti i servizi in the cloud messi a disposizione agli sviluppatori per migliorare le proprie applicazioni: XBox Live, Push notifications, servizi di geolocalizzazione, ecc.

24 Novembre: 12 – 13:15
Microsoft Push Notification Service: un nuovo modo di interagire con gli utenti

Durante la sessione (sempre a cura di Michele Locuratolo) verrà approfondito il tema delle push notification su Windows Phone, con una serie di esempi pratici e concreti su come implementarle nelle nostre applicazioni.

24 Novembre: 9 – 10:15
Model View ViewModel applied in a WPF, Silverlight and Windows Phone 7 world

Sessione molto interessante di Mauro Servienti su MVVM, uno dei pattern di sviluppo più utilizzati nel mondo Silverlight / WPF. Il tema è trasversale a tutti e 3 i mondi, dato che l’implementazione è praticamente la stessa sia su Silverlight che su WPF che in Windows Phone (con le dovute differenze, ad esempio nel mondo Windows Phone non esiste il concetto di Command, introdotto in Silverlight 4). Unico neo di questa sessione: è in contemporanea con quella di Michele Locuratolo sull’utilizzo dei servizi on the cloud.

24 Novembre: 10:30 – 11:45
Applicazioni Windows Phone 7 Data-Oriented

In questa sessione Sandro Vecchiarelli parlerà di come gestire i dati nelle applicazioni Windows Phone: RIA Services, Cloud computing, Isolated Storage, ecc.

25 Novembre: 12 – 13:15
Pubblicare un’applicazione sul Marketplace di WP7 al primo colpo: tips & tricks

Un’altra sessione a cura di Roberto Cavallini dedicata alla pubblicazione delle applicazioni sul Marketplace: verranno dati una serie di consigli e best practices su come utilizzare l’App Hub e su come affrontare i problemi più comuni che possono emergere in fase di pubblicazione.

25 Novembre: 15:30 – 16:45
Sviluppare videogame per Windows Phone 7

Sessione a cura di Giuseppe Maggiore in cui verrà approfondita la programmazione di videogiochi per Windows Phone utilizzando XNA come framework di sviluppo.


Windows Phone , Microsoft , Tech Days

1 comments

Isolated Storage: memorizziamo i settings della nostra applicazione – Parte 1: un primo approccio

Print Content | More

Dopo aver visto un’infarinatura sull’Isolated Storage, siamo pronti per iniziare ad utilizzarlo per salvare le impostazioni della nostra applicazione. Se si trattasse di una applicazione desktop tradizionale, una delle scelte migliori per un’esigenza di questo tipo sarebbe il formato XML: potremmo salvare su disco un file XML con le nostre impostazioni, da leggere in fase di avvio. .NET usa proprio questo meccanismo nelle applicazioni, supportando dei file di configurazione (tipicamente con estensione .config) e mettendoci a disposizione il dictionary ConfigurationManager.AppSettings per leggere e scrivere agilmente questo file (senza doverci preoccupare di creare a mano l’XML o di fare il parsing manuale per leggere le informazioni).

La classe IsolatedStorageSettings fa la stessa cosa: questa classe, infatti, ci mette a disposizione un dictionary, dove possiamo memorizzare delle coppie chiave / valore. La differenza rispetto al dictionary ConfigurationManager.AppSettings è che, trattandosi di un file XML, possiamo inserire solo coppie chiave / valore definite come string, string, mentre tramite la classe IsolatedStorageSettings possiamo memorizzare coppie definite come string, object.

Come utilizzare la classe IsolatedStorageSettings

Per iniziare ad utilizzare la classe IsolatedStorageSettings, non dobbiamo far altro che inizializzarla in questo modo:

IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;

Dopodichè possiamo iniziare a scrivere e leggere dall’oggetto settings come facciamo con qualsiasi altro dictionary. Vedremo ora due modi differenti di gestire i settings della nostra applicazione.

Il modo più semplice : gestiamo tutto nel code behind

Il metodo più semplice e veloce per utilizzare la classe IsolatedStorageSettings è di costruire il nostro form con le impostazioni per configurare la nostra applicazione e gestire le operazioni di scrittura / lettura direttamente nel code behind. Nello specifico, quello che andremo a fare sarà:

  • Leggere i dati dall’oggetto settings quando la pagina viene inizializzata.
  • Inserire un pulsante di conferma per salvare le impostazioni; quando viene premuto, i dati vengono salvati nell’oggetto settings.

Facciamo una prova realizzando una semplice applicazione, che permetta di configurare il nome, il sesso e e le tecnologie di sviluppo Microsoft conosciute dall’utente. Apriamo Visual Studio 2010, creiamo un nuovo progetto di tipo Silverlight for Windows Phone e, nel file MainPage.xaml, inseriamo il seguente codice nella ContentGrid:

<StackPanel Margin="5">
    <TextBlock Text="Name"></TextBlock>
    <TextBox x:Name="txtName"></TextBox>
    <TextBlock Text="Sex"></TextBlock>
    <StackPanel Orientation="Horizontal">
        <RadioButton x:Name="rMale" GroupName="Sex" Content="Male"></RadioButton>
        <RadioButton x:Name="rFemale" GroupName="Sex" Content="Female"></RadioButton>
    </StackPanel>
    <TextBlock Text="Knowledge"></TextBlock>
    <StackPanel Orientation="Horizontal">
        <CheckBox x:Name="cbAsp" Content="ASP.NET"></CheckBox>
        <CheckBox x:Name="cbSilverlight" Content="Silverlight"></CheckBox>
    </StackPanel>
    <Button x:Name="btnSave" Content="Save settings" Click="btnSave_Click"></Button>
</StackPanel>

Come potete intuire, le tre impostazioni vengono gestite in tre modi diversi:

  • Il nome viene chiesto tramite una Textbox
  • Il sesso viene chiesto tramite due RadioButton (dato che si tratta di una scelta esclusiva)
  • La tecnologia di sviluppo conosciuta viene chiesta tramite due Checkbox (dato che l’utente può anche scegliere entrambe)

Ecco il codice con cui andiamo a salvare, con il click sul pulsante, le varie impostazioni:

private void btnSave_Click(object sender, RoutedEventArgs e)
{
    IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
    //Name
    if (settings.Contains("Name"))
        settings.Remove("Name");
    settings.Add("Name", txtName.Text);
    
    //Sex
    string sex = string.Empty;

    if (rMale.IsChecked==true)
        sex = "Male";
    if (rFemale.IsChecked == true)
        sex = "Female";

    if (settings.Contains("Sex"))
        settings.Remove("Sex");
    settings.Add("Sex", sex);

    List<string> knowledge=new List<string>();
    if (cbAsp.IsChecked==true)
        knowledge.Add("ASP.NET");
    if (cbSilverlight.IsChecked==true)
        knowledge.Add("Silverlight");

    if (knowledge.Count > 0)
    {
        if (settings.Contains("Knowledge"))
            settings.Remove("Knowledge");
        settings.Add("Knowledge", knowledge);
    }

    settings.Save();
}

Il codice è piuttosto semplice da capire: per ognuna delle impostazioni, andiamo a salvare nell’oggetto settings una chiave con il relativo valore. Come possiamo vedere nel caso della chiave Knowledge, abbiamo la possibilità di salvare non solo semplici stringhe (come nel caso delle chiavi Name e Sex) ma anche veri e propri oggetti (nel caso specifico, una collezione di tipo List). Il metodo Save(), chiamato alla fine, forza il salvataggio dei dati: in condizioni normali, infatti, il salvataggio avviene in automatico nel momento in cui la pagina viene chiusa. Se l’applicazione però viene sospesa, rischiamo di perdere tutto anche se l’utente ha già premuto il pulsante Save Settings.

Dato che in un dictionary non possiamo inserire due volte la stessa chiave, dobbiamo sempre ricordarci di verificare se questa esiste già e, in caso affermativo, eliminarla prima di aggiungere il valore.

Ecco invece il codice con cui andiamo a leggere, in fase di inizializzazione della pagina, i settings:

private void LoadSettings()
{
    IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
    if (settings.Contains("Name"))
        txtName.Text = settings["Name"].ToString();

    if (settings.Contains("Sex"))
    {
        string sex = string.Empty;
        sex = settings["Sex"].ToString();

        switch (sex)
        {
            case "Male":
                rMale.IsChecked = true;
                break;
            case "Female":
                rFemale.IsChecked = true;
                break;
        }
    }

    if (settings.Contains("Knowledge"))
    {
        List<string> knowledge = (List<string>) settings["Knowledge"];
        if (knowledge.Contains("ASP.NET"))
            cbAsp.IsChecked = true;
        if (knowledge.Contains("Silverlight"))
            cbSilverlight.IsChecked = true;
    }
        
}

Come potete vedere, anche questo codice è piuttosto semplice da capire: se il dictionary contiene le tre chiavi Name, Sex e Knowledge, ne recuperiamo il valore e lo utilizziamo per impostare opportunamente il controllo.

La caratteristica del sistema che abbiamo appena visto è che le impostazioni non vengono salvate fino a che non premiamo il pulsante Save settings: sta a noi decidere se questo è un vantaggio o uno svantaggio. Il punto di forza è che l’utente ha modo di annullare le modifiche che ha fatto, nel caso cambi idea: basta che prema il pulsante Back per tornare alla pagina precedente senza salvare le impostazioni. Il punto debole è che siamo costretti a salvare in un tombstone ogni impostazione: il rischio, infatti, è che l’utente perda le modifiche nel caso in cui l’applicazione venga sospesa.

Il modo che abbiamo visto per gestire i settings, però, è un po’ “grezzo”: nel prossimo post vedremo un approccio alternativo, più pulito e che ci permette, volendo, di sfruttare, il binding di Silverlight. Scopo di questo post, infatti, era quello di farvi familiarizzare con la classe IsolatedStorageSettings, così da capirne i meccanismi di scrittura e lettura.

Di seguito trovate il codice d’esempio di questa applicazione.


Windows Phone , Microsoft , Isolated Storage

1 comments

Isolated Storage: una panoramica iniziale

Print Content | More

gnome-dev-harddisk_l

Nei tutorial che ho pubblicato in precedenza abbiamo visto in lungo e in largo come salvare i dati temporanei della nostra applicazione grazie al concetto di tombstoning. Ma per quanto riguarda i dati permanenti?  Iniziamo oggi perciò a parlare di Isolated Storage, ovvero lo spazio messo a disposizione da Windows Phone 7 per salvare in maniera permanente i dati della nostra applicazione.

Quando abbiamo parlato di launchers & choosers, vi ho spiegato come le applicazioni Windows Phone 7 girino in una sandbox, ovvero siano isolate l’una dall’altra. Questo significa che anche lo spazio di memoria utilizzato dalla nostra applicazione è isolato: possiamo pensare allo storage di Windows Phone come ad un disco fisso, dove ad ogni applicazione corrisponde una cartella diversa. La differenza con un file system tradizionale è che la nostra applicazione non ha alcun modo di accedere ad altre cartelle: può solo leggere e scrivere dati all’interno di quella che gli è stata assegnata.

L’Isolated Storage rappresenta proprio questa cartella: è lo spazio in cui una applicazione Windows Phone può scrivere dati che verranno memorizzati in maniera permanente, fino a quando questa non verrà disinstallata. Al contrario di launchers & choosers e del tombstoning, non si tratta di una novità di Windows Phone: il concetto di Isolated Storage deriva direttamente da Silverlight e può essere utilizzato nelle applicazioni che girano Out Of Browser per memorizzare dati.

La differenza principale tra le due tecnologie è che in Silverlight è possibile fissare lo spazio che andrà ad occupare la nostra applicazione e, previa autorizzazione dell’utente, eventualmente aumentarlo. Su Windows Phone ciò non è possibile: il massimo spazio utilizzabile è di 2 GB e la funzione che vi permette di aumentare lo spazio disponibile restituirà sempre un eccezione.

Cosa possiamo memorizzare nell’Isolated Storage?

La risposta è semplice: qualsiasi cosa. La caratteristica dell’Isolated Storage è quella di isolare lo spazio, ma per il resto è un file system tradizionale, che può contenere file e cartelle di qualsiasi tipo. Windows Phone ci mette a disposizione le seguenti classi per memorizzare dati nell’Isolated Storage:

  • IsolatedStorageFile: rappresenta il nostro spazio di archiviazione. Quando creiamo un’instanza di questa classe, abbiamo a disposizione i classici metodi per lavorare con un file system: creare e cancellare cartelle o file, verificare l’esistenza di una cartella o di un file specifico, ecc.
  • IsolatedStorageFileStream: rappresenta un file all’interno dell’Isolated Storage. Quando dobbiamo lavorare con un file (ad esempio, leggere un file XML per recuperare i dati memorizzati o scrivere delle informazioni) lo dobbiamo caricare in uno stream di questo tipo.
  • IsolatedStorageSettings: è una classe speciale che ci permette di leggere e scrivere in maniera semplice e intuitiva i settings della nostra applicazione.

What’s next?

Ecco alcuni degli argomenti legati all’Isolated Storage che vedremo nei prossimi post:

  • Come utilizzare la classe IsolatedStorageSettings per memorizzare le impostazioni della nostra applicazione.
  • Come leggere e scrivere file all’interno dell’Isolated Storage.
  • Come utilizzare la classe XmlSerialization messa a disposizione dal framework per memorizzare in maniera semplice i dati della nostra applicazione nell’Isolated Storage.
  • Come gestire il salvataggio dei dati in maniera permanente quando la nostra applicazione viene sospesa o riattivata.


Windows Phone , Microsoft , Isolated Storage

0 comments

Come intercettare il traffico di rete dell’emulatore Windows Phone 7 con Wireshark

Print Content | More

blog

Premessa: se seguite regolarmente il mio blog saprete che ho sviluppato un piccolo client che permette di gestire con Windows Phone 7 il proprio blog, dando la possibilità di guardare gli ultimi post e di pubblicarne uno nuovo. Per fare ciò, uso un’interfaccia messa a disposizione dalla maggior parte dei blog engine (Dexter incluso) chiamata Metaweblog API. Si tratta di un’interfaccia basata sul formato XML-RPC, che prevedo l’invio di chiamate POST HTTP in cui spediamo degli XML stutturati con delle regole ben precise e riceviamo, come risposta, un altro XML.

In ambito web ci sono delle ottime librerie per utilizzare il formato XML-RPC: Microsoft stessa propone sul sito MSDN (potete leggere la guida qui) un tutorial su come utilizzare la libreria Xml-Rpc.Net per supportare l'interfaccia Metaweblog API all’interno delle proprie applicazioni. Purtroppo tale libreria non è utilizzabile in un’applicazione Windows Phone 7, dato che Silverlight è un ambiente fortemente asincrono: non possiamo perciò inviare le richieste XML-RPC come faremmo su un sito web, ma dobbiamo gestire il fatto che una volta lanciata la richiesta riceveremo la risposta tramite un evento di callback che viene eseguito in un altro thread.

L’unica libreria già pronta che ho trovato compatibile con Silverlight si chiama XML-RPC for Silverlight, che però non supporta pienamente la Metaweblog API: alcuni tipi di dati infatti, nella generazione dell’XML, vengono creati con una struttura dati differente da quella richiesta dalle specifiche del formato. Non sto qui a dilungarmi troppo, in un altro post vi racconterò come ho fatto a risolvere il problema. Quello che conta (ed è l’argomento di questo post) è che ad un certo punto ho avuto bisogno di vedere il traffico di rete che usciva dall’emulatore Windows Phone, per capire l’XML che veniva generato dalla libreria e confrontarlo con quello definito dalle specifiche.

Il primo pensiero (grazie anche ad un suggerimento su Twitter di Raffaele Rialdi) è stato quello di utilizzare Fiddler, uno dei tool più utili in circolazione per chi sviluppa applicazioni web: si tratta di un’analizzatore che logga tutto il traffico HTTP che entra ed esce dal nostro computer e che ci consente di vedere in dettaglio ogni singola richiesta. Lancio perciò Fiddler, eseguo la mia applicazione sull’emulatore e pubblico un nuovo post: con mia grande sorpresa, viene sollevata un’eccezione, la cui descrizione mi fa capire che il mio client non riesce a collegarsi ad Internet. Incuriosito, provo a lanciare Internet Explorer sull’emulatore, digito l’indirizzo di un sito qualsiasi e anche qui la connessione fallisce. Chiudo Fiddler e riprovo: come per magia questa volta funziona tutto!

Il problema è dato da un’incompatibilità tra Fiddler e l’emulatore, che nella versione attuale non riesce ad effettuare il redirect del traffico sul proxy di sistema, anzi, ne blocca completamente l’accesso impedendo all’emulatore di collegarsi ad Internet.

La soluzione che ho trovato si chiama Wireshark ed è anch’esso un’analizzatore di rete che però, a differenza di Fiddler, intercetta tutto il traffico in entrata e in uscita dal vostro computer, non solo i pacchetti HTTP. Wireshark però, al contrario di Fiddler, riesce ad intercettare il traffico in entata e in uscita anche dall’emulatore Windows Phone 7. Vediamo come utilizzarlo!

Installazione e download

Possiamo scaricare Wireshark dal sito ufficiale: lanciamo l’installer e installiamo tutti i pacchetti che ci vengono proposti, che serviranno all’applicazione per analizzare tutto il traffico.

Intercettiamo il traffico

Lanciamo il programma: questa sarà la schermata che ci verrà presentata.

main

A questo punto siamo pronti per iniziare a intercettare il traffico dati in entrata e in uscita dal nostro computer: nella sezione Interface List vengono elencate tutte le schede di rete presenti nel nostro computer. Clicchiamo su quella che ci interessa e il programma partirà in automatico l’intercettazione: come detto in precedenza, Wireshark intercetterà tutto il traffico, non solo quello HTTP, perciò vedremo una notevole quantità di dati passare per l’applicazione. A questo punto possiamo tornare all’emulatore ed eseguire le operazioni che lanceranno il trasferimento dati che vogliamo intercettare (nel mio caso, la pubblicazione di un nuovo post sul blog).

Come trovare l’informazione che serve a noi?

traffic

Ecco un esempio di quello che vedremo una volta avviata l’intercettazione: come potete vedere, rispetto a Fiddler è molto più complesso capire quali sono le informazioni che ci servono, dato che vedremo ogni singolo pacchetto uscito o entrato dal nostro computer, incluso il traffico UDP e TCP. Come possiamo perciò trovare quello che serve a noi?

Innanzitutto una volta che sull’emulatore abbiamo completato le operazioni che vogliamo tracciare possiamo fermare l’analisi del traffico: per farlo andiamo nel menu Capture e scegliamo Stop (oppure premiamo CTRL-E). Ora possiamo iniziare la ricerca dei pacchetti che ci interessano. Abbiamo due strumenti a disposizione per farlo:

  • I filtri: scegliamo dal menu Analyze la voce Display filters. Il programma ci mette a disposizione una serie di filtri già preimpostati per i principali protocolli: in questo modo se, ad esempio, la nostra applicazione ha generato traffico HTTP (come nel caso del mio client) potremo eliminare tutti i dati che non ci interessano.
  • La ricerca libera: dal menu Edit scegliamo Find Packet. Questa schermata ci darà la possibilità di ricercare un testo libero all’interno dei pacchetti che sono stati catturati, scegliendo la tipologia di ricerca String. In questo modo se, ad esempio, conosciamo il contenuto della nostra richiesta o l’indirizzo verso cui è stata spedita possiamo cercarla tramite questo strumento. Nel mio caso, dato che la richiesta veniva effettuata verso il mio blog, mi è bastato cercare la stringa qmatteoq.tostring.it per trovare i pacchetti spediti dal mio client Windows Phone.

Una volta selezionato il pacchetto che ci interessa, nella schermata centrale potremo vederne tutti i dettagli: nel caso di una richiesta HTTP, potremo vederne anche il dettaglio con il relativo contenuto (nel mio caso, l’intero XML spedito dal client verso il blog).

http

Il gioco è fatto!

Esiste un’alternativa che vi permette di utilizzare comunque Fiddler, configurandolo come Reverse Proxy: tale soluzione però, al contrario di quella spiegata in questo post, richiede di modificare il codice della nostra applicazione per fare il redirect delle chiamate HTTP verso il reverse proxy esposto da Fiddler. Se volete comunque provare questa strada, trovate una spiegazione dettagliata su come fare in questo post.


Windows Phone , Microsoft , Fiddler , Wireshark

5 comments

Qualche considerazione sulla diatriba Silverlight - HTML5

Print Content | More

Silverlight

Durante la PDC di quest’anno sono iniziate a circolare numerose voci sulla fine di Silverlight: tutto è nato da un’intervista a Bob Muglia, presidente della divisione Servers & Tools di Microsoft, in cui si evidenzia come la strategia della casa di Redmond su Silverlight sia sempre più rivolta al mobile (nello specifico, a Windows Phone). Per quanto riguarda il web, il futuro verso il quale vuole tendere Microsoft è HTML5. Potete leggere l’intervista completa su ZDNet.

Dopo la pubblicazione di questa intervista, sui principali siti di settore nonchè sui vari social network sono iniziati a comparire dei veri e proprio necrologi: tutti erano pronti a dichiare che Silverlight è una tecnologia morta, che è inutile perderci tempo, che l’HTML5 risolverà tutti i problemi di interoperabilità e così via.

Sono convinto anche io che HTML5, per quanto riguarda il web, sia la tecnologia del futuro, grazie alle enormi potenzialità. Trovo però che dichiarare Silverlight una tecnologia morta sia un po’ prematuro: si è parlato tanto di questo argomento nelle ultime settimane, mi permetto perciò di fare solo qualche considerazione sul perchè sia prematuro piuttosto che su quale sia la strategia di Microsoft su Silverlight.

HTML5 è un draft

HTML5 in questo momento non è uno standard, ma una bozza: il W3C ha già detto che ci vorranno anni prima di arrivare ad una specifica standard. Questo vuol dire che tutto può cambiare, che per assurdo HTML5 potrebbe essere anche un fallimento e non vedere mai la luce. Sicuramente non sarà così, grazie agli investimenti che tante software house come Microsoft e Apple stanno facendo in questa direzione, però trattandosi per appunto di una bozza non è ancora una tecnologia su cui si può già fare affidamento al 100%.

HTML5 non ha un’implementazione standard

Allo stato attuale, l’implementazione di HTML5 dei vari browser è tutto fuorchè uno standard: basta vedere le demo che Microsoft e Google hanno rilasciato negli ultimi mesi, che funzionano in maniera corretta solo sui rispettivi browser. Un altro esempio è la tecnologia che Apple ha iniziato ad utilizzare per lo streaming live dei propri eventi, che attualmente funziona solo su Safari su Mac o sui device mobile Apple. Una tecnologia basata su plugin come Flash o Silverlight soffre il problema di aver bisogno di un qualcosa di “esterno” al browser per funzionare correttamente, ma consente un funzionamento uniforme dell’applicazione su tutti i browser e sistemi operativi.

Senza dimenticare, infine, che attualmente il browser più diffuso al mondo, ovvero Internet Explorer 8, non supporta HTML5.

HTML5 non è la soluzione a tutte le esigenze

Allo stato attuale, ci sono tantissime situazioni in cui HTML5 non può sopperire all’uso di Silverlight. Pensiamo ad esempio alla riproduzione video: HTML5 ci permette di inserire contenuti multimediali nella nostra pagina con sforzo minimo senza l’ausilio di plugin, ma solo se si tratta di un semplice video da riprodurre. Qualsiasi scenario più avanzato non è supportato: DRM, full screen, streaming live e adaptive streaming. Pensiamo al player presente sul sito Rai.Tv, oppure a quello utilizzato nel corso della PDC2010 per la trasmissione in streaming del keynote e delle sessioni: realizzare uno scenario simile con HTML5 sarebbe in questo momento impossibile.

HTML5 non ha tool di sviluppo

In questo momento, HTML5 non ha dei tool di sviluppo seri nè per i designer nè per gli sviluppatori. Le potenzialità di HTML5 legate alla grafica e alle animazioni sono incredibili: in questo momento i designer si troverebbero però nella condizione di dover scrivere a mano il codice HTML, CSS  e Javascript per realizzarle, al contrario di quanto avviene adesso con Silverlight e Flash, che mettono a disposizione degli ambienti visuali più adatti allo scopo.

Gli sviluppatori, da parte loro, in questo momento non hanno a disposizione dei tool seri per il testing e il debugging: se avete mai provato a lavorare con l’HTML e con Javascript, saprete meglio di me quanto sia complesso fare debug e scoprire gli errori che impediscono alla pagina di funzionare correttamente. Con Silverlight, invece, lavoriamo direttamente con Visual Studio e possiamo sfruttarne appieno tutte le potenzialità: unit testing, debug, breakpoint, watches sono solo alcuni degli esempi più comuni.

internet-explorer-9

Silverlight non è solo web

Quanto detto da Bob Muglia in realtà non è una novità: già negli ultimi anni Silverlight ha dimostrato di essere una tecnologia non solo per il web. Grazie all’introduzione della funzionalità out-of-browser, sono sempre di più gli sviluppatori che hanno iniziato ad usare Silverlight per realizzare applicazioni che potessero funzionare sia sul web che sul desktop. Pensiamo a Seesmic, celebre client per social network disponibile sia sul web, che come applicazione stand alone che come applicazione mobile, il tutto realizzato con la medesima tecnologia. Anche in Gaia abbiamo utilizzato Silverlight per la realizzazione di diverse applicazioni in cui il web viene solamente utilizzato come “piattaforma di distribuzione”: in realtà, si tratta di applicazioni RIA vere e proprie, che possono essere tranquillamente equiparate ad un’applicazione dekstop tradizionale.

In conclusione

L’HTML5 è una tecnologia decisamente promettente e il fatto che una grande software house come Microsoft abbia deciso di investire così tanto in questa direzione è sicuramente un’ottima cosa: sono sicuro che nel giro di qualche anno inizieremo a vedere tool e tecnologie che renderanno l’approccio con HTML5 più agevole sia per i designer che per gli sviluppatori. Fino a quel momento, e fino a quando HTML5 non diventerà uno standard, tecnologie come Silverlight e Flash continueranno ad essere fondamentali in molti scenari, in virtù di tutte le considerazioni che ho fatto in questo post.

Se volete leggere un parere sicuramente più autorevole del mio, vi consiglio questo post  di Laurent Bignion, MVP su Silverlight, nonchè realizzatore del celebre MVVM Light Toolit (una delle librerie più diffuse che semplifica l’implementazione del pattern MVVM nelle applicazioni Silverlight, WPF e WP7).

Infine, anche alcuni autorevoli personaggi del mondo Microsoft hanno preso posizione: lo stesso Bob Muglia ha pubblicato un post di chiarimento all’intervista sul blog del team di sviluppo di Silverlight, che potete leggere qui. Anche Scott Guthrie ha detto la sua tramite un post sul suo blog. Infine, se volete leggere un commento "ufficiale" Microsoft in Italiano trovate un post sul blog di MSDN Italia a cura di Giuseppe Guerrasio.

Se volete dire la vostra, i commenti al post sono benvenuti Smile


Silverlight , HTML 5

0 comments

Community Tour – La tappa di Bergamo: il resoconto

Print Content | More

180x150_thumb

Brevissimo post per ringraziare Roberto di DotNetLombardia, Mario di Dotnetteria, Alessandro di Umbraco Italia e Lorenzo di Microsoft per l’organizzazione di questo evento e per la possibilità che mi è stata data di contribuire con una sessione sullo sviluppo per Windows Phone 7.

L’evento, a mio avviso, è andato molto bene ed è stato molto interessante: il keynote di Lorenzo ha dato una panoramica generale sulle nuove tecnologie Microsoft (Windows Phone, IE9 ed Azure), tematiche che sono state poi approfondite nelle sessioni successive, assieme ad altri argomenti (come Umbraco e la metodologia DDD).

Degna di nota la location, sia come disponibilità di spazi che come qualità dei servizi offerti. Unico neo della giornata sono stati i tempi molto tirati, dovuti principalmente alle tantissime informazioni da trasmettere durante le sessioni, all’interesse della gente (che ha generato lunghi scambi di domande e risposte) e alla posizione dell’albergo, che rimaneva un po’ isolata e che ha allungato il tempo necessario per il pranzo. Niente che però abbia rovinato la bellezza della giornata!

Rinnovo perciò i miei ringraziamenti, ringrazio ancora una volta Microsoft per il supporto che da alle community organizzando e supportando questi eventi e vi lascio con il link per scaricare sia le slide che ho utilizzato durante la sessione che la piccola demo che ho preparato.

Piccola nota sulla demo: dal codice ho rimosso tutta la parte di collegamento con il servizio ospitato su Azure di Roberto, dato che a breve provvederà a rimuoverlo. E’ rimasta perciò la parte di utilizzo dei chooser e di visualizzazione dell’immagine scelta nell’applicazione.

Scarica le slide


Windows Phone , Community Tour , Microsoft , DotNetLombardia , Dotnetteria , Umbraco Italia , Azure , Internet Explorer 9

2 comments

Nuova release del Silverlight Toolkit for Windows Phone: i controlli LongListSelector e NavigationTransition

Print Content | More

Continuiamo ad esplorare i nuovi controlli introdotti nell’aggiornamento del Silverlight Toolkit per Windows Phone.

LongListSelector

Premessa: a questo controllo dedicherò in futuro un post dedicato, dato che è piuttosto articolato e richiede parecchie informazioni per essere compreso appieno e utilizzato. Vi anticipo solo che anche in questo caso parliamo di un controllo che viene già utilizzato nelle applicazioni native di Windows Phone 7, nello specifico nell’applicazione People. Il LongListSelector è una sorta di ListBox, che però permette di:

  • raggruppare gli elementi per categoria (ad esempio, in People i contatti sono raggruppati per l’iniziale)
  • utilizzare una jump list, ovvero la possibilità di saltare velocemente ad una determinata categoria (sempre in People, se premete su una delle iniziali avete la possibilità di saltare direttamente ai contatti che iniziano con una lettera specifica).
LongListSelector LongListSelector-JumpList

Il concetto di fondo è che nello XAML dovremo specificare i template per:

  • il singolo elemento
  • l’header di ogni categoria
  • la jump list

Dopodichè al componente va “data in pasto” una collection di elementi: dobbiamo però sfruttare LINQ per poter fornire questa collezione già raggruppata per categorie, così che il controllo sappia come suddividere gli elementi.

Se volete già iniziare a studiarlo e a fare qualche esperimento, il toolkit contiene una valida applicazione di esempio che ne mostra il funzionamento.

Transitions

Di default, le pagine di un’applicazione Windows Phone 7 non utilizzano alcuna animazione: quando passate da una vista all’altra, semplicemente quella corrente viene “nascosta” per lasciar spazio a quella nuova. Silverlight, però, consente, grazie anche a strumenti visuali come Blend, di rendere più piacevole l’esperienza d’uso grazie alle animazioni, che non hanno alcuna utilità pratica ma rendono sicuramente più bella da vedere e da utilizzare la nostra applicazione.

Le stesse applicazioni native ne fanno largo uso: pensiamo all’animazione di entrata e uscita di una pagina ogni volta che lanciamo una nuova applicazione, nativa o di terze parti che sia. Fino ad oggi se volevamo implementare anche noi animazioni nella nostra applicazione dovevamo costruirle per conto nostro, usando Blend o creandole a mano nello XAML. La nuova versione del toolkit ci viene in aiuto, mettendoci a disposizione una serie di controlli che ci permettono di implementare le animazioni standard di Windows Phone 7 in maniera molto semplice. Vediamo come!

Il modo più semplice e immediato per introdurre un’animazione nelle nostre pagine è quella di sfruttare il TransitionFrame, che è un oggetto che ci mette a disposizione il toolkit: il frame, in un’applicazione Windows Phone 7, è la “cornice” all’interno della quale noi carichiamo le nostre pagine. Il problema è che il frame che viene utilizzato di default nelle applicazioni Windows Phone (definito dalla classe PhoneApplicationFrame) non supporta le transizioni. Ecco perciò che ci viene in aiuto il TransitionFrame, che va a sostituirsi al PhoneApplicationFrame e ci permette di realizzare animazioni semplicemente inserendo una serie di controlli nello XAML. La prima cosa da fare è perciò aprire il file App.xaml.cs della nostra applicazione (che è il punto di partenza in cui viene inizializzata la nostra applicazione al primo avvio) e posizionarci alla riga 108, dove troveremo il seguente codice:

RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication

Quello che dovremo fare sarà semplicemente sostituire il PhoneApplicationFrame con il TransitionFrame nel seguente modo:

RootFrame = new TransitionFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication

Ora, come direbbe il buon Mauro, siamo abili e arruolati per poter utilizzare le transizioni all’interno della nostra applicazione. Vediamo un esempio di XAML che possiamo utilizzare nelle nostre pagine e che va inserito subito dopo l’inizializzazione della pagina:

<toolkit:TransitionService.NavigationInTransition>
    <toolkit:NavigationInTransition>
        <toolkit:NavigationInTransition.Backward>
            <toolkit:TurnstileTransition Mode="BackwardIn"/>
        </toolkit:NavigationInTransition.Backward>
        <toolkit:NavigationInTransition.Forward>
            <toolkit:TurnstileTransition Mode="ForwardIn"/>
        </toolkit:NavigationInTransition.Forward>
    </toolkit:NavigationInTransition>
</toolkit:TransitionService.NavigationInTransition>
<toolkit:TransitionService.NavigationOutTransition>
    <toolkit:NavigationOutTransition>
        <toolkit:NavigationOutTransition.Backward>
            <toolkit:TurnstileTransition Mode="BackwardOut"/>
        </toolkit:NavigationOutTransition.Backward>
        <toolkit:NavigationOutTransition.Forward>
            <toolkit:TurnstileTransition Mode="ForwardOut"/>
        </toolkit:NavigationOutTransition.Forward>
    </toolkit:NavigationOutTransition>
</toolkit:TransitionService.NavigationOutTransition>

Come possiamo vedere, il toolkit ci mette a dispozione due controlli:

  • <toolkit:TransitionService.NavigationInTransition> per specificare l’animazione che verrà utilizzata quando ci spostiamo verso la pagina corrente.
  • <toolkit:TransitionService.NavigationOutTransition> per specificare l’animazione che verrà utilizzata quando ci spostiamo dalla pagina corrente.

All’interno di ognuno di questi controlli, abbiamo la possibilità di specificare:

  • <toolkit:NavigationInTransition.Backward>: è l’animazione che viene utilizzata quando si arriva alla pagina tramite la pressione del tasto Back.
  • <toolkit:NavigationInTransition.Forward>: è l’animazione che viene utilizzata quando ci si sposta verso un’altra pagina usando il metodo Navigate o GoForward del NavigationService di Silverlight (ovvero la classe che ci permette di gestire lo spostamento tra le pagine all’interno della nostra applicazione).

Infine, l’ultimo step è quello di specificare l'animazione vera e propria che vogliamo ottenere. Possiamo scegliere tra:

  • <toolkit:RollTransition />: viene applicato un effetto di rotazione standard.
  • <toolkit:RotateTransition />: viene applicato un effetto di rotazione, personalizzabile impostando l’attributo Mode (esempi di valori supportati: In180Clockwise, Out90Counterclockwise, ecc.).
  • <toolkit:SlideTransition />: viene applicato un effetto di “scivolamento”, personalizzabile impostando l’attributo Mode (esempi di valori supportati: SlideDownFadeIn, SlideUpFadeIn)
  • <toolkit:SwivelTransition />: viene applicato un effetto di rotazione sull’asse verticale, anch’esso personalizzabile tramite l’attributo Mode (esempi di valori supportati: BackwardIn, ForwardIn).
  • <toolkit:TurnstileTransition/>: viene applicato un efetto di “sfogliamento” della pagina (come se si trattasse di un libro), personalizzabile tramite l’attributo Mode (esempi di valori supportati: BackwardIn, ForwardOut).

Per dare alla vostra applicazione un look coerente, una buona regola è quella di scegliere un solo tipo di animazione e utilizzarla in tutte le pagine. Questa regola vale ancora di più se stiamo parlando di due pagine collegate: in questo caso, è indispensabile utilizzare le stesse animazioni di entrata e di uscita, altrimenti si corre il rischio di generare confusione.

E’ possibile gestire le animazioni anche da codice, sfruttando le classi messe a disposizione dal Toolkit: il file TransitionSample.xaml.cs del progetto di esempio vi mostrerà come.

In conclusione

Abbiamo visto in dettaglio i nuovi controlli messi a disposizione dal toolkit: anche in questo caso non ho realizzato un progetto di esempio, dato che il Toolkit ne include già uno decisamente ben fatto.


Windows Phone , Windows Phone Toolkit , Microsoft

0 comments

Nuova release del Silverlight Toolkit for Windows Phone: i controlli AutoCompleteBox e ListPicker

Print Content | More

Microsoft ha rilasciato una nuova versione del Silverlight Toolkit for Windows Phone, con una serie di novità decisamente succose: sono stati introdotti infatti diversi nuovi controlli che torneranno sicuramente utili per chi sviluppa applicazioni per Windows Phone.

Dato che i nuovi controlli sono un po’ più articolati, ho deciso di dividere il post in due parti: in questa prima parte vedremo i controlli AutoCompleteBox e ListPicker, nella seconda parte vedremo invece i controlli LongListSelector e NavigationTransition.

Prima di iniziare, vi ricordo l’indirizzo del sito ufficiale dal quale potete scaricare il Toolkit: http://silverlight.codeplex.com/. Il pacchetto è disponibile in due formati: eseguibile (sotto forma di pacchetto MSI), il quale installerà le librerie e la documentazione nel percorso C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.0\Toolkit\Nov10, e file compresso, che contiene tutti i sorgenti e include anche un utile progetto di esempio.

AutoCompleteBox

Questo nuovo controllo si presenta come una normale TextBox: nel momento però in cui iniziamo a digitare del testo, si aprirà un’area in cui vi verranno suggerite delle parole in base a quanto avete scritto.

Ecco un esempio di come questo controllo viene definito nello XAML:

<toolkit:AutoCompleteBox x:Name="autocomplete" ItemsSource="{Binding Path=Words}"></toolkit:AutoCompleteBox>

Il controllo espone una proprietà ItemsSource (esattamente come una ListBox) alla quale deve essere assegnata una collection di stringhe (è indifferente che si tratti di una List o di una ObservableCollection, l’importante è che implementi l’interfaccia ICollection): tale collezione conterrà le parole che veranno utilizzate come suggerimento per l’autocompletamento.

Ecco un esempio di codice di una view in cui viene inizializzata una collection di stringhe e assegnata come ItemsSource del controllo:

public AutoComplete()
{
    InitializeComponent();
    ObservableCollection<string> words = new ObservableCollection<string>
                                             {
                                                 "Mauro",
                                                 "Ugo",
                                                 "Matteo",
                                                 "Giorgio"
                                             };
    autocomplete.ItemsSource = words;
}

Utilizzando il codice riportato nell’esempio, nel momento in cui inserirete la lettera M nel controllo, l’autocompletamento vi mostrerà in automatico gli elementi “Mauro” e “Matteo”: con un tap potrete selezionarli e inserirli senza dover scrivere il nome completo.

Autocomplete

ListPicker

In questo caso parliamo di un controllo che è già utilizzato dalle applicazioni native di Windows Phone 7, che però non era ancora disponibile per gli sviluppatori. Il ListPicker appare come una normale Textbox, che però quando viene selezionata diventa una sorta di dropdown, che ci permette di selezionare un elemento da una lista. La particolarità di questo controllo è che in grado di utilizzare due modalità di visualizzazione diverse a seconda del numero di elementi:

  • Da 1 a 5 elementi, il controllo si espande direttamente nella pagina stessa.
  • Da 5 elementi in su, la lista di elementi viene visualizzata in una pagina separata.

In entrambi i casi, il risultato sarà lo stesso: l’elemento selezionato comparirà nella TextBox.

Possiamo vedere un esempio di ListPicker con entrambe le modalità nella sezione Settings di Windows Phone 7, nello specifico nella schermata che ci permette di impostare il tema del telefono. Le opzioni su cui possiamo agire sono:

  • Background: ci permette di selezionare tra tema dark e tema light. In questo caso gli elementi della lista vegnono visualizzati nella pagina stessa, dato che sono solamente 2.
  • Accent Color: ci permette di scegliere il colore degli elementi del telefono. In questo caso gli elementi della lista vengono visualizzati in una pagina dedicata, dato che sono più di 5.
ListPicker-Short ListPicker-Long

Anche in questo caso il controllo supporta la proprietà ItemsSource, che accetta una collezione di elementi che verrà mostrata nella lista: ci penserà il controllo in automatico a scegliere la modalità di visualizzazione più adatta in base al numero di elementi.

Vediamo ora due esempi di ListPicker: il primo è quello più semplice, in cui utilizziamo il layout grafico di default e inseriamo (direttamenta nello XAML) una serie di elementi da mostrare.

<toolkit:ListPicker Header="background">
    <sys:String>dark</sys:String>
    <sys:String>light</sys:String>
    <sys:String>dazzle</sys:String>
</toolkit:ListPicker>

Il secondo esempio invece mostra un ListPicker nel quale definiamo un layout grafico personalizzato per ognuna delle due modalità di visualizzazione:

  • <toolkit:ListPicker.ItemTemplate> definisce il template utilizzato quando ci sono pochi elementi.
  • <toolkit:ListPicker.FullModeItemTemplate definisce il template utilizzando quando ci sono molti elementi.
<toolkit:ListPicker ItemsSource="{Binding}" Header="accent color" FullModeHeader="ACCENTS" CacheMode="BitmapCache">
<toolkit:ListPicker.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal">
            <Rectangle Fill="{Binding}" Width="24" Height="24"/>
            <TextBlock Text="{Binding}" Margin="12 0 0 0"/>
        </StackPanel>
    </DataTemplate>
</toolkit:ListPicker.ItemTemplate>
<toolkit:ListPicker.FullModeItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal" Margin="16 21 0 20">
            <Rectangle Fill="{Binding}" Width="43" Height="43"/>
            <TextBlock Text="{Binding}" Margin="16 0 0 0" FontSize="43" FontFamily="{StaticResource PhoneFontFamilyLight}"/>
        </StackPanel>
    </DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>

Anche in questo caso, possiamo rifarci alla sezione Theme dell’applicazione Settings per vedere entrambi gli utilizzi: nel caso della scelta del Background viene utilizzato un ListPicker standard (infatti il controllo mostra semplicemente il nome dell’elemento), nel caso della scelta dell’Accent Color viene utilizzato un ListPicker con un template custom (infatti a fianco del nome viene mostrato anche un rettangolo con il colore stesso).

In conclusione

Nel prossimo post vedremo gli altri due nuovi controlli introdotti nel toolkit: al contrario degli altri post tecnici che ho scritto negli ultimi mesi, questa volta non vi fornirò un progetto d’esempio, dato che in questa pagina potete scaricare il codice sorgente del Toolkit che, tra le altre cose, include un progetto d’esempio in cui vengono mostrati alcuni casi d’uso dei vari controlli.


Windows Phone , Windows Phone Toolkit , Microsoft

0 comments