Definizione: Silverlight è un plug-in cross-browser , cross-platform e cross-device per lo sviluppo di applicazioni web di ultima generazione.
Perché è importante questa definizione? Originariamente Silverlight si chiamava WPF/E , dove "E" stava per Everywhere, mentre WPF, è l'acronimo di Windows Presentation Foundation, la tecnologia Microsoft rilasciata per lo sviluppo di applicazioni con interfacce utente di ultima generazione, sia per il Desktop che per il Web.
Allora perché Silverlight? La risposta è semplice: WPF richiede l'uso di .Net 3.0 sulla macchina sulla quale gira l'applicazione questo perché ne sfrutta a pieno le funzionalità. Silverlight si ispira a questa tecnologia utilizzando un sottoinsieme delle API usate da WPF ed in particolare al linguaggio dichiarativo noto come XAML (Extensible Application Markup Language).
Mentre con WPF si possono realizzare applicazioni che sfruttano a pieno le funzionalità offerte dal sistema operativo client, che ci permettono ad esempio di realizzare applicazioni con funzionalità 3D e di sfruttare la GPU di una moderna scheda grafica, Silverlight permette di realizzare applicazioni Web per diverse piattaforme, browser ed in futuro anche per dispositivi di natura diversa, come cellulari e smartphone.
Per verificare le diverse piattaforme e browser supportati è possibile consultare l'elenco aggiornato.
Le versioni di Silverlight
Al momento esistono due versioni di Silverlight: la 1.0, ormai rilasciata, e la versione 2, che è lo scopo principale di questo articolo.
Silverlight 1.0 utilizza XAML come linguaggio per la definizione del layout e delle animazioni, mentre per aggiungere la logica applicativa si serve di JavaScript. Tanto per fissare le idee pensiamo ad una semplice applicazione che mostra un bottone: l'oggetto verrà descritto in XAML, mentre la definizione e gestione dell'evento click
sarà implementato in JavaScript. Sempre con JavaScript gestiamo eventi come il passaggio del mouse sul bottone e pilotiamo le eventuali animazioni come il cambiamento del colore.
La versione 2, che al momento della scrittura di questo articolo è stata rilasciata in beta 2, utilizza XAML per la definizione del'interfaccia, mentre il codice applicativo viene scritto in .NET ovvero in C# o VB.NET. Già Silverlight 1.1, una versione intermedia scaricabile come preview, integrava la programmazione .NET; la versione 2 ne è l'evoluzione naturale.
Il runtime
La grandissima novità consiste nel fatto che è possibile scrivere codice .NET per un plug-in cross-platform. Non è necessario infatti installare una specifica versione di .NET su Windows, Linux o Mac OS, perché scaricando il plug-in di Silverlight viene scaricata una versione "ridotta" del runtime del .NET Framework, eseguibile direttamente dal browser.
Nota: quando si parla di sviluppo con .NET per Silverlight ci si riferisce sempre a questa versione ridotta del runtime, e non quella completa installata sulla macchina.
La versione del runtime di Silverlight 2 beta 2 è di circa 4,6 MB
. Rispetto alla "beta 1" il runtime è aumentato di circa 0,6 MB
perché sono stati inclusi alcuni controlli, assenti nel runtime precedente. Questo fa si che un'applicazione che usa i controlli inclusi di default sarà poco più grande di qualche KB.
Da dove partire per sviluppare con Silverlight 2
Il punto di riferimento è il sito Community di Silverlight, nella sezione GetStarted in particolare. Come possiamo leggere anche sui consigli del sito ufficiale, è consigliabile munirsi di alcuni software prima di iniziare a lavorare con Silverlight 2.
Installare Visual Studio 2008
Una versione di Visual Studio 2008 ci aiuterà molto a lavorare con Silverlight 2. Possiamo installarne una dalla Standard in su, se non l'abbiamo, possiamo scaricare una versione Trial.
Installare i Silverlight Tools Beta 2 per Visual Studio 2008
Per lavorare con Visual Studio 2008 possiamo installare il toolkit apposito per Silverlight 2, se avevamo installata la Beta 1 dei tool, facciamo attenzione a rimuoverla. Nella pagina di download troviamo il file che installerà in un colpo solo:
- Il runtime
- L'SDK (Software Development Kit ) che contiene esempi e documentazione
- I tool per Visual Studio 2008
Nota: i tool della beta 2 possono essere installati anche se sulla macchina avete anche la beta 1 della SP1 di .NET Framework 3.5 e Visual Studio 2008.
Il processo di installazione dei tool è molto semplice, procede in modo automatizzato e non richiede particolare interazione.
Procurarsi la documentazione di riferimento
È disponibile on-line su MSDN oppure è scaricabile il manuale di riferimento in formato CHM, consultabile offline.
Installare Expression Blend 2.5 June 2008 Preview
Con la beta 2 di Silverlight 2 è stata rilasciata la June 2008 Preview di Expression Blend 2.5 . I programmi della famiglia Expression sono pensati per Designer e di conseguenza sono molto più focalizzati sulla parte di grafica e layout di un'applicazione.
Per sviluppare applicazioni con Silverlight 2 non è necessario utilizzare Blend, tuttavia Blend può rivelarsi utile anche allo sviluppatore per piccole modifice all'aspetto grafico delle applicazioni.
La cosa importante è che Visual Studio 2008 ed Expression Blend supportano lo stesso formato dei file di progetto: quindi possiamo iniziare a sviluppare con Visual Studio 2008, poi aprire lo stesso progetto con Expression Blend 2.5 o viceversa, il tutto senza preoccuparci di rovinare quanto fatto in precedenza. Questa soluzione è particolarmente utile nei casi in cui siano due persone a sviluppare sulla stesso progetto: chi si occupa di più degli aspetti di layout e grafica (che userà quindi Blend 2.5) e chi invece più della parte di codice applicativo (che userà invece Visual Studio 2008).
Creiamo la nostra prima applicazione
Lanciamo Visual Studio 2008 e creiamo un nuovo progetto da File>Nuovo>Progetto, nella maschera che segue possiamo scegliere un progetto di tipo "Silverlight Application"; possiamo utilizzare sia il template per C#, sia quello per VB.NET.
Nella schermata successiva possiamo definire meglio il tipo di progetto da creare: in particolare possiamo decidere se:
- creare un progetto esclusivamente di tipo Silverlight, che verrà ospitato da una pagina HTML generata in modo automatico in locale sul file system,
- oppure creare anche un progetto ASP.NET, sia di tipo Web Site che di tipo Web Application Project, che conterranno una pagina di test ASP.NET e una pagina HTML per lanciare l'applicazione.
Un progetto Silverlight 2, infatti, può essere ospitato anche in una semplice pagina HTML, quindi può essere installato su qualsiasi server Web che eroghi pagine statiche. Nel nostro caso lasciamo l'impostazione standard che creerà un progetto di tipo Web Site.
Come si vede in Esplora Risorse (Solution Explorer), Visual Studio ha predisposto una soluzione con due progetti: il primo (dall'alto) che contiene i file di Test che istanziano il plug-in di Silverlight sia in una pagina HTML che ASP.NET ed infine il vero e proprio progetto Silverlight.
Il progetto Web creato da Visual Studio 2008
Nella prima parte dell'articolo abbiamo visto come mettere le basi per un ambiente di sviluppo che ci consenta di realizzare applicazioni Silverlight 2
Nel seguito vedremo come è strutturato il progetto Web creato da Visual Studio 2008 che contiene il riferimento all'applicazione Silverlight, questo ci permetterà di capire meglio come istanziare il plug-in da una pagina HTML e ASP.NET e come configurarlo per eseguire una specifica applicazione.
Pagina HTML e tag Object
Se apriamo la pagina SilverlightPerHTMLITTestPage.html
(il nome della pagina HTML dipende dal nome che diamo al progetto) possiamo osservare l'utilizzo del tag <object>
per per Silverlight 2.
Nel tag <object>
possiamo vedere come viene usato il plug-in ed i parametri passati per inizializzarlo.
<div id="silverlightControlHost">
<object data="data:application/x-silverlight," type="application/x-silverlight-2-b2" width="100%" height="100%">
<param name="source" value="ClientBin/SilverlightPerHTMLit.xap"/>
<param name="onerror" value="onSilverlightError" />
<param name="background" value="white" />
<a href="http://go.microsoft.com/fwlink/?LinkID=115261" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
</a>
</object>
<iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
</div>
Non entriamo nel dettaglio di tutti i parametri, ma è utile segnalare il parametro source
che punta al file che contiene l'applicazione Silverlight. Il file ha estensione .xap
ed è a tutti gli effetti un file "zip", che contiene gli assembly e le risorse che il progetto Silverlight compilato produce.
La prima volta che compiliamo un progetto, infatti, viene creata una directory ClientBin
, nel progetto Web, con il file .xap
prodotto, come si vede in figura.
Il parametro onError
definisce una funzione JavaScript nella pagina HTML per la gestione di errori non gestiti direttamente e internamente all'applicazione Silverlight.
Subito dopo i parametri specifichiamo ciò che sarà visualizzato se il browser dell'utente non ha il plugin, o ne possiede una versione non adeguata. Per default, Visual Studio inserisce un'immagine che invita l'utente a scaricare e installare Silverlight.
Pagina ASPX
Per richiamare il plugin da una pagina aspx utilizziamo il controllo <asp:Silverlight>
, che espone una serie di attributi equivalenti a quelli visti in precedenza per il tag <object>.
<asp:Silverlight ID="Xaml1" runat="server"
Source="~/ClientBin/SilverlightPerHTMLit.xap"
MinimumVersion="2.0.30523" Width="100%" Height="100%" >
<PluginNotInstalledTemplate>
<!-- qui possiamo inserire il codice alternativo per chi non ha il plugin -->
</PluginNotInstalledTemplate>
</asp:Silverlight>
Inoltre per specificare il comportamento della Web Form quando Silverlight non è installato, possiamo utilizzare il template <PluginNotIntalledTemplate>
all'interno del quale definiremo ciò che sarà mostrato a chi non è in possesso del plugin.
Possiamo avere ulteriori chiarimenti sull'integrazione di Silverlight in applicazioni ASP.NET anche nella documentazione on-line.
Il progetto Silverlight
Vediamo ora il progetto Silverlight e notiamo subito che è composto da due file .xaml
e due file .cs
, che costituiscono le relative parti di codice applicativo.
- il file App.xaml, per i fini di questo articolo, possiamo considerarlo semplicemente come il punto d'ingresso per un'applicazione Silverlight
- il file Page.xaml, è di maggiore interesse, al suo interno, infatti, scriviamo il codice XAML per costruire la nostra interfaccia utente
- associato al file XAML, c'è anche il file di code-behind Page.xaml.cs, che contiene il codice C# (in questo caso, poiché abbiamo creato un progetto specifico per questo linguaggio) per agganciare la logica applicativa
Nel caso volessimo realizzare un semplice button
, ne definiremmo la grafica in XAML, e implementeremmo la logica di gestione dell'evento di click
in .NET.
Cos'è XAML
L'Extensible Application Markup Language (XAML) è un linguaggio dichiarativo che serve a rappresentare gli oggetti e ad organizzarli in gerarchie. Viene utilizzato anche per WPF e WF. In Silverlight 2 utilizziamo solo un sottoinsieme del markup XAML messo a disposizione da WPF, per cui il passaggio da WPF a Silverlight 2 risulta semplificato.
Per i nostri scopi sarà utile concentrarci su alcune caratteristiche di questo linguaggio, in particolare sul concetto di Attached Property
e sul meccanismo di Data Binding
.
Tornando al nostro esempio, realizziamo finalmente un bottone, e scopriamo che il codice risulta molto leggibile.
Definire un bottone
<Button x:Name="btn1" Content="Il mio primo bottone" Height="50" Width="150" />
In questo modo abbiamo istanziato un oggetto di tipo Button
e gli abbiamo assegnato alcune proprietà. Lo stesso codice potrebbe essere scritto in C#: basterebbe dichiarare l'oggetto e aggiungerlo all'elemento root del nostro progetto.
L'elemento root del progetto realizzato da Visual Studio è un elemento di tipo Grid
, che costituisce il contenitore per tutti i controlli che aggiungeremo al progetto. Il controllo Grid, non è l'unico controllo che definisce il layout di un'applicazione Silverlight, esistono infatti anche lo StackPanel
e il Canvas
. Gli elementi in essi contenuti tenderanno a disporsi in base alle caratteristiche di ogni singolo controllo di layout.
- Grid: offre molta flessibilità ed i controlli in esso contenuto si disporranno in base alle righe e alle colonne definite nella griglia
- StackPanel: i controlli andranno ad impilarsi tra loro verticalmente o orizzontalmente in base all'orientamento del controllo
- Canvas: i controlli saranno posizionati in modo assoluto rispetto ad un sistema di coordinate ch ha origine nell'angolo in alto a sinistra del Canvas
Possiamo specificare la posizione di un controllo (pensiamo al nostro bottone) rispetto alle righe e colonne di una Grid
o rispetto alle coordinate sul Canvas
impostando le opportune proprietà.
Posizionare un controllo nella griglia (Grid)
<Grid x:Name="LayoutRoot">
<Button x:Name="btn1"
Grid.Column="1" Grid.Row="1"
Content="ciao" />
</Grid>
Nel Caso di un Canvas:
Posizionare un controllo nel Canvas
<Canvas x:Name="LayoutRoot" >
<Button x:Name="btn1"
Canvas.Top="10" Canvas.Left="10"
Content="ciao"/>
</Canvas>
Le Attached Property
Le proprietà viste sopra non sono delle proprietà "standard", vengono definite Attached Property e sono un concetto proprio di XAML. In questo esempio le proprietà per impostare il layout del bottone non sono definite nel bottone: le proprietà Grid.Row
e Canvas.Top
, ad esempio, sono in realtà definite nei rispettivi controlli di layout Grid
e Canvas
, il bottone le può impostare proprio perché è stato definito nel primo caso in una Grid
e nel secondo caso in un Canvas
.
Con l'utilizzo delle Attached Property, il nostro elemento button
a runtime istruisce l'elemento in cui è contenuto (una Grid
o un Canvas
a seconda dei casi) su come dovrà essere visualizzato nell'interfaccia.
Il meccanismo delle Attached Property inizialmente può sembrare un po' macchinoso, ma consente di far ereditare all'elemento "contenuto" le proprietà dell'elemento "contenitore", senza necessità di ridefinirle. Ad esempio non abbiamo bisogno di definire le proprietà di posizione per ogni elemento nel layout, ciascun oggetto semplicemente le "vede" quando si trova nel contenitore opportuno.
Il Code-Behind
Torniamo al nostro bottone e alla sua definizione XAML. Uno degli attributi più importanti da associare ad un controllo è x:Name
, che ne definisce il nome, appunto. Ciò che rende questo attributo così importante è il fatto che il nome che definiamo indentificherà l'elemento nel codice "code-behind".
Ma andiamo con ordine, se vogliamo aggiungere un comportamento legato all'evento "click" sul bottone, possiamo farlo direttamente dall'editor XAML
in Visual Studio 2008, che grazie all'IntelliSense, ci permette, premendo il tasto TAB
, di aggiungere un handler, cioè un gestore per il nostro evento.
L'operazione precedente ha anche come effetto quello di creare lo stub per l'implementazione del metodo nel file Page.xaml.cs
, dove possiamo scrivere codice .NET per la gestione dell'evento. Nell'esempio di codice seguente possiamo cambiare il valore della proprietà Content
del nostro controllo, che nel caso di un bottone ne definisce il testo.
private void btn1_Click(object sender, RoutedEventArgs e) { btn1.Content = "Cliccato!"; }
È utile notare come da codice C# referenziamo il controllo proprio usando il nome che abbiamo definito in XAML con l'attributo x:Name
.
I controlli per l'interfaccia utente
Con Silverlight 2 sono disponibili numerosi controlli, non è obiettivo di questo articolo esaminarli tutti, ma è possibile consultare un elenco online che mostra quelli attualmente disponibili.
La maggior parte dei controlli si trova già nel runtime, mentre alcuni di essi come DataGrid
, GridSplitter
, Calendar
, DatePicker
e TabControl
, sono inclusi in un assembly a parte.
Se effettuiamo il drag & drop di uno di questi controlli da Visual Studio 2008, notiamo che viene aggiunto un riferimento all'assembly System.Windows.Controls.Extended
e un nuovo namespace nel codice XAML della pagina. In questo caso quando compileremo il nostro progetto Silverlight l'assembly referenziato sarà aggiunto al file xap
.
Data Binding
Una volta realizzata l'interfaccia (o UI) il passo successivo è il collegamento ad una sorgente dati. Con i termini Data Binding ci si riferisce al collegamento di un elemento della UI, il target, ad una sorgente dati.
L'elemento dell'interfaccia che vogliamo "collegare" è una Dependency Property. Una Dependency Property è esposta a tutti gli effetti come una proprietà di un oggetto, ma il suo valore può dipendere da una sorgente esterna, ad esempio il valore di un oggetto .NET.
Grazie a questa caratteristica, ad esempio, possiamo "collegare" la proprietà Text
di un controllo TextBlock
al nome di un oggetto.
Facciamo un esempio più concreto per fissare il concetto e verificarne l'applicabilità. Creiamo una classe che utilizzeremo, una volta instanziata, come sorgente dati e che metteremo in Data Binding con con la nostra UI.
La classe potrebbe descrivere un Cliente
ed esporre delle semplici proprietà come il Nome
e una proprietà IsValid
, di tipo boolean
.
La classe Cliente
public class Cliente { public String Nome { get; set; } public bool IsValid { get; set; } }
Nella nostra UI abbiamo inserito un controllo TextBlock
e un controllo Checkbox
che ospiteranno relativamente i due valori di un'istanza della classe Cliente
.
<TextBlock Text="{Binding Nome}" /> <CheckBox IsChecked="{Binding IsValid}" />
Facciamo attenzione alla sintassi utilizzata per il binding. Si tratta di quella definita tramite le XAML Markup Extension, delimitate tramite le parentesi graffe.
Nell'esempio Nome
e IsValid
, espresse in Binding
nel codice XAML, sono predisposte per rappresentare le proprietà Nome
e IsValid
del nostro oggetto Cliente
. Rimane a questo punto da capire come collegare un'istanza della classe Cliente
ai controlli della UI.
Andiamo nel file di code-behind. Nel costruttore della classe Page
, possiamo scrivere il codice in questione, dopo il metodo InitializeComponent()
:
public Page()
{
InitializeComponent();
Cliente cl = new Cliente() { Nome = "Pietro", IsValid = true };
LayoutRoot.DataContext = cl;
}
Importante è notare la proprietà DataContext
. Questa proprietà ci permette di impostare la sorgente dati. Ma dove è impostata? Nell'esempio è impostata sull'elemento contenitore che di default si chiama LayoutRoot
.
Facciamo caso ad una particolarità: impostando a livello di elemento contenitore la proprietà DataContext
, questa viene "ereditata" anche dai controlli contenuti e quindi anche dal nostro TextBlock
e dal Checkbox
. In alternativa avremmo potuto impostare la proprietà DataContext
sui singoli controlli.
Modalità di Binding
Tra le opzioni per il Data Binding possiamo specificare anche la modalità di collegamento tra Target e Sorgente, come specificato nel seguito:
- OneTime: il target viene aggiornato con la sorgente al momento in cui viene impostato il binding
- OneWay: come OneTime, ma in più il target viene aggiornato per ogni aggiornamento della sorgente
- TwoWay: c'è aggiornamento in entrambe le direzione, anche quando modifichiamo la UI, cioè il target ed in questo caso viene modificata anche la sorgente
Il Data Binding in Silverlight è un meccanismo molto potente è flessibile. Un'altra caratteristica di interesse riguarda la possibilità di auto aggiornamento, cioè è possibile fare in modo che la UI venga aggiornata automaticamente (cioè senza scrivere del codice ad-hoc). Per far questo le sorgenti dati devono implementare le interfacce INotifyPropertyChanged
e per le collezioni INotifyCollectionChanged
.
Networking
In Silverlight 1.0 non esiste un supporto diretto per effettuare chiamate verso servizi esterni; nei casi in cui è necessario è possibile utilizzare chiamate da librerie JavaScript per applicazioni AJAX, come ad esempio le Microsoft AJAX Library. Silverlight 2 offre invece uno stack completo per le funzionalità di Networking.
Con Silverlight 2 possiamo effettuare chiamate HTTP e HTTPS verso servizi SOAP, oppure verso servizi REST. Per la chiamata a questo tipo di servizi esistono due API : WebClient
e la coppia HttpRequest
/HttpWebResponse
, queste ultime due offrono un maggior controllo sui parametri per la chiamata rispetto alla prima, a scapito di una minor semplicità di utilizzo.
Un aspetto da tenere presente è che tutte le chiamate verso servizi di qualsiasi tipo avviene in modo asincrono in Silverlight 2. Nell'esempio seguente vedete un semplice esempio di utilizzo di una chiamata HTTP usando la classe WebClient.
Una semplice chiamata ad un URL con WebClient
WebClient proxy = new WebClient(); proxy.OpenReadCompleted += new OpenReadCompletedEventHandler(proxy_OpenReadCompleted); proxy.OpenReadAsync(serviceUri);
Dopo aver instanziato la classe WebClient
abbiamo aggiunto un gestore di eventi all'evento OpenReadCompleted
che sarà scatenato al completamento della chiamata (asincrona) verso l'URL richiesto.
Una volta definita questa funzione di call-back possiamo effettuare una chiamata usando il metodo OpenReadAsync
per un URL specifico, nel codice sopra è definito nel parametro ServiceUri
, un semplice oggetto di tipo Uri
che contiene il riferimento all'URL HTTP.
Per meglio chiarire il pattern da utilizzare per usare questa classe, esaminiamo la funzione di call-back:
void proxy_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) { Stream responseStream = e.Result; ... }
La proprietà e.Result
contiene il risultato della chiamata che in questo caso è uno stream
, poiché il metodo usato inizialmente (OpenReadAsync
) si aspetta uno stream
.
La classe WebClient
permette inoltre di fare il download di stringhe e ha una nuova funzionalità per l'Upload
. È possibile esaminare un elenco completo dei metodi supportati.
Nota: la nuova classe WebClient
, ora più completa, rimpiazza anche la classe Downloader
usata in Silverlight 1.0 .
La chiamata di web service da Silverlight 2
Se vogliamo effettuare una chiamata verso un servizio SOAP da un progetto Silverlight 2, possiamo sfruttare il supporto diretto dell'IDE. Premendo tasto destro sul progetto, quindi "Aggiungi riferimento al servizio", possiamo specificare l'indirizzo di un particolare servizio oppure cercare un servizio direttamente nella vostra soluzione, che in ultima analisi sarà un servizio WCF o ASMX.
Successivamente appare la maschera per cercare il servizio nella soluzione o all'esterno.
l'operazione creerà le opportune classi proxy per la chiamata al servizio. La chiamata da Silverlight è molto semplice ed il codice si presenta come nel seguente snippet:
ServiceReference1.ServiceClient proxy = new SilverlightApplicationWCF.ServiceReference1.ServiceClient(); proxy.DoWorkCompleted += new EventHandler<SilverlightApplicationWCF.ServiceReference1.DoWorkCompletedEventArgs>(proxy_DoWorkCompleted); proxy.DoWorkAsync("Pietro");
In questo caso viene istanziata la classe ServiceClient
che è stata creata da Visual Studio, il pattern di utilizzo è come il precedente, viene definita la funzione di call-back e poi viene invocato in modo asincrono il Web service. In questo caso il nome del metodo da chiamare riprende quello esposto dal WebService, che si chiama DoWork e accetta un parametro di tipo stringa. Il nome del metodo generato nella classe proxy è quindi DoWorkAsync
, che ne identifica chiaramente la modalità asincrona di chiamata.
Chiamate via Socket
Oltre all'utilizzo delle chiamate via HTTP già dalla beta 1 di Silverlight 2 era possibile effettuare chiamate usando i Socket
. Con la beta 1 era possibile però effettuare chiamate solo dal dominio di origine, cioè da quello da cui si scaricava l'applicazione Silverlight.
Con la beta 2 il comportamento è cambiato, sono possibili anche chiamate cross-domain. In ogni caso per effettuare chiamate che usano i Socket è necessario che sia presente un file delle policy (che esaminiamo nel prossimo paragrafo). Per l'utilizzo dei Socket
esiste anche la restrizione che la chiamata deve essere compresa tra porte in un range che va da 4502
a 4534
.
Chiamate Cross-Domain
Con Silverlight 2 sono possibili chiamate verso domini esterni a quelli da cui si scarica l'applicazione Silverlight, rendendo cioè possibili chiamate cross-domain. In questo caso, è necessario che Silverlight 2 trovi un file delle policy.
I file delle policy supportati sono due:
- il file
crossdomain.xml
, il formato definito da Flash, che rende di fatto già utilizzabili da Silverlight 2 tutti quei servizi che già lo espongono, - un nuovo formato di file
clientaccesspolicy.xml
, definito per Silverlight 2 e che viene cercato per primo tra i due file supportati.
Il comportamento di come viene scaricato questo file cambia a seconda che sia stia effettuando una chiamata via HTTP, utilizzando la classe WebClient
, oppure si stiano utilizzando i Socket
. È possibile trovare ulteriori dettagli in merito su MSDN.
Chiamate in push (dal Server verso Silverlight 2)
Una delle novità presenti nella beta 2 è la possibilità per Silverlight 2 di ricevere notifiche delle modifiche fatte su un servizio WCF. Per ora rimandiamo alla documentazione per approfondimenti.
Supporto ai feed (Syndication)
Tra le altre funzionalità per il Networking è da menzionare il supporto ai feed. Silverlight 2 espone un sottoinsieme del modello ad oggetti di WCF per la gestione dei feed RSS, per la parte client. I due scenari tipici di utilizzo con Silverlight 2 sono di deserializzazione dei dati in formato RSS o ATOM, grazie all'uso della classe SyndicationFeed
e al processo inverso di serializzazione dei dati ivi contenuti per il successivo invio via HTTP.
Formato dei dati supportato
Lavorando con chiamate verso servizi esterni i due formati più tipici per i dati restituiti sono XML e JSON. Le classi base di Silverlight 2 consentono di lavorare in modo comodo sia con l'XML, si veda meglio il paragrafo successivo, che con il formato JSON.
A partire dalla beta 2 è possibile utilizzare LINQ to JSON per operazioni su in formato JSON utilizzando una sintassi che ricorda quella usata con l'SQL. A questo link alla documentazione MSDN, potete vedere un semplice esempio di dati in formato JSON e come utilizzare LINQ to JSON per lavorarci.
Supporto per l'XML
Come anticipato nel paragrafo precedente può capitare di effettuare chiamate via HTTP e avere delle risposte che contengono dati in formato XML; oppure può essere necessario creare file in XML, per poi inviarli via HTTP. A fronte di queste necessità il runtime .NET di Silverlight 2 mette a disposizione almeno due tipologie di classi per lavorare con l'XML.
Una prima scelta può ricadere sull'uso delle classi XmlReader
e XmlWriter
:
- la prima permette di leggere dati XML (read-only), in modo diretto, cioè senza poter tornare indietro e senza caching;
- la seconda permette di generare del nuovo contenuto in XML, ad esempio si potrebbe salvare il contenuto nell'Isolated Storage di Silverlight 2 (che introduciamo più avanti).
Un'alternativa è utilizzare le API per LINQ to XML: grazie a queste è possibile effettuare query su dati in formato XML con una sintassi simile a SQL e tramite codice. Inoltre alcune nuove classi ci permettono di costruire una nuova struttura dati in XML.
Nell'esempio seguente utilizziamo la classe XElement
per creare un file XML, che poi viene assegnata alla proprietà Text
di un TextBlock
. Per poter utilizzare la suddetta classe dobbiamo aggiungere un nuovo riferimento all'assembly System.Xml.Linq
e la relativa clausola using
in C#.
using System.Xml.Linq; ... XElement contacts = new XElement("Autori", new XElement("Autore", new XElement("Nome", "Pietro Brambati"), new XElement("Telefono", "000-555-0111"), new XElement("Indirizzo", new XElement("via", "123 via"), new XElement("City", "Milano"), new XElement("codice", "20060") ) ), new XElement("Autore", new XElement("Nome", "Gabriele Castellani"), new XElement("Telefono", "111-555-2222"), new XElement("Indirizzo", new XElement("via", "1234 via"), new XElement("City", "Firenze"), new XElement("codice", "20090") ) ) ); tb1.Text = contacts.ToString();
Il risultato sarà simile al seguente:
Possiamo ora effettuare una query LINQ to XML per selezionare dalla lista di autori quelli che vivono a Milano, che nell'esempio è solo uno; ecco il codice in cui vedete una sintassi che fa uso di From, where e Select, che sono parole chiave del linguaggio C#.
var autoriDiMilano = from a in contacts.Descendants("Autore") where ((string)a.Descendants("City").First()) == "Milano" select (string)a.Element("Nome");
Per maggiori informazioni sulla sintassi di LINQ to XML possiamo rifarci ad un articolo precedente oppure alla documentazione MSDN on-line. LINQ to XML permette quindi di lavorare con dati in XML in memoria, come accade con il Document Object Model (DOM), ma in modo più semplice ed immediato.
Isolated Storage
Silverlight 2 permette di gestire quello che viene chiamato Isolated Storage, cioè uno spazio virtuale su file system, legato al profilo dell'utente e alle applicazioni Web. La quota iniziale è di circa 1MB (nella beta 2), ma è possibile, utilizzando un'opportuna API (TryIncreaseQuotaTo
), aumentare lo spazio a disposizione.
Dalla versione beta 2 è migliorato anche il supporto per l'utente nella gestione del suo storage. Se clicchiamo con il tasto destro nel browser in una zona in cui sta girando un'applicazione Silverlight possiamo accedere alle informazioni sulla configurazione del plug-in.
In particolare appare un nuovo tab "Application Storage", che mostra l'utilizzo dell'Isolated Storage e permette all'utente alcuni interventi.
HTML Bridge: integrazione tra Silverlight 2 e l'HTML
Con Silverlight 2 è possibile non solo scrivere applicazioni usando i linguaggi .NET, ma anche creare un "ponte" tra il mondo .NET che si utilizza all'interno dell'applicazione Silverlight e il DOM della pagina che contiene il plug-in. Il collegamento è bidirezionale: da .NET è possibile chiamare e accedere al DOM della pagina, ad esempio all'elemento Window
, oppure agganciare eventi a elementi della pagina HTML che poi possiamo gestire in codice .NET.
Un esempio molto semplice è il seguente, in cui generiamo un semplice Alert da .NET all'interno dell'applicazione Silverlight. Per eseguire codice è necessario aggiungere una clausola al namespace opportuno:
using System.Windows.Browser; ... HtmlPage.Window.Alert("prova da .NET");
È possibile anche ottenere il processo inverso, cioè chiamare codice .NET da JavaScript: per fare questo occorre per prima cosa applicare l'attributo ScriptableMember
agli oggetti .NET che si vogliono richiamare da JavaScript; è poi necessario andare a registrare la classe come ScriptableObject
sull'evento Application_Startup
nel file App.xaml.cs
. Per avere più chiaro il concetto possiamo esaminare un esempio completo.
DeepZoom
DeepZoom è la tecnologia usata da Silverlight 2 per vedere immagini ad alta risoluzione, oppure collezioni di immagini che possono essere messe insieme al fine di realizzarne una di dimensioni maggiori. L'immagine, che sarà di grosse dimensioni, non viene caricata tutta in una sola volta, cosa che richiederebbe molto tempo e banda occupata, ma ne viene caricata inizialmente solo una parte alla risoluzione richiesta. L'utente, utilizzando il mouse, può "navigare" all'interno dell'immagine, caricandone le parti mancanti che servono per la visualizzazione.
L'immagine deve essere inizialmente processata da DeepZoom Composer, questo tool si occupa di suddividere l'immagine in una serie di tessere che vengono visualizzate a livelli di zoom diversi in base all'interazione che l'utente ha sulla stessa muovendo la rotella del mouse.
Dopo aver installato Deep Zoom Composer, possiamo creare un nuovo progetto dal menu file. La prima fase per realizzare un progetto è la fase di import, in cui possiamo aggiungere o una foto ad alta risoluzione o più foto singole. Nell'immagine seguente troviamo quattro delle mie foto:
La successiva fase di "Compose" prevede di sistemare le foto su una sorta di "lavagna virtuale", come si vede nell'immagine seguente, in cui ho sistemato le quattro foto vicine tra loro:
Possiamo ora eseguire la fase di esportazione, che elabora le foto dividendole in tessere; alla fine otteniamo il risultato in preview nel browser. L'esempio generato da Deep Zoom Composer, contiene anche il codice per la gestione della rotella e il click del mouse per gli eventi di zoom in e zoom out.
Muovendoci con il mouse possiamo zoomare sull'immagine in basso a sinistra per vedere meglio gli animali della foto.
Dynamic Language Runtime (DLR)
Silverlight 2 include oltre il runtime descritto in precedenza per lavorare con i linguaggi .NET (C# e Visual Basic .NET) anche un componente (attualmente una preview) per il supporto a linguaggi dinamici. In particolare il Dynamic Language Runtime (DLR) supporta tre linguaggi: IronPython, IronRuby e Managed JScript.
Conclusione
Silverlight è un argomento molto vasto e in questo articolo abbiamo cercato di farci un'idea il più possibile completa di tutte le funzionalità e degli aspetti che riguardano lo sviluppo. All'inizio abbiamo visto come installare un ambiente di sviluppo e cominciare a programmare con Silverlight 2.
Va menzionato anche il fatto che dalla versione beta 2 di Silverlight 2 è stata rilasciata anche un licenza go live, che abilita all'utilizzo in siti per fini commerciali.
Sul sito MSDN Italia è disponibile un percorso formativo su Silverlight versione 1.0 e 2.