Capitoli
Transcript
Capitoli
Capitolo 3 La prima applicazione Windows 8 Dopo aver completato questo capitolo, sarai in grado di: n Installare e utilizzare gli strumenti di Microsoft Visual Studio 2012 per sviluppare un’applicazione Windows 8 n Comprendere e utilizzare i template per creare applicazioni Windows Store n Creare una semplice applicazione usando C# e Visual Basic (VB) n Testare l’applicazione n Usare le API del Windows 8 Runtime (WinRT) da un’applicazione Windows 8 Nel capitolo precedente abbiamo visto come Microsoft Windows 8 abbia introdotto una nuova interfaccia utente e presenti una user experience completamente rinnovata, mettendo altresì a disposizione un nuovo insieme di API denominate Windows Runtime API (WinRT). Tanto l’interfaccia quanto la complessiva user experience sono basate su quel particolare linguaggio di design denominato “Windows 8 UI style” (conosciuto nelle versioni beta come “Metro style”) che abbiamo visto nel Capitolo 2, “Windows 8 UI style”. In questo capitolo tradurremo in pratica quello che abbiamo sin qui visto. Cominceremo con il creare una semplice applicazione Windows 8 utilizzando uno dei template messi a disposizione da Visual Studio 2012, per poi installarla sulla macchina locale. Infine, implementeremo una semplice chiamata alle API di WinRT. Installazione del software Per cominciare a sviluppare applicazioni Windows 8, è necessario Visual Studio 2012. Questa nuova versione di Visual Studio può essere installata per funzionare fianco a fianco con preesistenti installazioni di Visual Studio 2010 e porta con sé la versione 4.5 del .NET Framework. Quest’ultima versione non rappresenta una major release, ma contiene comunque alcune importanti funzionalità che permettono di sfruttare le API di WinRT. Ti consigliamo di installare l’ambiente di sviluppo direttamente su una macchina con sopra Windows 8, in modo da accelerare le fasi di sviluppo e di testing sull’ambiente finale e su eventuali componenti hardware: ad esempio, se la tua applicazione fa uso dell’accelerometro, dell’inclinometro, della camera o di un qualunque altro sensore, le fasi di testing e di debug risulteranno più accurate e spedite. Per scaricare Windows 8, vai alla pagina http://msdn.microsoft.com//windows/apps—che rappresenta l’home page per lo sviluppo di applicazioni Windows 8. A partire da questa pagina, puoi facilmente raggiungere le differenti versioni messe a disposizione per il download. Nella sezione Getting Started, puoi inoltre trovare utili informazioni per il download e l’installazione. 67 68 Creare applicazioni per Windows 8 Passo per Passo Nota Dal momento che URL e componenti possono variare nel tempo, cerca Windows 8 e Visual Studio 2012 sulla home page di Windows 8 (http://msdn.microsoft.com/windows/apps) o utilizza Bing (http://www.bing.com). Come abbiamo visto nel Capitolo 1, “Introduzione alle applicazioni Windows Store”, Visual Studio 2012 Express for Windows 8 è una versione gratuita di Visual Studio che contiene quanto strettamente necessario allo sviluppo di un‘applicazione Windows 8. È anche possibile utilizzare la versione completa di Visual Studio 2012, sia installandola direttamente sopra l‘edizione Express che installandola separatamente. Per riassumere, i componenti necessari per iniziare a sviluppare un’applicazione Windows 8 sono i seguenti: n Visual Studio 2012 Express Edition for Windows 8 o una versione superiore di Visual Studio 2012 (come l’edizione Ultimate). n L’SDK di Windows 8, in modo da poter sfruttare i template di default e l’integrazione con l’ambiente di Windows 8. Questo componente è incluso con Visual Studio 2012 Express for Windows 8. n Windows 8, per testare l’applicazione nel suo ambiente reale. n Una licenza per sviluppatore (“developer license”). L’IDE (Integrated Development Environment) di Visual Studio 2012 è in grado di gestire questo requisito in modo automatico, l’unica cosa che devi fare è cliccare sul pulsante Yes nel momento in cui apparirà il relativo dialog. I template Windows Store Il modo più semplice di cominciare a sviluppare un’applicazione Windows 8 è partire da uno dei template già disponibili. Visual Studio 2012 mette infatti a disposizione una serie di template raggruppati sotto la voce «Windows Store». Questi template includono i file necessari per lo sviluppo, il test e l‘installazione - in locale o sul simulatore - di un progetto Windows Store, nonché le procedure necessarie per creare un package applicativo per la pubblicazione sul Windows Store. Ciascuno di questi template rappresenta un valido punto di partenza per iniziare a sviluppare differenti tipologie di applicazioni Windows Store. Di seguito sono riassunte le principali caratteristiche dei diversi template: n Blank App (XAML): Questo template crea uno scheletro di progetto con il minimo indispensabile per creare un’applicazione Windows Store. n Grid App (XAML): Il progetto che ne deriva include più pagine per navigare tra diversi livelli di contenuto. I dettagli di ciascun elemento della griglia possono essere visualizzati semplicemente con un “tap” o un click sull’elemento stesso e sono mostrati in una pagina separata. Capitolo 3 La prima applicazione Windows 8 69 n Split App (XAML): Questo template rappresenta un buon punto di partenza per creare una lista di tipo “master-detail”. La lista è visualizzata sul lato sinistro della pagina, mentre i dettagli di ciascun elemento sono mostrati sul lato destro della medesima pagina. n Class Library (Windows Store apps): Il progetto che ne deriva è una classica libreria da utilizzare per centralizzare il codice di un’applicazione Windows Store. Questo template può essere usato anche per creare un componente Windows Runtime. n Windows Runtime Component: Permette di sviluppare un componente che può essere utilizzato da applicazioni Windows Store, a prescindere dal linguaggio con cui sono state sviluppate. n Unit Test Library (Windows Store apps): L’obiettivo di questo template è quello di fornire un progetto contenente gli unit test relativi a un’applicazione Windows Store, a un componente Windows Runtime o a una libreria per applicazioni Windows Store. Nella prossima procedura, avrai modo di creare il tuo primo progetto. Creare il progetto Come forse ricorderai dal Capitolo 1, il processo di setup dell’SDK include una serie di nuovi template e di wizard per facilitare la creazione di un progetto Windows Store. Come vedrai meglio al passo 3 della procedura seguente, tra i template messi a disposizione da Visual Studio 2012 (sia in C# che VB) troverai una nuova sezione denominata Windows Store, che rappresenta il punto di partenza per questo nuova tipologia di progetti. Questa sezione contiene tutti i template specifici per applicazioni Windows 8. 1. Crea una nuova applicazione. A tal fine, apri Visual Studio 2012 e dal menu File seleziona New Project (nelle versioni superiori di Visual Studio, il percorso può essere leggermente diverso: File, New e quindi Project). Seleziona Visual C# nell’albero Templates e, all’interno della lista dei template installati, scegli Windows Store; infine, seleziona Blank App (XAML) dalla lista dei progetti disponibili. 2. Come versione del .NET Framework per il nuovo progetto seleziona la 4.5. Questo passaggio non è richiesto in Visual Studio Express. 3. Assegna al nuovo progetto il nome MyFirstApp, scegli la directory sul filesystem e lascia invariato il nome assegnato alla solution. Quando hai terminato, clicca sul pulsante OK. Se utilizzi un sistema di controllo sorgente, puoi selezionare la checkbox Add To Source Control. 70 Creare applicazioni per Windows 8 Passo per Passo La seguente Figura mostra il primo passo del wizard New Project: sia il progetto che la solution sono denominati MyFirstApp. A questo punto, Visual Studio 2012 creerà le directory necessarie e il progetto associato a quel particolare template. Avendo selezionato Blank App come template di partenza, Visual Studio utilizzerà per la nuova applicazione il progetto con la struttura più semplice tra quelle disponibili. La Figura 3-1 mostra il risultato della procedura appena conclusa. Capitolo 3 La prima applicazione Windows 8 71 FIGURA 3-1 Il progetto Windows Store nel Solution Explorer. Come puoi facilmente notare, all’interno del progetto troverai due file, denominati rispettivamente App.xaml e MainPage.xaml, nonché una cartella denominata Properties contenente il classico file AssemblyInfo.cs. La struttura del progetto è dunque simile a quella che troveresti in un progetto Windows Presentation Foundation Browser Application, o addirittura in un progetto Windows Presentation Foundation, ma con alcune differenze. 72 Creare applicazioni per Windows 8 Passo per Passo La prima differenza rispetto a un’applicazione Windows Presentation Foundation (WPF) è l’assenza del file app.config. Questo significa che, alla pari di un‘applicazione Microsoft Silverlight o Windows Presentation Foundation Browser, non è possibile usare il classico meccanismo di configurazione di .NET. Ed in effetti, l‘applicazione viene eseguita in un ambiente «sandboxed», come in un‘applicazione Silverlight o WPF Browser: in particolare, l‘utente non può selezionare la directory in cui installare l‘applicazione, né tantomeno modificarne i file, dal momento che le applicazioni Windows Store sono generalmente scaricate e installate dal Windows Store. Un eccezione a questa regola la si ha quando stiamo lavorando nell‘ambiente di sviluppo, in cui l‘applicazione viene installata tramite Visual Studio 2012 (o manualmente dallo sviluppatore, tramite uno strumento a riga di comando) per consentire il testing e il debug dell‘applicazione stessa. La seconda differenza rispetto a un‘applicazione Silverlight o WPF Browser è data dalla presenza del file Package.appxmanifest. Questo file contiene una descrizione dell‘applicazione (incluse le icone applicative e le interazioni con il sistema operativo), nonché l‘indicazione delle funzionalità del sistema operativo di cui l‘applicazione intende fare uso (racchiuse sotto la voce «capabilities» e «declarations»). Sotto questo profilo, ci sono forti somiglianze con un progetto Windows Phone 7.x, in cui il file WMAppManifest.xml provvede a informare il sistema operativo circa le funzionalità cui ha bisogno di accedere per poter funzionare. La Figura 3-2 mostra il designer per il file Package.appxmanifest messo a disposizione da Visual Studio per semplificare la definizione dell‘applicazione. Come puoi vedere, il tab Application UI permette di scegliere il Display Name dell‘applicazione— ossia il nome da mostrare nella Start Page—una descrizione dell‘applicazione, tre loghi, e così via. FIGURA 3-2 Il designer di Visual Studio per l’application manifest Capitolo 3 La prima applicazione Windows 8 73 Un’altra analogia con un progetto Windows Phone è rappresentata dalla presenza di una serie di immagini di default all’interno del progetto. Queste immagini sono contenute nella directory Assets e sono referenziate dal file Package.appxmanifest. Il template di default, infatti, utilizza un‘immagine per il tile di default dell‘applicazione (Logo.png), una per lo splash screen iniziale (SplashScreen.png), un‘immagine più piccola da utilizzare quando l‘applicazione modifica il proprio tile via codice (SmallLogo.png), nonché un‘ulteriore immagine per rappresentare l‘applicazione sul Windows Store (StoreLogo.png). Come si può vedere dalla figura precedente, non c‘è invece un‘immagine di default da usare come tile «wide», né questa immagine è referenziata dal Package.appxmanifest. Se eseguiamo adesso l‘applicazione, lasciando invariati i file e le impostazioni del manifest, dopo un breve intervallo dovuto alle operazioni di installazione dell‘applicazione nell‘ambiente di sviluppo ad opera di Visual Studio, vedremo lo splash screen, seguito da uno schermo completamente nero che rappresenta l‘applicazione medesima. A prima vista questo potrebbe sembrare strano, dato che tradizionalmente Visual Studio include un qualche testo di esempio nei suoi template - ma come scoprirai tra breve nella prossima procedura, molte cose sono successe durante l‘installazione dell‘applicazione. Esplorare l’applicazione installata sul sistema Per prima cosa, nota l’assenza della classica finestra con i pulsanti per chiudere, minimizzare e massimizzare la finestra stessa. In effetti, si tratta della prima versione di Windows senza… finestre. Segui i prossimi passaggi per esplorare l’interazione tra Visual Studio e Windows 8 durante il processo di installazione di un’applicazione. 1. Clicca sul tasto Start del tuo tablet o della tastiera, o posiziona il puntatore del mouse nell’angolo inferiore sinistro dello schermo e clicca su Start per tornare alla Start Page. 2. Scorri verso destra con uno “swipe”, oppure usando la rotellina del mouse o la scroll bar inferiore fino a raggiungere l’estremità destra della Start Page. 3. L’ultimo tile applicativo presente sulla Start Page rappresenta la tua prima applicazione Windows 8 installata tramite Visual Studio e denominata “MyFirstApp.” 4. Clicca sul tile per lanciare nuovamente l’applicazione. 5. Torna a Visual Studio e interrompi la sessione di debug cliccando sul pulsante Stop Debugging o premendo Shift+F5. 6. Ripeti i passaggi da 1 a 3, dopodiché esegui un “tap” prolungato sul tile (o clicca sul tile con il tasto destro del mouse). Nell’App Bar inferiore vedrai apparire due comandi: Unpin e Uninstall. La prima opzione ti permette di rimuovere il tile dalla Start Page, lasciando però l’applicazione intatta, mentre la seconda disinstalla l’applicazione dal sistema. 7. Seleziona Unpin per rimuovere l’applicazione dalla Start Page. 8. Posiziona il puntatore del mouse nell’angolo in basso a destra dello schermo per visualizzare la Charms Bar e quindi seleziona il comando Search, o premi Windows+Q sulla tastiera, per aprire il pannello Search nella parte destra dello schermo. 74 Creare applicazioni per Windows 8 Passo per Passo 9. Digita le prime lettere del nome dell’applicazione—per esempio myfi — nella textbox e seleziona Apps nell’elenco dei “posti” in cui effettuare la ricerca. La tua applicazione apparirà adesso nel pannello di sinistra, come mostrato nella prossima Figura. 10. Puoi lanciare l’applicazione sia con un “tap” che cliccandoci sopra, ma non farlo. Esegui piuttosto un “tap” prolungato sul relativo tile (oppure cliccaci sopra con il tasto destro del mouse) per aprire l’App Bar. 11. Seleziona il comando Pin. L’applicazione verrà aggiunta alla Start Page usando il tile di default. Puoi verificarne la presenza ripetendo i passi 1 e 2 di questa procedura. Nota che dal pannello Search è possibile ricercare non solo tra i file e le impostazioni di sistema, ma anche effettuare ricerche all’interno delle applicazioni elencate. Queste applicazioni hanno infatti dichiarato la funzionalità (“capability”) di Search all’interno del loro Package.appxmanifest. Più avanti, aggiungeremo questa dichiarazione all’applicazione di esempio sviluppata in questo capitolo. Prima di procedere oltre, tieni presente che se hai scelto di lanciare l’applicazione dal pannello di Search o dalla Start Page—ossia, se hai lanciato l’applicazione da fuori Visual Studio—questa dovrà essere chiusa manualmente prima di poter effettuare una nuova installazione. Infatti, se l’applicazione viene lanciata tramite Visual Studio, questi chiede al sistema operativo di creare e installare il relativo package, dopodiché lancia l’applicazione in debug: interrompendo la sessione di debug da Visual Studio, il relativo processo viene terminato (la stessa cosa accade se l’applicazione va in crash). Se invece l’applicazione viene lanciata al di fuori di Visual Studio, questa occupa l’intero schermo e, come abbiamo notato in precedenza, non esiste alcun pulsante per chiuderla. In questi casi è necessario chiudere manualmente (“kill”) il processo per evitare che questo rimanga in esecuzione indefinita- Capitolo 3 La prima applicazione Windows 8 75 mente. Per far questo, puoi sfruttare il Windows Task Manager, premere Alt-F4, oppure usare uno “swipe” dal centro del bordo superiore dello schermo verso il bordo inferiore. Vedremo meglio i dettagli relativi alla gestione del ciclo di vita di un’applicazione nel Capitolo 4, “Application Lifecycle Management”, ma per il momento è importante chiarire che Windows 8 introduce un modo completamente nuovo di gestire il ciclo di vita di un’applicazione. Un’applicazione si trova in esecuzione fino a quando l’utente la sta utilizzando (in altre parole, fino a quando l’applicazione si trova in primo piano); quando l’utente l’abbandona - ad esempio premendo il tasto Start, o lanciando un’altra applicazione, o avviando una nuova ricerca, ecc. —il sistema può sospendere l’applicazione ed eventualmente terminarla, per liberare nuova memoria. Questo comportamento è simile alla gestione del ciclo di un’applicazione Windows Phone 7.x, così come a quello di altri sistemi operativi moderni. Come già menzionato, il Task Manager rappresenta un altro modo per terminare un’applicazione in esecuzione. Questi è stato modificato in Windows 8 in modo da visualizzare lo stato di un’applicazione. La Figura 3-3 mostra l’applicazione MyFirstApp in stato di sospensione all’interno del Task Manager. Save the Planet, un’applicazione reale portata da Windows Phone 7 a Windows 8, non risulta invece sospesa-ossia è ancora in esecuzione. FIGURA 3-3 Il Task Manager mostra lo stato di esecuzione/Sospensione delle applicazioni Windows Store 76 Creare applicazioni per Windows 8 Passo per Passo Questo meccanismo si applica unicamente alle applicazioni Windows Store e non alle classiche applicazioni .NET o Win32. In effetti, le due istanze di Visual Studio, Paint e altre applicazioni Win32 mostrate nella precedente figura sono ancora in esecuzione. Aggiungere la dichiarazione di Search nel manifest In questa procedura aggiungeremo la dichiarazione di Search al manifest applicativo in modo da consentire all’utente di ricercare del testo “all’interno” della nostra applicazione. Segui questi passi utilizzando il progetto Visual Studio 2012 creato nella prima procedura. 1. Fai doppio click sul file Package.appxmanifest dell’applicazione MyFirstApp per aprire il relativo designer. 2. Clicca il tab Declarations per gestire le dichiarazioni per questa applicazione. 3. Seleziona Search all’interno della listbox denominata Available Declarations e quindi clicca su Add. Come si può leggere nella sezione Description, la dichiarazione di Search “…registers the application as providing search functionality. Users will be able to search the application from anywhere in the system”; in altri termini, significa che l’applicazione si registrerà sul sistema operativo come provider di ricerca. Con l’espressione “search the application”, in particolare, si intende che il testo digitato dall’utente come querystring verrà passato all’applicazione, che internamente eseguirà la ricerca. 4. Prima di testare l’applicazione, clicca sul tab Application UI e accertati che la voce All Logos sia selezionata all’interno della drop-down list Show Name. 5. Per cambiare il logo di default, copia i file .png che trovi nella directory Logos del file demo di questo capitolo all’interno nella directory Assets del progetto. Questi file rispecchiano i nomi di default, per cui non è necessario modificare il Package. appxmanifest. 6. Clicca con il tasto destro sul progetto MyFirstApp nel Solution Explorer e seleziona la voce Deploy. Questa operazione installa l’applicazione in Windows 8 senza iniziare una sessione di debug. 7. Torna alla Start Page tramite il tasto Start e scorri verso destra per verificare che il nome e il nuovo logo appaiano sul tile dell’applicazione. 8. Premi Windows+F o Windows+Q per attivare una delle interfacce di Search (la prima combinazione apre la pagina di ricerca dei file, la seconda la pagina di ricerca delle applicazioni), e digita del testo nella relativa textbox. Scorri tra i risultati per verificare che la tua applicazione compia nell’elenco, come mostrato nella prossima Figura. Puoi anche cliccare sull’applicazione per attivarla, anche se per il momento non otterrai alcun risultato; il codice per implementare la ricerca verrà infatti implementato nell’ultima parte di questo capitolo. Capitolo 3 La prima applicazione Windows 8 77 Aggiungere elementi di UI In questa sezione analizzeremo gli altri elementi del progetto creati dal template di default e aggiungeremo un po’ di codice per creare una lista di persone e metterle in binding con la user interface. Nota Va oltre gli scopi di questo libro analizzare le diverse tecniche di binding e i pattern di user interface come MVVM (Model View View Model) e MVC (Model View Controller). Cominciamo analizzando il codice proposto dal template di Visual Studio 2012. Abbiamo già visto il significato e il ruolo dell’application manifest e della directory contenente una serie di immagini predefinite. Il Listato 3-1 mostra il codice XAML della pagina principale (MainPage.xaml), cui è stato aggiunto un controllo ListView standard per visualizzare la proprietà FullName di una lista di elementi in binding. LISTATO 3-1 La pagina MainPage.xaml modificata. <Page x:Class=”MyFirstApp.MainPage” xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” 78 Creare applicazioni per Windows 8 Passo per Passo xmlns:local=”using:MyFirstApp” xmlns:d=”http://schemas.microsoft.com/expression/blend/2008” xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006” mc:Ignorable=”d”> <Grid Background=”{StaticResource ApplicationPageBackgroundThemeBrush}”> <ListView x:Name=”list” DisplayMemberPath=”FullName” /> </Grid> </Page> La pagina include la classica definizione XAML per il controllo Page rappresentato dalla classe MyFirstApp.MainPage. Il controllo referenzia quattro namespace XML —esattamente come in un progetto Silverlight o in un’applicazione WPF o Windows Phone 7.x. Per default, il template utilizza un controllo Grid per il layout, ma più avanti nel corso di questa procedura avrai modo di cambiarlo, aggiungendo altresì alcuni stili per modificare l’aspetto e il “feeling” di questa semplice applicazione. Modificherai anche il code behind della pagina MainPage.xaml, come mostrato nel Listato 3-2, così da invocare un componente del business layer che restituisca una lista di persone rappresentate dalla classe Person, che implementerai a breve. LISTATO 3-2 Il codice modificato della MainPage.xaml.cs. using using using using using using using using using using using using using System; System.Collections.Generic; System.IO; System.Linq; Windows.Foundation; Windows.Foundation.Collections; Windows.UI.Xaml; Windows.UI.Xaml.Controls; Windows.UI.Xaml.Controls.Primitives; Windows.UI.Xaml.Data; Windows.UI.Xaml.Input; Windows.UI.Xaml.Media; Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at http://go.microsoft.com/ fwlink/?LinkId=234238 namespace MyFirstApp { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); // Fill the ListView var biz = new Biz(); list.ItemsSource = biz.GetPeople(); } Capitolo 3 79 La prima applicazione Windows 8 /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name=”e”>Event data that describes how this page was reached. Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } } } The Modificare e testare l’applicazione 1. Modifica il file MainPage.xaml in modo che il relativo contenuto sia identico a quello mostrato nel Listato 3-1. 2. Apri il file contenente il code-behind file della pagina (MainPage.xaml.cs) e inserisci le linee evidenziate in grassetto nel Listato 3-2. 3. Aggiungi una nuova classe al progetto cliccando con il tasto destro sul termine “Biz” nel code behind e quindi selezionando Generate | Class. 4. Genera lo stub per il metodo GetPeople usando la stessa tecnica: clicca con il tasto destro sul metodo GetPeople e seleziona Generate | Method Stub. Utilizza il seguente codice per sostituire quello del file Biz.cs. using using using using System; System.Collections.Generic; System.Linq; System.Text; namespace MyFirstApp { public class Biz { public List<Person> GetPeople() { return new List<Person>() { new Person() { FullName new Person() { FullName new Person() { FullName new Person() { FullName new Person() { FullName new Person() { FullName new Person() { FullName new Person() { FullName }; } } = = = = = = = = “Roberto Brunetti” }, “Paolo Pialorsi” }, “Marco Russo” }, “Luca Regnicoli” }, “Vanni Boncinelli” }, “Guido Zambarda” }, “Jessica Faustinelli” }, “Katia Egiziano” } public class Person { public string FullName { get; set; } } } 80 Creare applicazioni per Windows 8 Passo per Passo 5. Esegui l’applicazione Il codice della classe Biz si limita a restituire una lista di persone rappresentate dalla classe Person. Per semplicità, questa classe si limita a esporre una sola proprietà, FullName. Se esegui l’applicazione, dovresti ottenere un risultato simile a quello mostrato in Figura 3-4, e dovresti essere in grado di selezionare una persona dalla lista. FIGURA 3-4 La pagina principale dell’applicazione che presenta una lista di nomi Questo è il momento di mettere da parte lo sviluppatore che è in te e di “indossare il cappello” da designer per trasformare una semplice lista in qualcosa di più “accattivante”. Interrompi la sessione di debug e torna a Visual Studio 2012. Prima di procedere a rifinire l’aspetto della lista, però, devi aggiungere alcuni elementi di user interface alla pagina—come un controllo TextBlock per visualizzare il titolo dell’applicazione—così da far apparire la tua applicazione meglio integrata con l’ambiente di Windows 8. Per aggiungere un titolo, è necessario modificare il codice XAML nel file MainPage.xaml, come mostrato nel Listato 3-3: LISTATO 3-3 La pagina MainPage.xaml con un controllo Grid <Page x:Class=”MyFirstApp.MainPage” xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” xmlns:local=”using:MyFirstApp” xmlns:d=”http://schemas.m icrosoft.com/expression/blend/2008” Capitolo 3 La prima applicazione Windows 8 81 xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006” mc:Ignorable=”d”> <Grid Background=”{StaticResource ApplicationPageBackgroundThemeBrush}”> <Grid.RowDefinitions> <RowDefinition Height=”140”/> <RowDefinition Height=”*”/> </Grid.RowDefinitions> <!-- page title --> <Grid Grid.Row=”0” Grid.Column=”0”> <Grid.ColumnDefinitions> <ColumnDefinition Width=”120”/> <ColumnDefinition Width=”*”/> </Grid.ColumnDefinitions> <TextBlock x:Name=”pageTitle” Grid.Column=”1” Text=”My First Windows 8 App” Style=”{StaticResource PageHeaderTextStyle}”/> </Grid> <ListView x:Name=”list” DisplayMemberPath=”FullName” Grid.Row=”1” Grid.Column=”0” Margin=”116,0,0,46”/> </Grid> </Page> Se adesso premi F5 in Visual Studio, la tua pagina dovrebbe assomigliare a quella mostrata in Figura 3-5. FIGURA 3-5 Pagina principale che riporta il titolo dell’applicazione 82 Creare applicazioni per Windows 8 Passo per Passo Nel listato precedente abbiamo usato una Grid come elemento root della pagina. In XAML, il pannello Grid permette di posizionale gli elementi child (letteralmente, elementi “figli”) in righe e colonne, così come di definire in anticipo il numero e le proprietà di ciascuna riga e colonna sfruttando le proprietà RowDefinitions e ColumnDefinitions del controllo Grid. Nel nostro esempio, la griglia principale è stata suddivisa in due righe. Adesso è tempo di ritornare al codice per una spiegazione più approfondita. Le prime quattro righe di codice relative al controllo Grid sono le seguenti: <Grid Background=”{StaticResource ApplicationPageBackgroundThemeBrush}”> <Grid.RowDefinitions> <RowDefinition Height=”140”/> <RowDefinition Height=”*”/> </Grid.RowDefinitions> Per definire righe e colonne della griglia principale, abbiamo usato la proprietà Grid.RowDefinitions. Questa sintassi (nella forma classtype.propertyname, conosciuta anche come sintassi “extended property”) rappresenta una modalità standard per impostare un insieme complesso di proprietà tramite il linguaggio di markup XAML . All’interno della proprietà RowDefinitions troverai due elementi RowDefinition: la prima imposta l’altezza a 140 pixel, mentre la seconda usa il carattere “*” (asterisco) per impostare un valore non definito in fase di design (“design-time”) che indica a runtime di riempire lo spazio rimanente dello schermo. Tieni sempre a mente che disegnare un’interfaccia utente in grado di adattarsi alla risoluzione dello schermo dell’utente è sempre più importante, dato che i tablet e i dispositivi oggi in commercio offrono un’ampia varietà di risoluzioni e orientamenti. Usare un dimensionamento relativo degli elementi piuttosto che uno assoluto aiuta moltissimo a raggiungere l’obiettivo di realizzare un’interfaccia in grado di adattarsi ai diversi dispositivi. Per assegnare ciascun elemento grafico a una specifica cella della griglia è sufficiente impostare le proprietà Grid.Row e Grid.Column dell’elemento stesso. Queste proprietà sono anche definite “attached property”, perché non appartengono all’object model del controllo, ma sono piuttosto “attaccate” al controllo medesimo. L’esempio proposto prevede due elementi child all’interno della griglia principale: n Il primo elemento child è rappresentato da un (ulteriore) controllo Grid destinato a contenere gli elementi relativi al titolo della pagina. Questo controllo Grid utilizza due “attached property”: Grid.Row e Grid.Column, entrambe con valore 0. In questo modo, l’elemento verrà collocato nella prima cella della griglia principale. Il secondo elemento child è costituito da un controllo ListView con le proprietà Grid.Row = “1” e Grid.Column = “0,” dunque posizionato nella seconda riga della prima colonna. Ecco alcuni utili suggerimenti relativi al controllo Grid: n Puoi omettere di specificare le proprietà Grid.Row e/o Grid.Column se il loro valore è 0. n Se un controllo Grid non imposta esplicitamente la proprietà RowDefinitions, è considerato come se avesse una singola RowDefinition con altezza impostata a ”*”. n Se il controllo Grid non definisce esplicitamente la proprietà ColumnDefinitions, è considerato come se avesse una sola ColumnDefinition la cui proprietà Width è impostata a ”*”. Capitolo 3 La prima applicazione Windows 8 83 n Puoi impostare la proprietà Height di RowDefinition ad “Auto,” nel qual caso la sua dimensione verrà definita a runtime in base all’altezza del controllo contenuto. n Puoi impostare la proprietà Width di ColumnDefinition ad “Auto,” nel qual caso la sua dimensione verrà definita a runtime sulla base della larghezza del controllo contenuto. Continuando l’analisi del codice XAML, troverai un controllo Grid secondario, ulteriormente suddiviso in due colonne, il cui unico elemento child è rappresentato da un controllo TextBlock: <TextBlock x:Name=”pageTitle” Grid.Column=”1” Text=”My First Windows 8 App” Style=”{StaticResource PageHeaderTextStyle}”/> La proprietà Grid.Column = “1” significa che il controllo TextBlock verrà posizionato nella seconda colonna del controllo Grid “parent” (letteralmente, “elemento genitore”), mentre la proprietà Style fa riferimento a uno stile denominato PageHeaderTextStyle tramite la speciale sintassi {StaticResource} (avrai modo di esplorare i concetti principali relativi agli stili nei prossimi capitoli). Per il momento, tieni presente che uno stile è semplicemente un contenitore di proprietà aventi determinate impostazioni—un oggetto condiviso che può essere riutilizzato in scenari differenti. La proprietà Grid.Row = “1” è stata aggiunta al controllo ListView in modo che questo occupi l’intera seconda riga della griglia principale, mentre la proprietà Margin = “116,0,0,46” posiziona il controllo ListView a qualche pixel di distanza dai margini della cella. La proprietà Margin è impostata usando quattro valori separati da virgole. Il primo valore identifica la distanza dal bordo sinistro e quindi continua in senso orario: nel nostro esempio, il controllo ListView è collocato a 116 pixel di distanza dal bordo sinistro, 0 dal bordo superiore e da quello destro, e 46 pixel dal bordo inferiore. Prova adesso ad aggiungere nuove foto al progetto. Per far questo, trascina semplicemente la cartella denominata Photos (nel file demo per questo capitolo) in Visual Studio, e rilascia il pulsante del mouse sulla root del progetto denominato MyFirstApp. Come risultato di questa operazione, Visual Studio creerà all‘interno della root del progetto una directory denominata Photos (allo stesso livello delle directory Assets e Common) contenente alcuni file .jpg. Il passo successivo consiste nel modificare la classe Person per aggiungere una proprietà custom denominata Photo, e definire il componente di business per impostare questa proprietà. Il Listato 3-4 mostra il codice modificato da copiare nel file Biz.cs: LISTATO 3-4 Il codice modificato del file Biz.cs. using using using using System; System.Collections.Generic; System.Linq; System.Text; 84 Creare applicazioni per Windows 8 Passo per Passo namespace MyFirstApp { public class Biz { public List<Person> GetPeople() { return new List<Person>() { new Person() { FullName = “Roberto Brunetti”, Photo = “Photos/01.jpg” }, new Person() { FullName = “Paolo Pialorsi”, Photo = “Photos/02.jpg” }, new Person() { FullName = “Marco Russo”, Photo = “Photos/03.jpg” }, new Person() { FullName = “Luca Regnicoli”, Photo = “Photos/04.jpg” }, new Person() { FullName = “Vanni Boncinelli”, Photo = “Photos/05.jpg” }, new Person() { FullName = “Guido Zambarda”, Photo = “Photos/06.jpg” }, new Person() { FullName = “Jessica Faustinelli”, Photo = “Photos/07.jpg” }, new Person() { FullName = “Katia Egiziano”, Photo = “Photos/08.jpg” } }; } } public class Person { public string FullName { get; set; } public string Photo { get; set; } } } Per rendere la visualizzazione dell’elenco di nomi nel controllo ListView esteticamente più gradevole, è necessario modificare la proprietà ItemTemplate del controllo. È importante capire che in XAML, un template corrisponde al concetto di “struttura”: la proprietà ItemTemplate rappresenta dunque la struttura dei singoli elementi del controllo ListView. Comincia a modificare il codice XAML della pagina MainPage.xaml per introdurre alcuni miglioramenti nel controllo ListView. Sostituisci la definizione della ListView nel file MainPage.xaml: <ListView x:Name=”list” DisplayMemberPath=”FullName” Grid.Row=”1” Grid.Column=”0” Margin=”116,0,0,46”/> con il seguente codice markup: <ListView Grid.Row=”1” Grid.Column=”0” x:Name=”list” Margin=”116,0,0,46”> <ListView.ItemTemplate> <DataTemplate> <TextBlock Text=”{Binding FullName}” FontSize=”10” /> </DataTemplate> </ListView.ItemTemplate> </ListView> Nel secondo esempio è stata rimossa la proprietà DisplayMemberPath, che visualizza semplicemente una serie di stringhe collegate alla proprietà FullName dell’oggetto messo in binding, e la sostituisce con la proprietà ItemTemplate che accetta oggetti di tipo DataTemplate. In questo scenario, il DataTemplate consiste in una semplice TextBlock la cui proprietà Text è collegata alla proprietà FullName dell’oggetto in binding; se adesso esegui Capitolo 3 La prima applicazione Windows 8 85 l’applicazione, vedrai l’elenco di persone visualizzato con un font più piccolo. Non è certo un grande miglioramento rispetto alla precedente versione, ma questi passaggi rappresentano comunque la base per le prossime attività che sarai chiamato a svolgere. Nel prossimo passo, proveremo a modificare il DataTemplate di ciascun elemento così da visualizzare sia il nome che l’immagine. Sostituisci la definizione del DataTemplate del controllo ListView: <DataTemplate> <TextBlock Text=”{Binding FullName}” FontSize=”10” /> </DataTemplate> con il seguente codice: <DataTemplate> <StackPanel Width=”200” Height=”200”> <TextBlock Text=”{Binding FullName}” /> <Image Source=”{Binding Photo}” /> </StackPanel> </DataTemplate> Rispetto alla versione precedente, questo codice utilizza un nuovo pannello denominato StackPanel, che posiziona i propri elementi child uno sotto l’altro in verticale, ovvero—se la proprietà Orientation è impostata su «Horizontal»— uno accanto all‘altro. In questo scenario, ogni elemento della ListView verrà mostrato utilizzando uno StackPanel, il quale visualizzerà il nome della persona e la relativa foto mettendo in binding, rispettivamente, la proprietà FullName con la proprietà Text di una TextBlock e la proprietà Photo con la proprietà Source di un controllo Image. Fino ad ora abbiamo usato un controllo ListView, che visualizza una serie di elementi in verticale; adesso proverai a sostituire la definizione del controllo ListView, che era: <ListView Grid.Row=”1” Grid.Column=”0” x:Name=”list” Margin=”116,0,0,46”> <ListView.ItemTemplate> <DataTemplate> <StackPanel Width=”200” Height=”200”> <TextBlock Text=”{Binding FullName}” /> <Image Source=”{Binding Photo}” /> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> con questo markup che utilizza un controllo GridView: <GridView Grid.Row=”1” Grid.Column=”0” x:Name=”list” Margin=”116,0,0,46”> <GridView.ItemTemplate> <DataTemplate> <StackPanel Width=”200” Height=”200”> <TextBlock Text=”{Binding FullName}” /> <Image Source=”{Binding Photo}” /> </StackPanel> </DataTemplate> </GridView.ItemTemplate> </GridView> 86 Creare applicazioni per Windows 8 Passo per Passo Il controllo GridView, come suggerisce il nome, è in grado di visualizzare i suoi elementi in una forma tabulare, o a griglia. Se premi F5 in Visual Studio, vedrai il risultato mostrato in Figura 3-6. FIGURA 3-6 L’elemento selezionato nel controllo GridView personalizzato Questo risultato è accettabile, ma possiamo fare anche meglio usando un po’ di creatività e qualche linea di codice XAML all’interno del DataTemplate. Il prossimo listato mostra l’intera pagina MainPage.xaml con il codice modificato nei passaggi precedenti evidenziato in grassetto. Sostituisci l’intero codice della MainPage.xaml con il seguente: <Page x:Class=”MyFirstApp.MainPage” xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” xmlns:local=”using:MyFirstApp” xmlns:d=”http://schemas.microsoft.com/expression/blend/2008” xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006” mc:Ignorable=”d”> <Grid Background=”{StaticResource ApplicationPageBackgroundThemeBrush}”> <Grid.RowDefinitions> <RowDefinition Height=”140”/> <RowDefinition Height=”*”/> </Grid.RowDefinitions> Capitolo 3 La prima applicazione Windows 8 87 <!-- Back button and page title --> <Grid Grid.Row=”0” Grid.Column=”0”> <Grid.ColumnDefinitions> <ColumnDefinition Width=”120”/> <ColumnDefinition Width=”*”/> </Grid.ColumnDefinitions> <TextBlock x:Name=”pageTitle” Grid.Column=”1” Text=”My First Windows 8 App” Style=”{StaticResource PageHeaderTextStyle}”/> </Grid> <GridView Grid.Row=”1” Grid.Column=”0” x:Name=”list” Margin=”116,0,0,46”> <GridView.ItemTemplate> <DataTemplate> <Grid> <Image Source=”{Binding Photo}” Width=”200” Height=”130” Stretch=”UniformToFill” /> <Border Background=”#A5000000” Height=”45” VerticalAlignment=”Bottom”> <StackPanel Margin=”10,-2,-2,-2”> <TextBlock Text=”{Binding FullName}” Margin=”0,20,0,0” Foreground=”#7CFFFFFF” HorizontalAlignment=”Left” /> </StackPanel> </Border> </Grid> </DataTemplate> </GridView.ItemTemplate> </GridView> </Grid> </Page> Il nuovo DataTemplate utilizza una Grid come elemento root, con due elementi al suo interno: una Image e un Border. Dato che la Grid non ha né RowDefinitions né ColumnDefinitions, verrà visualizzata come una singola cella contenente i due elementi child, secondo l’ordine definito nel markup—il che significa che il primo elemento child renderizzato dal runtime sarà il controllo Image, quindi il controllo Border (con tutti i suoi elementi child) verrà renderizzato in overlay. Oltre a queste modifiche, il markup XAML aggiunge una sola cosa: la proprietà Background del controllo Border che contiene la seguente stringa “#A5000000”. Vale la pena notare che i primi due caratteri dopo # rappresentano il canale alfa, ossia la trasparenza, del colore definito dai successivi sei caratteri (nero, in questo caso). Infatti, nell’esempio proposto il Border non utilizza un colore pieno e opaco come background, quanto piuttosto un colore nero semi-trasparente che rende l’aspetto grafico più gradevole. Il risultato finale è decisamente in linea con l’ecosistema di Windows 8 e visivamente gradevole, come puoi desumere dalla Figura 3-7. 88 Creare applicazioni per Windows 8 Passo per Passo FIGURA 3-7 Una differente personalizzazione del controllo GridView Vale la pena osservare che i controlli messi a disposizione dal framework supportano in modo nativo qualsiasi tipo di input, come mouse, tastiera, touch screen e penna—in altre parole, non è necessario scrivere alcun codice specifico per gestire i diversi tipi di input. Aggiungere la funzionalità di Search In questa sezione, aggiungeremo alla nostra applicazione il codice necessario per sfruttare la funzionalità di ricerca all’interno dell’applicazione stessa. Una cosa che potresti aver notato in un progetto Windows Store è l’assenza di reference ad altri assembly; se infatti apri l‘elemento References nell’albero del progetto, non troverai il classico System.Qualcosa assembly. Al contrario, troverai soltanto una reference alle librerie .NET for Windows Store apps e Windows. Questi due assembly contengono tutte le classi del Windows Runtime necessarie per sviluppare un’applicazione Windows Store. Puoi dunque implementare l’intera funzionalità di Search all’interno della tua applicazione senza dover aggiungere alcuna reference; solo se deciderai di creare la tua libreria di classi avrai la necessità di aggiungere una reference al relativo assembly. Puoi trovare maggiori informazioni in merito allo sviluppo di librerie personali nel Capitolo 5, “Introduzione al Windows Runtime”. Capitolo 3 La prima applicazione Windows 8 89 In una delle precedenti procedure, abbiamo aggiunto la Search Declaration all’applicazione, permettendo così al sistema operativo di includere la nostra applicazione nel pannello di Search. La dichiarazione nel manifest informa infatti il runtime di Windows 8 dicendogli: “Sono un’applicazione ricercabile”. In altre parole, il sistema includerà l’applicazione tra i possibili target per una ricerca all’interno dell’applicazione stessa. Quando l’utente seleziona l’applicazione come target della propria ricerca, questa viene attivata e il testo digitato dall’utente viene passato come querystring all’applicazione. L’idea sottostante è piuttosto semplice: l’applicazione è l’unico componente che può decidere come mostrare i risultati della ricerca; nessun altro componente, né tantomeno il sistema operativo, conoscono qualcosa dei dati interni all’applicazione. Il modo con cui questi dati sono visualizzati è specifico per quella particolare applicazione. Nel Capitolo 6, “Windows Runtime API,” entreremo nei dettagli delle varie API di WinRT, come Share, Webcam, FilePicker, ecc. La funzionalità di ricerca è implementata da un contratto, denominato “Search Contract”, che regola l’interazione tra l’applicazione e il sistema operativo. Il Search Contract stabilisce che: n L’applicazione necessita di essere registrata. La registrazione è basata sulla relativa dichiarazione nel manifest. n La dichiarazione può includere il nome dell’eseguibile, ossia il nome del file .exe che rappresenta l’applicazione—l’entry point applicativo che il sistema invocherà qualora l’utente scelga l’applicazione come “search target”. n Spetta all’applicazione presentare i dati nel formato più appropriato in un’apposita pagina. n L’applicazione riceverà il testo di ricerca digitato dall‘utente in corrispondenza dell‘entry point. Sarà poi responsabilità dell‘applicazione presentare all‘utente la pagina con il relativo feedback: questo può consistere nell‘elenco degli elementi trovati o in un messaggio (nel caso in cui la ricerca non abbia avuto esito positivo), come «Nessun risultato» o «Dati non disponibili, riprova più tardi». Cerca di mostrare all‘utente un messaggio che sia il più specifico possibile. n Windows provvede a gestire la cronologia delle ricerche (Search History) dell‘utente. n L‘applicazione può fornire suggerimenti per il testo digitato dall‘utente. Aggiungere il Search Contract Il template messo a disposizione da Visual Studio permette di implementare in modo semplice un contratto di ricerca che copre tutti i punti sopra evidenziati, salvo l’ultimo. Il primo passo da compiere in questa procedura consiste nell’eliminare la Search Declaration che abbiamo aggiunto nella procedura precedente in modo da esplorare l’intero processo di implementazione di default. Segui i prossimi passi per aggiungere la funzionalità di ricerca. 1. Apri il Package.appxmanifest per rimuovere la Search Declaration. Vai al tab Declarations, cerca “Search” nell’elenco delle Supported Declaration, seleziona la relativa voce e clicca su Remove. Salva il manifest. 90 Creare applicazioni per Windows 8 Passo per Passo 2. Aggiungi un nuovo elemento Search Contract cliccando con il tasto destro sul progetto all’interno del Solution Explorer e seleziona Add | New Item. 3. Nel dialog Add New Item, seleziona Search Contract e assegnagli il nome SearchPeople.xaml, come mostrato nella prossima figura. Clicca su OK. 4. Clicca su Yes nel dialog che ti chiederà se vuoi aggiungere i file necessari all’implementazione del contratto. Testare il componente di ricerca di default Prima di procedere oltre, puoi testare immediatamente l’applicazione per comprendere a fondo il flusso completo. Implementerai il meccanismo di ricerca nella procedura immediatamente successiva. 1. Installa l’applicazione da Visual Studio cliccando con il tasto destro sul progetto nel Solution Explorer e seleziona Deploy. 2. Premi Windows+Q per attivare il pannello Search. 3. Digita del testo da ricercare nel relativo box e seleziona MyFirstApp dalla lista di applicazioni disponibili. Il sistema operativo lancerà l’applicazione (la quale non era ancora in esecuzione, dato che l’hai appena installata), e attiverà la ricerca all’interno dell’applicazione stessa tramite una chiamata all’entry point del Search Contract. L’applicazione mostrerà la pagina SearchPeople.xaml, la quale ovviamente non visualizzerà ancora nessun risultato, come mostrato nella seguente immagine. Capitolo 3 La prima applicazione Windows 8 91 4. Premi ancora Windows+Q per iniziare una nuova ricerca. 5. Digita del testo nel box di ricerca e seleziona MyFirstApp nell’elenco delle applicazioni. La pagina dei risultati sarà identica a quella precedente, ma questa volta il pulsante di Back risulterà abilitato, dato che il “search target” (ossia la tua applicazione) era già in esecuzione nel momento in cui la ricerca è stata attivata. 6. Clicca sul pulsante Back e nota che l’applicazione si presenterà nello stesso stato. 7. Torna alla Start Page e apri un’altra applicazione (Mail dovrebbe andare bene). Ripeti i passi da 6 a 8. Il risultato sarà sempre una pagina vuota, ma se questa volta clicchi sul pulsante Back tornerai alla pagina relativa ai risultati della ricerca precedente—il che dimostra come l’applicazione sia stata sospesa dal runtime e ripristinata quando il “search target” è stato attivato. 8. Premi Alt+Tab (sì, questa combinazione di tasti funziona ancora in Windows 8) per portare un’altra applicazione in primo piano. 9. Torna alla Start Page e lancia la tua applicazione. L’applicazione visualizzerà i risultati della ricerca perché Windows 8 ha sospeso l’applicazione per poi ripristinarla quando l’utente l’ha riportata in primo piano. Adesso che abbiamo visto l’intero flusso della ricerca, è tempo di implementare il template del Search Contract. Il template aggiunge la relativa Search Declaration al Package.appxmanifest, come puoi facilmente verificare facendo doppio click sul file e selezionando il tab Declarations. Il template modifica anche il progetto—tra le altre cose, aggiunge una nuova pagina per la visualizzazione dei risultati della ricerca (SearchPeople.xaml, o qualunque altro nome usato nel dialog Add New Item), e che hai avuto modo di vedere all’opera nella precedente procedura quando hai selezionato MyFirstApp come “search target”. 92 Creare applicazioni per Windows 8 Passo per Passo Questa nuova pagina è mostrata quando viene attivata la ricerca. Il contratto definisce l’entry point per la richiesta di ricerca che, per default, è rappresentato dalla classe App. Il template del Search Contract utilizzato da Visual Studio modifica anche il file App.xaml.cs realizzando l’override del metodo OnSearchActivated della classe base, in modo da visualizzare la pagina dei risultati della ricerca. Il Listato 3-5 mostra il codice completo del file App. xaml.cs. LISTATO 3-5 Il code-behind della classe App: App.xaml.cs. using using using using using using using using using using using using using using using System; System.Collections.Generic; System.IO; System.Linq; Windows.ApplicationModel; Windows.ApplicationModel.Activation; Windows.Foundation; Windows.Foundation.Collections; Windows.UI.Xaml; Windows.UI.Xaml.Controls; Windows.UI.Xaml.Controls.Primitives; Windows.UI.Xaml.Data; Windows.UI.Xaml.Input; Windows.UI.Xaml.Media; Windows.UI.Xaml.Navigation; // The Blank Application template is documented at http://go.microsoft.com/ fwlink/?LinkId=234227 namespace MyFirstApp { /// <summary> /// Provides application-specific behavior to supplement the default Application class. /// </summary> sealed partial class App : Application { /// <summary> /// Initializes the singleton application object. /// This is the first line of authored code /// executed, and as such is the logical equivalent of main() or WinMain(). /// </summary> public App() { this.InitializeComponent(); this.Suspending += OnSuspending; } /// <summary> /// Invoked when the application is launched normally by the end user. /// Other entry points will be used when the application is launched to open /// a specific file, to display, search results, and so forth. /// </summary> /// <param name=”args”>Details about the launch request and process.</param> protected override void OnLaunched(LaunchActivatedEventArgs args) { Frame rootFrame = Window.Current.Content as Frame; Capitolo 3 La prima applicazione Windows 8 // Do not repeat app initialization when the Window already has content, // just ensure that the window is active if (rootFrame == null) { // Create a Frame to act as the navigation context and navigate // to the first page rootFrame = new Frame(); if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) { //TODO: Load state from previously suspended application } // Place the frame in the current Window Window.Current.Content = rootFrame; } if (rootFrame.Content == null) { // When the navigation stack isn’t restored navigate to // the first page, configuring the new page by passing // required information as a navigation parameter if (!rootFrame.Navigate(typeof(MainPage), args.Arguments)) { throw new Exception(“Failed to create initial page”); } } // Ensure the current window is active Window.Current.Activate(); } /// <summary> /// Invoked when application execution is being suspended. /// Application state is saved without knowing whether the application /// will be terminated or resumed with the contents /// of memory still intact. /// </summary> /// <param name=”sender”>The source of the suspend request.</param> /// <param name=”e”>Details about the suspend request.</param> private void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); //TODO: Save application state and stop any background activity deferral.Complete(); } /// <summary> /// Invoked when the application is activated to display search results. /// </summary> /// <param name=”args”>Details about the activation request.</param> protected async override void OnSearchActivated( Windows.ApplicationModel.Activation.SearchActivatedEventArgs args) { // TODO: Register the Windows.ApplicationModel.Search.SearchPane. // GetForCurrentView().QuerySubmitted // event in OnWindowCreated to speed up searches once // the application is already running 93 94 Creare applicazioni per Windows 8 Passo per Passo // If the Window isn’t already using Frame navigation, insert our own Frame var previousContent = Window.Current.Content; var frame = previousContent as Frame; // // // if { If the app does not contain a top-level frame, it is possible that this is the initial launch of the app. Typically this method and OnLaunched in App.xaml.cs can call a common method. (frame == null) // Create a Frame to act as the navigation context and associate it with // a SuspensionManager key frame = new Frame(); MyFirstApp.Common.SuspensionManager.RegisterFrame(frame, “AppFrame”); if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) { // Restore the saved session state only when appropriate try { await MyFirstApp.Common.SuspensionManager.RestoreAsync(); } catch (MyFirstApp.Common.SuspensionManagerException) { //Something went wrong restoring state. //Assume there is no state and continue } } } frame.Navigate(typeof(SearchPeople), args.QueryText); Window.Current.Content = frame; // Ensure the current window is active Window.Current.Activate(); } } } Il metodo OnLaunched rappresenta il codice standard suggerito dal template per un’applicazione Windows Store ed è necessario per attivare la pagina principale nel momento in cui l’utente lancia l’applicazione. Un’applicazione viene “lanciata” quando non era già in esecuzione. Il metodo OnSearchActivated rappresenta invece l’implementazione di default del Search Contract. Il codice istanzia la pagina in cui verranno mostrati i risultati della ricerca (in questo caso SearchPeople.xaml) e invoca il metodo custom Activate passando come parametro gli argomenti a sua volta ricevuti. I SearchActivatedEventArgs utilizzati dal metodo OnSearchActivated e i LaunchActivatedEventArgs usati dal metodo OnLaunched implementano entrambi l’interfacia IActivatedEventArgs. La prima proprietà dell’interfaccia è Kind, la quale può assumere uno dei valori definiti nell’enumerazione ActivationKind. Questa proprietà permette agli sviluppatori di determi- Capitolo 3 La prima applicazione Windows 8 95 nare il tipo di attivazione durante la fase di lancio: per esempio, se l’applicazione è lanciata dall’utente, questa proprietà sarà ActivationKind.Launch. Se invece l’applicazione è lanciata dal sistema allorché questa è stata designata dall’utente come “search target”, la proprietà sarà ActivationKind.Search. Se infine l’applicazione è attivata per ricevere del contenuto proveniente da altre applicazioni tramite lo Share Contract, la proprietà sarà ActivationKind. ShareTarget. La proprietà QueryText dei SearchActivatedEventArgs contiene il testo digitato dall’utente nel pannello Search. Questa proprietà è utilizzata nel metodo di default OnSearchActivated durante la navigazione verso la pagina di ricerca, come puoi vedere nel seguente estratto. frame.Navigate(typeof(SearchPeople), args.QueryText); Window.Current.Content = frame; // Ensure the current window is active Window.Current.Activate(); Il testo da ricercare è ricevuto nel parametro navigationParameter (di tipo Object) del metodo LoadState della pagina SearchPeople.xaml.cs e viene utilizzato per costruire la proprietà QueryText dell’interfaccia utente nella proprietà DefaultViewModel della pagina. Il seguente listato mostra il codice relativo a questo metodo. LISTATO 3-6 Estratto del code behind SearchPeople.xaml.cs. protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState) { var queryText = navigationParameter as String; // // // // // // // // // // TODO: Application-specific searching logic. The search process is responsible for creating a list of user-selectable result categories: filterList.Add(new Filter(“<filter name>”, <result count>)); Only the first filter, typically “All”, should pass true as a third argument in order to start in an active state. Results for the active filter are provided in Filter_SelectionChanged below. var filterList = new List<Filter>(); filterList.Add(new Filter(“All”, 0, true)); // Communicate results through the view model this.DefaultViewModel[“QueryText”] = ‘\u201c’ + queryText + ‘\u201d’; this.DefaultViewModel[“Filters”] = filterList; this.DefaultViewModel[“ShowFilters”] = filterList.Count > 1; } Il codice sopra presentato è relativamente semplice. La prima riga definisce una variabile locale denominata queryText per contenere il testo digitato dall’utente nel box di ricerca. Il testo è stato ricevuto durante l’attivazione della ricerca come proprietà QueryText dei SearchActivatedEventArgs. 96 Creare applicazioni per Windows 8 Passo per Passo Il placeholder aggiunto dall’implementazione di default del metodo permette di aggiungere la logica di business per ricercare il testo all’interno dei dati applicativi e rappresenta la parte più importante di questo codice. Le ultime tre righe di codice sono utili nel caso in cui tu decidessi di utilizzare il layout di default per mostrare i risultati della ricerca. Il codice assegna, rispettivamente, il testo per la query, l’elenco dei filtri e un valore booleano per indicare se mostrare o meno l’elenco dei filtri. Proviamo a implementare la logica di ricerca riutilizzando il layer di business incontrato all’inizio del capitolo. Implementare la logica di ricerca Nella seguente procedura implementeremo la logica necessaria a recuperare una lista di nominativi che soddisfino i criteri di ricerca. Sebbene sia possibile implementare tale logica tramite una query LINQ (Language Integrated Query) sulla lista restituita dal metodo List del componente di business, considera l’idea di passare il testo da ricercare al componente di business in modo da lasciare a quest’ultimo il compito di effettuare la ricerca nei layer sottostanti. È infatti generalmente una cattiva idea quella di filtrare l’intero set di dati in memoria nel layer della user interface. Per finalità puramente illustrative, questa semplice applicazione non presenta alcun layer di persistenza, per cui saremo costretti a implementare la ricerca in memoria all’interno del layer di business. 1. Aggiungi un metodo al componente di business (Biz.cs) per filtrare il data source usando il seguente codice. public List<Person> GetPeople(String search) { var list = this.GetPeople(); return list.Where(p => p.FullName.Contains(search)).ToList(); } 2. Aggiungi una chiamata al nuovo metodo GetPeople dal metodo LoadState del file SearchPeople.xaml.cs e assegna il risultato alla proprietà DefaultViewModel. Usa il seguente codice come riferimento (le righe da aggiungere sono evidenziate in grassetto). protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState) { var queryText = navigationParameter as String; // TODO: Application-specific searching logic. The search process is // responsible for creating a list of user-selectable result categories: // // filterList.Add(new Filter(“<filter name>”, <result count>)); // // Only the first filter, typically “All”, should pass true as a third argument // in order to start in an active state. Results for the active filter // are provided in Filter_SelectionChanged below. var biz = new Biz(); var people = biz.GetPeople(queryText); this.DefaultViewModel[“Results”] = people; var filterList = new List<Filter>(); filterList.Add(new Filter(“All”, 0, true)); Capitolo 3 La prima applicazione Windows 8 97 // Communicate results through the view model this.DefaultViewModel[“QueryText”] = ‘\u201c’ + queryText + ‘\u201d’; this.DefaultViewModel[“Filters”] = filterList; this.DefaultViewModel[“ShowFilters”] = filterList.Count > 1; } 3. Apri la pagina SearchPeople.xaml e cerca il controllo GridView denominato “resultGridView.” Rimuovi la definizione di default dell’ItemTemplate e sostituiscila con un’altra che mostri il nome di ciascuna delle persone restituite dal componente di business. Il codice che segue mostra la definizione completa del controllo: <GridView x:Name=”resultsGridView” AutomationProperties.AutomationId=”ResultsGridView” AutomationProperties.Name=”Search Results” TabIndex=”1” Grid.Row=”1” Margin=”0,-238,0,0” Padding=”110,240,110,46” SelectionMode=”None” IsSwipeEnabled=”false” IsItemClickEnabled=”True” ItemsSource=”{Binding Source={StaticResource resultsViewSource}}”> <GridView.ItemTemplate> <DataTemplate> <TextBlock Text=”{Binding FullName}” Margin=”0,20,0,0” Foreground=”#7CFFFFFF” HorizontalAlignment=”Left” /> </DataTemplate> </GridView.ItemTemplate> <GridView.ItemContainerStyle> <Style TargetType=”Control”> <Setter Property=”Height” Value=”70”/> <Setter Property=”Margin” Value=”0,0,38,8”/> </Style> </GridView.ItemContainerStyle> </GridView> 4. Effettua un deployment dell’applicazione e testa il form di ricerca dal pannello Search, come hai visto nella procedura “Testare il componente di ricerca di default”. Il risultato è mostrato nella seguente immagine. 98 Creare applicazioni per Windows 8 Passo per Passo L’ultima cosa che devi fare per completare questa semplice applicazione di esempio è modificare il valore della proprietà DefaultViewModel per mostrare l’effettivo numero di persone recuperate dalla ricerca. Modificare le proprietà del View Model In questa procedura modificheremo il codice in modo da mostrare in numero di risultati restituiti dalla ricerca. La procedura è decisamente semplice. 1. Modifica il metodo LoadState come segue. Le righe di codice modificate sono evidenziate in grassetto. protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState) { var queryText = navigationParameter as String; // // // // // // // // // TODO: Application-specific searching logic. The search process is responsible for creating a list of user-selectable result categories: filterList.Add(new Filter(“<filter name>”, <result count>)); Only the first filter, typically “All”, should pass true as a third argument in order to start in an active state. Results for the active filter are provided in Filter_SelectionChanged below. Capitolo 3 La prima applicazione Windows 8 99 var biz = new Biz(); var people = biz.GetPeople(queryText); this.DefaultViewModel[“Results”] = people; var filterList = new List<Filter>(); filterList.Add(new Filter(“All”, people.Count, true)); // Communicate results through the view model this.DefaultViewModel[“QueryText”] = ‘\u201c’ + queryText + ‘\u201d’; this.DefaultViewModel[“Filters”] = filterList; this.DefaultViewModel[“ShowFilters”] = filterList.Count >= 1; } In pratica, il filtro aggiunto alla lista (quello cioè che contiene il termine “All”) include il numero di risultati effettivi (indicati dalla proprietà people.Count), mentre la proprietà booleana ShowFilters indica se mostrare o meno all’utente i filtri disponibili. Ovviamente, è necessario implementare ciascuno dei filtri con relativo codice. 2. Controlla di aver chiuso l’applicazione tramite il Task Manager, in quanto l’applicazione potrebbe essere ancora in esecuzione dall’ultima procedura. Se ancora in esecuzione, terminala. 3. Installa l’applicazione e testala ancora tramite il pannello Search. Se adesso cerchi il testo “Rob”, dovresti ottenere un risultato simile a quello mostrato nella prossima figura. 100 Creare applicazioni per Windows 8 Passo per Passo Riepilogo In questo capitolo, abbiamo visto il ciclo completo di una semplice applicazione Windows 8, dalla sua creazione, al testing fino alla sua installazione in locale. Abbiamo anche preso confidenza con i template messi a disposizione da Visual Studio, e imparato come descrivere l’applicazione tramite il suo manifest. Infine, abbiamo aggiunto il codice necessario a implementare il Search Contract utilizzando il relativo template di default. Il prossimo capitolo è dedicato alla gestione del ciclo di vita di un’applicazione. Vedremo nei dettagli l’application manifest, come creare il package, testare e installare l’applicazione, nonché come Windows 8 gestisce il lancio, la sospensione e la chiusura di un’applicazione. Quick Reference Per Fai così Disporre i controlli all’interno di una griglia in grado di adattarsi al suo contenuto Usa il controllo Grid. Allineare gli elementi child in orizzontale o in verticale Usa il controllo StackPanel. Installare un’applicazione Windows Store In Visual Studio 2012, clicca con il tasto destro sul progetto nel Solution Explorer e seleziona la voce di menu Deploy. Installare e testare un’applicazione In Visual Studio, premi F5. Implementare il Search Contract Usa il template messo a disposizione dall’SDK e denominato Search Contract, il quale aggiunge alla solution la pagina dei risultati e del codice esemplificativo, modificando altresì la relativa dichiarazione nel manifest. Definire le funzionalità applicative Apri il file Package.appxmanifest tramite il relativo designer messo a disposizione da Visual Studio 2012. Chiudere un’applicazione Interrompi la sessione di debug, se in corso, o premi Alt+F4, o usa uno “swipe” dal bordo superiore dello schermo verso il bordo inferiore, oppure utilizza il nuovo Task Manager per terminare il relativo processo.