Parte uno, Sqlite in Windows Phone 8.1

      Nessun commento su Parte uno, Sqlite in Windows Phone 8.1

Introduzione
In questo primo articolo, faremo un’introduzione a uno strumento molto importante legato alla memorizzazione dei dati in maniera permanente nello storage del nostro dispositivo. Da sviluppatori, sapete bene che il supporto alla memorizzazione delle informazioni che siano impostazioni, o dati di altro tipo é molto importante. Al momento il Windows Runtime non dispone in maniera nativa il supporto ai Database, ma mette a disposizione la possibilità di serializzare/deserializzare i dati in diversi formati: xml e json. Seppur molto importanti e di semplice utilizzo, lo svantaggio è che tutte le informazioni devono comunque essere mantenute in memoria a scapito di rallentamenti e impatto sulle performance della nostra applicazione. Per questo motivo, torna utile l’approccio all’utilizzo del Database; un’ottima scelta è di ricorrere a Sqlite. Sqlite è un engine open source, creato e supportato dalla SQLite Consortiun supportato dal Windows Runtime grazie anche alla compatibilità con C++. Scritto in C++, garantisce ottime performance a livello di esecuzione e di qualunque operazione eseguiamo, lavora in modalità dati disconnessa, a differenza per esempio di Sqlserver, dove esiste un servizio chiamato DBMS per l’interazione con i dati. E’ multipiattaforma, quindi oltre Windows Phone Store, è compatibile con Windows Store, Android e altre piattaforme. Infine, è possibile utilizzare alcuni exstension methods di Linq (Language Integrated Query), per la precisione LinqToObject, che vedremo nel corso dell’articolo. Fino ad ora, è stata fatta una semplice introduzione su che cosa è Sqlite, ma per maggiori dettagli e delucidazioni, rimando alla fonte ufficiale. In quest’articolo vedremo nell’ordine:

  • Installazione dell’engine di Sqlite
  • Creazione del progetto
  • Installazione di Sqlite-Net
  • Creazione della classe per il Database
  • Inserimento dei dati
  • Aggiornamento dei dati
  • Eliminazione dei dati
  • Altre classi necessarie
  • Inserimento dei namespace necessari
  • Architettura di compilazione
  • Test dell’applicazione
  • Conclusione

Installazione dell’engine di Sqlite
Prima cosa da fare, non essendoci, come detto, il supporto ai dati in Windows Runtime, vanno installate alcune estensioni per interagire con Sqlite. La prima la troviamo a questo link. Facciamo attenzione a una cosa, in questo caso, installeremo l’estensione adatta a Windows Phone Store, ma se volessimo sviluppare un’applicazione Windows Store, dobbiamo installare l’engine adatto, poiché se abbiamo un progetto Universal App, si tratta non di una singola applicazione, ma siamo di fronte a un progetto che creerà alla fine due applicazioni distinte per piattaforma. Una volta scaricato e installato, lo aggiungeremo al progetto che pian piano andremo a creare nel corso dell’articolo.
Creazione del progetto
E’ arrivato il momento di creare il nostro progetto di esempio. Avviamo VisualStudio 2013, nel mio caso uso la versione professional. Dal menù File, selezioniamo “Nuovo” e subito dopo “Progetto”. Creeremo un’applicazione usando come linguaggio di sviluppo C#. Nei template disponibili alla sezione “Applicazioni Windows Phone”, selezioniamo “Applicazione vuota (Windows Phone)” e assegniamo al progetto il nome “Sqlite Sample” come visibile in figura.

image thumb1 - Parte uno, Sqlite in Windows Phone 8.1
Immagine 1.1 I template disponibili per lo sviluppo su Windows Phone.

Attendiamo che l’ambiente di sviluppo sia inizializzato correttamente, e come anticipata nell’introduzione, andiamo ad aggiungere tutte le estensioni necessarie per interagire con Sqlite. Prima cosa, aggiungiamo il riferimento all’engine per Windows Phone, in esplora soluzioni, click con il tasto destro del Mouse su “Riferimenti”, e andiamo a selezionare “Aggiungi riferimento”. Nella finestra di dialogo successiva, sulla sinistra espandiamo la sezione “Estensioni”, se abbiamo installato correttamente l’engine, lo troveremo tra le estensioni disponibili, come mostrato in figura.

Ad
image thumb3 - Parte uno, Sqlite in Windows Phone 8.1
Immagine 1.2 L’engine di Sqlite per Windows Phone 8.1.

Adesso in concomitanza alla stesura dell’articolo la versione è la 3.8.7.4, per cui tutte le esercitazioni saranno con questa versione. Al momento, abbiamo installato il primo dei due elementi necessari, questo perché l’engine in se é scritto in C++, per cui per interagire richiederebbe che il progetto sia C++, dando poi non pochi problemi per chi non conosce tale linguaggio, o se abbiamo incluso il tutto in un progetto C# come nel nostro caso. Per questo motivo, sono state create delle librerie da diversi sviluppatori, in grado di astrarre quello che è in realtà l’engine di Sqlite, attraverso una serie di metodi e classi che aiutano lo sviluppatore a interagirne scrivendo codice con linguaggi di alto livello come C# e VB NET. Una di queste librerie si chiama Sqlite-net.
Installazione dell’engine di Sqlite-net
Con tale libreria, saremo in grado di eseguire tutte le operazioni che si fanno normalmente in un Database, come Insert, Delete, Update ed eseguire delle query di ricerca. Sqlite-net inoltre, offre un approccio tipico dell’Orm, si prenda come esempio LinqToSql o l’ultimo attuale EntityFramework. In più, ha il supporto a LinqToObject, per cui è possibile eseguire delle ricerche su collezioni di oggetti come Liste e ObservableCollection. Per maggiori dettagli, rimando alla documentazione ufficiale ed esempi che trovate a questo link. Essendo come detto una libreria di terze parti, dobbiamo aggiungerla al nostro progetto. Il modo più semplice è ricorrere a Nuget. Ritorniamo al nostro progetto, sempre in “Riferimenti”, tasto destro del mouse, selezioniamo il comando “Gestisci pacchetti Nuget”. Nella finestra di dialogo successiva, digitiamo nella casella di ricerca che troviamo in alto a destra “Sqlite-net”, come visibile in figura.

image thumb5 - Parte uno, Sqlite in Windows Phone 8.1
Immagine 1.3 La libreria Sqlite-net su Nuget.

Dopo aver trovato la libreria, e fatto click sul pulsante “Installa”, se tutto va a buon fine, ha, com’è visibile in figura, un cerchio verde con il segno di spunta al suo interno, questo sta a significare che è stata installata correttamente. Abbiamo installato tutto il necessario; è ora di procedere alla creazione del database, ma prima guardiamo cosa è stato aggiunto dopo l’istallazione dell’engine di Sqlite e Sqlite-net.

image thumb7 - Parte uno, Sqlite in Windows Phone 8.1
Immagine 1.4 La finestra esplora soluzioni dopo l’installazione dei file necessari.

Abbiamo il riferimento SQLite for Windows Phone 8.1 nei riferimenti, si tratta dell’engine che abbiamo aggiunto per primo, e i file SqLite.cs e SQLiteAsync.cs, appartenenti all’installazione della libreria Sqlite-net, con i quali saremo in grado di eseguire operazioni sul Database.
Creazione della classe per il Database
Come detto prima, Sqlite-net, offre un approccio tipico dell’orm, per cui non dovremmo preoccuparci del database, ma di creare la o le classi necessarie per poi eseguirne la creazione mediante la libreria e l’engine di Sqlite. Click con il mouse sul nome del progetto, quindi Sqlite Sample, tasto destro, e scegliamo il comando “Aggiungi” e dopo “Nuova Cartella”. La chiameremo “Classes”, al suo interno metteremo tutto ciò che riguarda l’interazione con il database e altro. Con la stessa procedura creiamo un’altra cartella, e la chiameremo “Screen”dove inseriremo, le schermate che compongono la nostra applicazione. Nella cartella Classes creiamo una nuova Classe denominata “Employee”, la procedura resta sempre quella per la creazione delle cartelle, ma scegliendo il comando “Classe”. All’interno del file inseriamo il codice che segue.

using SQLite;
namespace SqlLite_Sample.Classes
{
    class Employee
    {
        [PrimaryKey,AutoIncrement]
        public int Id { get; set; }
        [MaxLength(30)]
        public string Name { get; set; }
        [MaxLength(30)]
        public string SurName { get; set; }
        [MaxLength(3)]
        public int Age { get; set; }
    }

} Com’è possibile notare, abbiamo semplicemente creato una classe chiamata Employee, che contiene quattro Proprietà, con degli attributi inseriti tra parentesi quadre, che daranno altra personalizzazione. E’ utile sapere che in questo caso, sarà creato all’interno del Database, una tabella con lo stesso nome della classe, quattro campi esattamente con lo stesso nome delle proprietà, sarà dedotto automaticamente il tipo di dato per i campi, varchar per Name e SurName, int per Id e Age. Inoltre con gli attributi, personalizziamo ulteriormente queste quattro proprietà, per il campo Id, gli diciamo mediante “PrimaryKey” che si tratta del campo contatore e che sarà aumentato automaticamente, questo mediante l’attributo “AutoIncrement”. Definiamo una lunghezza massima di trenta caratteri per i campi Name e SurName, e un massimo di tre numeri per il campo Age. Abbiamo definito una semplice classe che rappresenterà un dipendente, definendone il nome, cognome ed età. Nella schermata MainPage, definiamo una semplice interfaccia grafica che ci consentirà di accedere alle altre schermate. Copiamo questo codice xaml nel file MainPage.xaml. 
 

    <Grid x:Name=”LayoutRoot”>
        <Grid.ChildrenTransitions>
            <TransitionCollection>
                <EntranceThemeTransition/>
            </TransitionCollection>
        </Grid.ChildrenTransitions>
        <Grid.RowDefinitions>
            <RowDefinition Height=”Auto”/>
            <RowDefinition Height=”*”/>
        </Grid.RowDefinitions>
        <!– Pannello del titolo –>
        <StackPanel Grid.Row=”0″ Margin=”19,0,0,0″>
            <TextBlock Text=”Sqlite sample” Style=”{ThemeResource TitleTextBlockStyle}” Margin=”0,12,0,0″/>
            <TextBlock Text=”Main page” Margin=”0,-6.5,0,26.5″ Style=”{ThemeResource HeaderTextBlockStyle}” CharacterSpacing=”{ThemeResource PivotHeaderItemCharacterSpacing}”/>
        </StackPanel>
        <!–TODO: il contenuto deve essere inserito all’interno della seguente griglia–>
        <Grid Grid.Row=”1″ x:Name=”ContentRoot” Margin=”19,9.5,19,0″>
            <StackPanel>
                <Button
                    x:Name=”btnInsertSample”
                    Content=”Insert sample page”
                    Tapped=”btnInsertSample_Tapped”
                    Width=”300″/>
                <Button
                    x:Name=”btnUpdateSample”
                    Content=”Update sample page”
                    Tapped=”btnUpdateSample_Tapped”
                    Width=”300″/>
                <Button
                    x:Name=”btnDeleteSample”
                    Content=”Delete sample page”
                    Tapped=”btnDeleteSample_Tapped”
                    Width=”300″/>
            </StackPanel>
        </Grid>

    </Grid> Se tutto è inserito in maniera corretta, la nostra schermata iniziale deve avere quest’aspetto.

image thumb9 - Parte uno, Sqlite in Windows Phone 8.1
Immagine 1.5 La schermata MainPage.

Passiamo ora all’editor di codice, con tasto F7, individuiamo il costruttore della classe MainPage, e inseriamo questo codice.
 

DatabaseManagement.CreateDatabase();

DatabaseManagement e una classe dentro della quale andremo a inserire tutta la gestione per l’interazione con il database. In questo caso stiamo andando a richiamare il Metodo CreateDatabase, il quale si occuperà di creare il Database qualora non esistesse nell’isolated storage. Questa è la parte di codice interessata che creerà il Database.
 

public static async void CreateDatabase()
{
    var person = await ConnectionDb().CreateTableAsync<Employee>();

} Definiamo una variabile denominata person di tipo SqliteAsyncConnection, che non è altro che la classe per la gestione della stringa di connessione al database, e mediante il metodo seguente:
 

        private static SQLiteAsyncConnection ConnectionDb()
        {
            var conn = new SQLite.SQLiteAsyncConnection(Path.Combine(ApplicationData.Current.LocalFolder.Path, “employee.db”),true);
            return conn;
        }

andiamo a recuperare la variabile conn, che si trova all’interno del metodo ConnectionDb(), la quale ci restituisce la seguente riga di codice, che poi sarà il percorso di locazione del Database.
 

Path.Combine(ApplicationData.Current.LocalFolder.Path, “employee.db”

In questo modo, dopo l’esecuzione del codice, abbiamo creato nella cartella “Local” dell’isolated storage un file denominato “employee.db”. Vedremo in seguito tutto il codice all’interno di questa classe, perché ci servirà nell’esempio che andremo a creare. Per completare tutta la parte di codice concernente la schermata iniziale, andiamo a gestire l’evento tapped dei quattro pulsanti, inseriamo la parte di codice seguente.
 

private void btnInsertSample_Tapped(object sender, TappedRoutedEventArgs e)
{
   Frame.Navigate(typeof(Insert));
}
private void btnUpdateSample_Tapped(object sender, TappedRoutedEventArgs e)
{
   Frame.Navigate(typeof(Update));
}
private void btnDeleteSample_Tapped(object sender, TappedRoutedEventArgs e)
{
   Frame.Navigate(typeof(Delete));
}

Per chi ha avuto esperienza con le versioni precedenti, noterà delle differenze per quanto riguarda la navigazione tra pagine. Se in Windows Phone 7/8 si utilizzava il metodo Navigate della proprietà NavigationService, passando poi mediante url di tipo relativo il nome della pagina sulla quale accedere, con eventuali parametri per lo scambio d’informazioni tra pagine, sulle applicazioni Windows Phone Store l’approccio è leggermente differente. Passiamo direttamente al metodo Navigate il riferimento alla pagina alla quale vogliamo accedere, in altre parole typeof(Delete) per esempio. Abbiamo poi due overload, il primo rimane sempre il/i parametri da passare alla pagina alla quale navighiamo, l’ultimo invece dalla possibilità di stabilire con quale animazione intendiamo visualizzare la pagina al momento della visualizzazione.
Inserimento dei dati
Arrivati a questo punto, abbiamo implementato tutta la parte concernente, la creazione del database. Creiamo ora, tutto ciò che riguarda l’inserimento dei dati all’interno della tabella Employee. Tornando al progetto, poniamo il cursore sulla cartella “Screen”, tasto destro del mouse, e scegliamo il comando “Aggiungi” e subito dopo “Nuovo elemento”. Nella successiva finestra di dialogo, cerchiamo il template “Pagina base”, come mostrato in figura.

image thumb11 - Parte uno, Sqlite in Windows Phone 8.1
Immagine 1.6 Il template Pagina base.

Creato il template e visualizzata la pagina, inserisce il seguente codice xaml per definirne l’interfaccia grafica.
 

<!– Pannello del titolo –>
        <StackPanel Grid.Row=”0″ Margin=”19,0,0,0″>
            <TextBlock
                Text=”Sqlite sample”
                Style=”{ThemeResource TitleTextBlockStyle}”
                Margin=”0,12,0,0″/>
           
            <TextBlock
                Text=”Insert page”
                Margin=”0,-6.5,0,26.5″
                Style=”{ThemeResource HeaderTextBlockStyle}”
                CharacterSpacing=”{ThemeResource PivotHeaderItemCharacterSpacing}”/>
        </StackPanel>
        <!–TODO: il contenuto deve essere inserito all’interno della seguente griglia–>
        <Grid Grid.Row=”1″ x:Name=”ContentRoot” Margin=”19,9.5,19,0″>
            <Grid.RowDefinitions>
                <RowDefinition Height=”Auto”/>
                <RowDefinition Height=”Auto”/>               
            </Grid.RowDefinitions>
                       
            <Grid Grid.Row=”0″>
                <Grid.RowDefinitions>
                    <RowDefinition Height=”Auto”/>
                    <RowDefinition Height=”Auto”/>
                    <RowDefinition Height=”Auto”/>
                    <RowDefinition Height=”Auto”/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width=”Auto”/>
                    <ColumnDefinition Width=”*”/>
                </Grid.ColumnDefinitions>
                <TextBlock
                            Grid.Column=”0″
                            Grid.Row=”0″
                            x:Name=”tbkName”
                            FontSize=”25″               
                            Text=”Name”
                            VerticalAlignment=”Center”
                />
                <TextBlock
                            Grid.Column=”0″
                            Grid.Row=”1″               
                            x:Name=”tbkSurname”
                            FontSize=”25″
                            Text=”Surname”
                            VerticalAlignment=”Center”
                />
                <TextBlock
                            Grid.Column=”0″
                            Grid.Row=”2″               
                            x:Name=”tbkAge”
                            FontSize=”25″
                            Text=”Age”
                            VerticalAlignment=”Center”
                />
                <TextBox
                            Grid.Column=”1″
                            Grid.Row=”0″
                            x:Name=”tbxName”
                />
                <TextBox
                            Grid.Column=”1″
                            Grid.Row=”1″               
                            x:Name=”tbxSurname”
                />
                <TextBox
                            Grid.Column=”1″
                            Grid.Row=”2″               
                            x:Name=”tbxAge”
                            InputScope=”Number”
                />
            </Grid>
            <Grid Grid.Row=”1″>
                <Grid.RowDefinitions>
                    <RowDefinition Height=”20″/>
                    <RowDefinition Height=”Auto”/>                   
                </Grid.RowDefinitions>
               
                <Button
                           Grid.Row=”1″
                           x:Name=”btnInsert”
                           Content=”Insert”
                           HorizontalAlignment=”Center”
                           Tapped=”btnInsert_Tapped”
                />
               
            </Grid>
        </Grid>

Se tutto il codice è inserito correttamente, questo sarà l’aspetto della pagina.

image thumb13 - Parte uno, Sqlite in Windows Phone 8.1
Immagine 1.7 La schermata inserimento dati.

A livello di codice, tutto ciò che dobbiamo gestire, non è altro che l’evento tapped del pulsante Insert. Con tasto F7, entriamo nell’editor di codice, e inseriamo tutto il necessario all’interno dell’evento tapped del pulsante.
 

private async void btnInsert_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
        {
            if(Validations.CheckTextBox(tbxName,tbxSurname,tbxAge).Equals(true))
            {
                var dialog = new MessageDialog(“Valorizzare tutti i campi”);
                await dialog.ShowAsync();
            }
            else
            {
                DatabaseManagement.InsertData(tbxName.Text, tbxSurname.Text, int.Parse(tbxAge.Text));
            }
        }

Notiamo che abbiamo inserito un costrutto if; questo perché l’utente potrebbe non inserire alcun dato e toccare poi il pulsante inserendo così dei valori null. Per evitare ciò, è stata creata una nuova classe denominata Validations, dentro la quale vi sono dei metodi che non fanno altro che eseguire un controllo. Nel nostro caso sarà verificato che le TextBox siano tutte valorizzate, se solo una non lo fosse, avviseremo l’utente mediante una MessageDialog. Non ci soffermeremo ulteriormente sui metodi di questa classe, ma ci limiteremo a mostrare poi il codice, poiché l’articolo è dedicato a Sqlite. Ciò che interessa invece, è il codice che trova all’interno del costrutto else, che si occuperanno di eseguire l’inserimento dei dati all’interno della tabella Employee. Anche il metodo InsertData, lo troviamo nella classe DatabaseManagement, vediamo come funziona.
 

        public async static void InsertData(string _name, string _surname, int _age)
        {
            var newemployee = new Employee
            {
                Name = _name,
                SurName = _surname,
                Age = _age,
            };
            await ConnectionDb().InsertAsync(newemployee);

        } Il metodo è molto semplice, andiamo a creare un nuovo oggetto di tipo Employee, dove valorizzeremo le proprietà Name, SurName e Age con i valori dei parametri che il metodo InsertData richiede al momento in cui è invocato. In seguito richiamiamo il metodo asincrono InsertAsync(), facente della classe SqliteAsyncConnection, passando come parametro l’oggetto da aggiungere alla tabella Employee, ovvero la variabile newemployee. Il metodo ConnectionDb lo abbiamo già visto in precedenza, al momento della parte di codice per la creazione del Database.
Aggiornamento dei dati
La procedura di aggiornamento dei dati, è simile a quella per l’inserimento, se non per la differenza che dovremo recuperare il dato/i da modificare. Torniamo al nostro progetto, e con la procedura che abbiamo utilizzato per la creazione della pagina Insert, sempre nella cartella Screen, creiamone una denominata Update. Inseriamo come per la pagina insert il codice xaml per definirne l’interfaccia grafica
 

        <!– Pannello del titolo –>
        <StackPanel Grid.Row=”0″ Margin=”19,0,0,0″>
            <TextBlock Text=”Sqlite sample” Style=”{ThemeResource TitleTextBlockStyle}” Margin=”0,12,0,0″/>
            <TextBlock Text=”Update page” Margin=”0,-6.5,0,26.5″ Style=”{ThemeResource HeaderTextBlockStyle}” CharacterSpacing=”{ThemeResource PivotHeaderItemCharacterSpacing}”/>
        </StackPanel>
        <!–TODO: il contenuto deve essere inserito all’interno della seguente griglia–>
        <Grid Grid.Row=”1″ x:Name=”ContentRoot” Margin=”19,9.5,19,0″>
            <Grid.RowDefinitions>
                <RowDefinition Height=”Auto”/>
                <RowDefinition Height=”Auto”/>
                <RowDefinition Height=”Auto”/>
                <RowDefinition Height=”Auto”/>
                <RowDefinition Height=”Auto”/>
                <RowDefinition Height=”Auto”/>
                <RowDefinition Height=”Auto”/>               
            </Grid.RowDefinitions>
            <ListBox Grid.Row=”0″ x:Name=”lstUpdatePerson” SelectionChanged=”lstUpdatePerson_SelectionChanged”>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <StackPanel Orientation=”Horizontal”>
                                <TextBlock x:Name=”tbkName”
                                           FontWeight=”Bold”
                                           Text=”Name”/>
                                <TextBlock Width=”30″/>
                                <TextBlock x:Name=”tbkSurname”
                                           FontWeight=”Bold”                                          
                                           Text=”Surname”/>
                                <TextBlock Width=”30″/>
                                <TextBlock x:Name=”tbkAge”
                                           FontWeight=”Bold”                                          
                                           Text=”Age”/>
                                <TextBlock Height=”50″/>
                            </StackPanel>
                            <StackPanel Orientation=”Horizontal”>
                                <TextBlock
                                    x:Name=”tbkFindForName”
                                    Text=”{Binding Name}”/>
                                <TextBlock Width=”20″/>
                                <TextBlock
                                    x:Name=”tbkFindForSurName”
                                    Text=”{Binding SurName}”/>
                                <TextBlock Width=”20″/>
                                <TextBlock
                                    x:Name=”tbkFindForAge”                                   
                                    Text=”{Binding Age}”/>
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
           
            <TextBlock Grid.Row=”3″ x:Name=”tbkNewData” Text=”New data” HorizontalAlignment=”Center”/>
           
            <StackPanel Grid.Row=”4″ x:Name=”splNewData”>
                <StackPanel x:Name=”splNewName” Orientation=”Horizontal”>
                    <TextBlock Text=”Name” VerticalAlignment=”Center”/>
                    <TextBlock Width=”30″/>
                    <TextBox x:Name=”tbxNewName” Width=”Auto”/>
                </StackPanel>
                <StackPanel x:Name=”splNewSurName” Orientation=”Horizontal”>
                    <TextBlock Text=”SurName” VerticalAlignment=”Center”/>
                    <TextBlock Width=”15″/>
                    <TextBox x:Name=”tbxNewSurName” Width=”Auto”/>
                </StackPanel>
                <StackPanel x:Name=”splNewAge” Orientation=”Horizontal”>
                    <TextBlock Text=”Age” VerticalAlignment=”Center”/>
                    <TextBlock Width=”40″/>
                    <TextBox x:Name=”tbxNewAge” Width=”Auto” InputScope=”Number”/>
                </StackPanel>
            </StackPanel>           
           
            <Button Grid.Row=”6″ x:Name=”btnUpdatePerson” Content=”Update” Tapped=”btnUpdatePerson_Tapped”/>

        </Grid> Anche in questo caso, se tutto il codice è inserito correttamente, questo, sarà l’aspetto finale della pagina.

image thumb15 - Parte uno, Sqlite in Windows Phone 8.1

Immagine 1.8 La schermata aggiornamento dati.
Come per l’inserimento dei dati, anche in questa circostanza, dobbiamo gestire l’evento tapped del pulsante Update più l’evento SelectionChanged del controllo ListBox, che si occuperà di visualizzare tutti i dati disponibili all’interno della tabella Employee, e l’override On NavigatedTo. Quest’ultimo è eseguito al momento in cui si accede alla pagina scelta dall’utente durante l’utilizzo dell’applicazione. Con il tasto F7, accediamo all’editor e inseriamo il codice seguente.
 

        private void lstUpdatePerson_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Parametri_ricerca.NewName = ((Employee)(lstUpdatePerson.SelectedValue)).Name;
            tbxNewName.Text = ((Employee)(lstUpdatePerson.SelectedValue)).Name;
            tbxNewSurName.Text = ((Employee)(lstUpdatePerson.SelectedValue)).SurName;
            tbxNewAge.Text = ((Employee)(lstUpdatePerson.SelectedValue)).Age.ToString();
        }

Analizziamo il codice dell’evento SelectionChanged del controllo ListBox. Abbiamo definito una nuova classe denominata Parametri_ricerca, dove al suo interno vi sono dei campi che ci serviranno come scambio d’informazioni tra pagine, fondamentalmente tornando al discorso della navigazione tra pagine, per lo scambio d’informazioni tra esse, abbiamo la possibilità di utilizzare i parametri all’interno del metodo Navigate, come abbiamo già visto, o il sistema da me utilizzato, in altre parole creare una classe statica e definire tutti i campi necessari per l’utilizzo. Valorizziamo il campo NewName, con il valore della proprietà SelectedValue del controllo ListBox, più i controlli TextBox della pagina. C’è una cosa alla quale bisogna prestare attenzione: la proprietà SelectedValue è di tipo Object e non può essere assegnata direttamente alla proprietà Text dei controlli TextBox, e nemmeno alla variabile NewName, poiché tutti sono di tipo String, ma bisogna fare un cast, in altre parole convertire il tipo Object restituito in Employee, poi mediante le proprietà della classe, avremo in ritorno il valore del tipo corretto. In altre parole Name, Surname e Age convertito in stringa mediante il metodo ToString(). Terminata la valorizzazione di tutti gli oggetti all’interno dell’evento SelectionChanged, vediamo il codice per l’aggiornamento dei dati.
 

        private async void btnUpdatePerson_Tapped(object sender, TappedRoutedEventArgs e)
        {
            await Validations.MessageConfirmDeleteoUpdatePerson(“Vuoi aggiornare i dati?”);
            if (Validations.result.Equals(true))
            {
                if (Validations.CheckTextBox(tbxNewName, tbxNewSurName, tbxNewAge).Equals(true))
                {
                    var dialog = new MessageDialog(“Valorizzare tutti i campi”);
                    await dialog.ShowAsync();
                }
                else
                {
                    DatabaseManagement.UpdateData(Parametri_ricerca.NewName,tbxNewName.Text);
                }
            } 

        }
Al tap sul pulsante btnUpdate, visualizziamo una MessageDialog all’utente, in cui è chiesta conferma per l’aggiornamento dei dati, se si facciamo ancora un altro controllo che tutte le TextBox siano correttamente valorizzate, abbiamo già visto questa procedura nella parte concernente l’inserimento dei dati. Ciò che interessa è il codice all’interno del costrutto else. Anche questo metodo lo troveremo nella classe DatabaseManagement.
 

        public async static void UpdateData(string _name, string _newname)
        {
            var updateemployee = await ConnectionDb().Table<Employee>().Where(w => w.Name.Equals(_name)).FirstOrDefaultAsync();
            updateemployee.Name = _newname;
            await ConnectionDb().UpdateAsync(updateemployee);

        } Analizziamo il codice concernente, l’aggiornamento dei dati. Per la connessione e il recupero della tabella Employee, facciamo uso dell’oramai conosciuto ConnectionDb(), ma ecco che subentra quanto abbiamo accennato all’inizio dell’articolo, il supporto a Linq. Questa riga di codice:
Where(w => w.Name.Equals(_name)).FirstOrDefaultAsync();
fa uso dell’exstension methods Where(), dove in base ad una condizione, (nel nostro esempio vogliamo modificare il nome di un dipendente “employee”) data dal parametro _name, recuperiamo poi, mediante l’exstension methods FirstOrDefaultAsync() il dato corretto e assegniamo alla proprietà Name della variabile updateemployee di tipo Employee il valore di _newname, dove _newname corrisponde al nome modificato. Infine mediante il metodo UpdateAsync(), viene eseguito l’aggiornamento verso la tabella Employee presente all’interno del Database.
Dobbiamo ancora inserire il codice dell’override OnNavigatedTo, lo trovate all’interno della Registrazione di Navigation Helper presente nei file di codice .cs.
 

protected async override void OnNavigatedTo(NavigationEventArgs e)
        {
           await  DatabaseManagement.LoadData(lstUpdatePerson);
            this.navigationHelper.OnNavigatedTo(e);
        }

La riga di codice che interessa a noi è la prima ovvero il metodo LoadData(), presente all’interno della oramai conosciuta classe DatabaseManagement.
 

        public async static Task LoadData(ListBox box)
        {
            var employee = new List<Employee>();
            var query = ConnectionDb().Table<Employee>();
            var result = await query.ToListAsync();
            foreach (var person in result)
            {
                employee.Add(new Employee { Name = person.Name, SurName = person.SurName, Age = person.Age });
            }
            box.ItemsSource = employee;

        } Si tratta di un task, con il quale vuole eseguire l’aggiornamento del controllo Listbox della pagina Update. Infatti, se notiamo il metodo, richiede un parametro di tipo ListBox. In altre parole dovremmo passare un riferimento di un controllo, nel nostro caso la ListBox lstUpdatePerson. Poi, dichiarata una lista di tipo Employee, eseguiamo la connessione al database e recuperiamo la tabella Employee mediante il metodo Table<>, ma la query vera e propria é eseguita nel momento che invochiamo l’istruzione await query.ToListAsync(). Questo metodo restituisce una collection di oggetti di tipo Employee che poi andiamo ad aggiungere alla lista employee mediante un ciclo foreach. Terminata l’interazione del ciclo, l’ultima cosa da fare, è assegnare al parametro box il risultato di employee. In questo modo quando accederemo alla schermata di Update, se vi sono presenti dati, li potremo visualizzare correttamente.
Eliminazione dei dati
Il processo per l’eliminazione dei dati, è pressoché identico a quello per l’aggiornamento, l’unica differenza sta nel chiamare una query differente al momento in cui desideriamo eliminare il dato. Torniamo al nostro progetto iniziale, seguiamo la procedura che abbiamo già visto per la creazione delle schermate di Insert e Update, e aggiungiamo sempre nella cartella Screen una nuova pagina base e la denominiamo Delete. Aggiungiamo il seguente codice xaml per definirne l’interfaccia grafica.

        <!– Pannello del titolo –>
        <StackPanel Grid.Row=”0″ Margin=”19,0,0,0″>
            <TextBlock Text=”Sqlite sample” Style=”{ThemeResource TitleTextBlockStyle}” Margin=”0,12,0,0″/>
            <TextBlock Text=”Delete page” Margin=”0,-6.5,0,26.5″ Style=”{ThemeResource HeaderTextBlockStyle}” CharacterSpacing=”{ThemeResource PivotHeaderItemCharacterSpacing}”/>
        </StackPanel>
      
        <!–TODO: il contenuto deve essere inserito all’interno della seguente griglia–>
            <Grid Grid.Row=”1″ x:Name=”ContentRoot” Margin=”19,9.5,19,0″>
                <Grid.RowDefinitions>
                    <RowDefinition Height=”Auto”/>
                    <RowDefinition Height=”Auto”/>
                    <RowDefinition Height=”Auto”/>
                    <RowDefinition Height=”Auto”/>
                    <RowDefinition Height=”Auto”/>
                </Grid.RowDefinitions>
               
            <ListBox Grid.Row=”0″ x:Name=”lstDeletePerson” SelectionChanged=”lstDeletePerson_SelectionChanged”>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <StackPanel Orientation=”Horizontal”>
                                <TextBlock x:Name=”tbkName”
                                           FontWeight=”Bold”
                                           Text=”Name”/>
                                <TextBlock Width=”30″/>
                                <TextBlock x:Name=”tbkSurname”
                                           FontWeight=”Bold”                                          
                                           Text=”Surname”/>
                                <TextBlock Width=”30″/>
                                <TextBlock x:Name=”tbkAge”
                                           FontWeight=”Bold”                                          
                                           Text=”Age”/>
                                <TextBlock Height=”50″/>
                            </StackPanel>
                            <StackPanel Orientation=”Horizontal”>
                                <TextBlock
                                    x:Name=”tbkFindForName”
                                    Text=”{Binding Name}”/>
                                <TextBlock Width=”20″/>
                                <TextBlock
                                    x:Name=”tbkFindForSurName”
                                    Text=”{Binding SurName}”/>
                                <TextBlock Width=”20″/>
                                <TextBlock
                                    x:Name=”tbkFindForAge”
                                    Text=”{Binding Age}”/>
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <ScrollViewer Grid.Row=”2″>
                <StackPanel Grid.Row=”2″ x:Name=”splData”>
                    <StackPanel x:Name=”splName” Orientation=”Horizontal”>
                        <TextBlock Text=”Name” VerticalAlignment=”Center”/>