Nel post precedente abbiamo visto che tramite il parametro opzionale initParams è possibile passare alla nostra applicazione dei parametri direttamente dalla pagine web che la ospita.
I parametri saranno delle coppie chiave=valore e saranno separati dalla virgola, una stringa di parametri potrebbe essere la seguente: nomeparametro1=valorepatametro1,nomeparametro2=valoreparametro2
Attualmente non è supportato l’escape dei caratteri speciali, sarà quindi opportuno utilizzare sono caratteri alfanumerici.
Il parametro initParams sarà gestibile ora dalla nostra applicazione web, ma attenzione non sarà leggibile dall’istanza della classe Page della nostra applicazione, ma sarà leggibile dall’istanza della classe App (quella sottolineata in rosso nell’immagine)

Passare poi i parametri letti alla classe Page (che è quella che contiene il codice vero e proprio della nostra applicazione) sarà abbastanza semplice e possimo farlo in tre modi
- modificando la dichiarazione della nostra classe Page facendogli accettare dei parametri nel Costruttore
- aggiungendo un costruttore che accetti i parametri (quindi usando l’overloading)
- aggiungendo un attributo pubblico (o privato ma con un metodo pubblico per poterlo settare)
Nell’esempio seguente utilizzeremo il secondo metodo, vediamo quindi per primo il codice HTML che useremo per richiamare il plugin silverlight e per passare i parametri alla nostra applicazione
1 2 3 4 5 6 7 8 9 10 11 12 13 | <div id="silverlightControlHost"> <object data="data:application/x-silverlight," type="application/x-silverlight-2-b1" width="100%" height="100%"> <param name="source" value="ClientBin/PassaggioParametri.xap"/> <param name="onerror" value="onSilverlightError" /> <param name="background" value="white" /> <param name="initParams" value="nomeParam=ValoreParam" /> <a href="http://go.microsoft.com/fwlink/?LinkID=108182" 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> |
Vediamo ora invece il codice della nostra classe Page, supponiamo che textboxT1 sia un controllo textBox
1 2 3 4 5 6 7 8 9 10 11 12 13 | public partial class Page : UserControl { public Page() { InitializeComponent(); } public Page(string valoreParametro) { InitializeComponent(); textboxT1.Text = valoreParametro; } } |
Infine per leggere correttamente i parametri passati dall’HTML modifichiamo il metodo Application_Startup della nosta classe App nel seguente modo
1 2 3 4 5 6 | private void Application_Startup(object sender, StartupEventArgs e) { string nomeParam = e.InitParams["nomeParam"]; Page pagina = new Page(nomeParam); this.RootVisual = pagina; } |
Quando il nostro esempio verrà eseguito il testo del nostro controllo textboxT1 sarà uguale a “ValoreParam”.
Le applicazioni silverlight vengono facilmente integrate nelle pagine Web, più o meno come succede per quelle sviluppate in Flash. In questo post descriveremo come integrare nelle pagine web le applicazioni silverlight 2.0
Il tag HTML da utilizzare è il tag <object>, vediamo come utilizzarlo e quali sono i parametri che dobbiamo utilizzare, alcuni dei quali obbligatori, altri opzionali ed infine alcuni completamente personalizzabili (per passare dei parametri all’applicazione per esempio). Oltre al tag object è necessario anche l’utilizzo di un <iframe>.
Vediamo un esempio:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <script type="text/javascript"> function onSilverlightError(sender, args) { if (args.errorType == "InitializeError") { var errorDiv = document.getElementById("errorLocation"); if (errorDiv != null) errorDiv.innerHTML = args.errorType + "- " + args.errorMessage; } } function onResizeHandler(sender, args) { } </script> <div id='errorLocation' style="font-size: small;color: Gray;"></div> <div id="silverlightControlHost"> <object data="data:application/x-silverlight," type="application/x-silverlight-2-b1" width="100%" height="100%"> <param name="source" value="ClientBin/PassaggioParametri.xap"/> <param name="onerror" value="onSilverlightError" /> <param name="onResize" value="onResizeHandler" /> <param name="background" value="white" /> <param name="initParams" value="nomeParam=ValoreParam,nomeParam2=ValoreParam2" /> <a href="http://go.microsoft.com/fwlink/?LinkID=108182" 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> |
Per una corretta dichiarazione dobbiamo inserire nel tag object alcuni attributi e quest’ultimo dovrà contenere delle proprietà, vediamoli nel dettaglio.
Attributi obbligatori
- id
è il classico tag HTML che specifica un identificativo univoco per l’istanza del tag object all’interno del Dom HTML. Quindi qui si può specificare un identificativo alfanumerico a nostra scelta, l’importante è che sia univoco nella pagina. - data
qui viene specificato l’application mime type silverlight, che è data:application/x-silverlight, - type
questo identifica la versione di silverlight che stiamo utilizzando, la si specifica sempre tramite un mime type. Nel caso del nostro esempio sarà application/x-silverlight-2-b1 - height
specifica l’altezza del nostro applicativo, può essere specificata in due modi. Il primo modo è assoluto in pixel, cioè specificando un numero intero che indica l’altezza in pixel della nostra app. Il secondo metodo è specificando una percentuale, quindi con un intero seguito dal segno %, in questo caso l’altezza del nostro controllo verrà calcolata prendendo una data percentuale dell’elemento che lo contiene (nel nostro esempio del div che contiene il tag object). - widht
stesse considerazioni fatte per l’attributo height, quindi possiamo specificare un intero per indicare l’altezza in pixel o un intero seguito da % per indicare l’altezza in percentuale rispetto al suo contenitore.
Parametri obbligatori
- source
questo parametro contiene l’url dove risiede all’applicazione, questo segue le regole dell’html per la specifica degli url, può essere quindi relativo (come nel nostro esempio) o assoluto, cioè specificando tutto il percorso partendo dal dominio
Eventi obbligatori
silverlight permette di gestire alcuni eventi che può lanciare il plugin, questi ultimi vengono gestiti tramite funzioni javascript.
- onError
questo evento viene lanciato in caso di errore sollevato dal plugin o dal codice utente. - onResize
viene lanciato quando le propietà ActualHeight o ActualWidth cambiano, cioè quando viene ridimensionata la nostra applicazione.
Parametri opzionali
- background
specifica il colore in formato ARGB (la A sta per alpha) con cui viene riempita l’area che conterrà il plugin silverlight. Il valore di default è #FFFFFFFF che corrisponde al bianco. - enableHtmlAccess
è un campo booleano, quindi può assumere il valore true o false e permette (se true) al plugin di accedere al DOM HTML, cioè di poter modificare dinamicamente la struttura della pagina HTML. Questa feature può passare in secondo piano ma è forse una delle caratteristiche più importanti del silverlight. - initParams
permette di specificare dei parametri di inizializzazione per la nostra applicazione, vedremo questa feature nel dettaglio nel prossimo post. - splashScreenSource
tramite un url si può indicare uno XAML che viene visualizzato durante il caricamento della nostra applicazione (si può quindi creare un loader personalizzato). - maxFramerate
valore intero che specifica il massimo framerate che la nostra applicazione può ragiungere, di default è 60.Da sottolineare che è indicato il valore massimo, il valore minimo invece dipende dalla potenza del computer che sta visualizzando la pagina. - windowless
valore booleano che attiva (se true) la modalità windowless, cioè rendendo trasparenti le aree del plugin che non sono opache. NB in ambiente mac il plugin è sempre in modalità windowless e questo parametro viene ignorato.
Eventi opzionali
oltre ai due eventi visti sopra, silverlight ne espone altri tre sempre gestibili via javascript ma non obbligatori.
- onLoad
viene invocato una volta che la nostra applicazione è stata caricata dal plugin. Viene lanciata prima che il contenuto della nostra applicazione venga visualizzato all’utente. - onSourceDownloadComplete
viene invocata quando il plugin ha terminato di scaricare la nostra applicazione (questo evento viene invocato prima del precedente onLoad). - onSourceDownloadProgressChanged
viene invocata ogni qual volta varia la porzione di applicazione scaricata dal plugin, questo metodo è quello utilizzato per realizzare i loader personlalizzati.
Parametri opzionali di Debug
i seguenti parametri ci se specificati forniscono dei dati utili per monitorare le nostre applicazioni in fase di sviluppo.
- enableRedrawRegions
un booleano che se abilitato (quindi true) evidenzia sulla nostra applicazione le aree che sono soggette a redraw (in genere cerchiamo di identificarle per ottimizzare le performance in applicazioni che fanno uso di animazioni) - enableFramerateCounter
anche questo booleano, se true visualizza nella barra di stato il numero di frame al secondo che la nostra applicazione sta correntemente visualizzando. Funziona solo su Internet Explorer.
Infine abbiamo la parte del codice che permette di personalizzare l’installazione del plugin. Specificando infatti la parte:
<a href=”http://go.microsoft.com/fwlink/?LinkID=108182″ style=”text-decoration: none;”>
<img src=”http://go.microsoft.com/fwlink/?LinkId=108181″ alt=”Get Microsoft Silverlight” style=”border-style: none”/>
</a>
Facciamo in modo che se un utente non ha il plugin silverlight installato facciamo apparire un immagine (specificata nell’attributo src del tag IMG) che linka alla pagina (specificata dall’attributo href del tag A) dove è possibile scaricare il plugin ed installarlo.
Nei prossimi post vedremo nel dettaglio alcuni concetti che qui abbiamo solo accennato (passaggio di parametri alla nostra applicazione, creazione di un loader personalizzato etc.etc.) in quanto abbiamo preferito dare qui più una visione di insieme dei parametri e degli attributi che possono essere specificati quando inseriamo un’applicazione silverlight nelle nostre pagine web.
Molti di voi ormai avranno già notato che il linguaggio XAML ha molti punti in comune con il linguaggio HTML. Entrambi possono essere definiti linguaggi di Markup descrittivi. Un ulteriore punto in comune tra i due linguaggi sono gli stili. Uno Style raggruppa un insieme di proprietà attribuendogli dei valori al fine di poterli condividere con uno o più elementi.
Nel seguente esempio vediamo dei bottoni definiti all’interno di un Canvas, ognuno dei quali con le stesse caratteristiche degli altri.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <Canvas Width="825" Height="645" Background="#FF000000"> <Button Height="50" Width="100" Content="bottone 1" FontSize="15" Canvas.Top="271" Canvas.Left="322" Background="red" Foreground="green" RenderTransformOrigin="0.5,0.5"> <Button.RenderTransform> <RotateTransform Angle="-30"/> </Button.RenderTransform> </Button> <Button Height="50" Width="100" Content="bottone 2" FontSize="15" Canvas.Top="271" Canvas.Left="442" Background="red" Foreground="green" RenderTransformOrigin="0.5,0.5"> <Button.RenderTransform> <RotateTransform Angle="-30"/> </Button.RenderTransform> </Button> <Button Height="50" Width="100" Content="bottone 3" FontSize="15" Canvas.Top="271" Canvas.Left="562" Background="red" Foreground="green" RenderTransformOrigin="0.5,0.5"> <Button.RenderTransform> <RotateTransform Angle="-30"/> </Button.RenderTransform> </Button> </Canvas> |
produce

Proviamo a definire uno Style per raggruppare le caratteristiche comuni di questi bottoni. Questo ci porterà 2 vantaggi. Il primo sarà quello di definire le caratteristiche comuni dei bottoni una sola volta, senza quindi doverle riscrivere per ogni bottone. Il secondo vantaggio sarà che quando dovremo modificare le caratteristice dei nostri bottoni basterà modificarle in quell’unico punto dove sono definite, lo Style appunto.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <Canvas Width="825" Height="645" Background="#FF000000"> <Canvas.Resources> <Style x:Key="mioStile"> <Setter Property="Button.Height" Value="50" /> <Setter Property="Button.Width" Value="100" /> <Setter Property="Button.FontSize" Value="15" /> <Setter Property="Button.Background" Value="red" /> <Setter Property="Button.Foreground" Value="green" /> <Setter Property="Button.RenderTransform"> <Setter.Value> <RotateTransform Angle="-30"/> </Setter.Value> </Setter> </Style> </Canvas.Resources> <Button Style="{StaticResource mioStile}" Canvas.Top="271" Canvas.Left="322" Content="Bottone1" /> <Button Style="{StaticResource mioStile}" Canvas.Top="271" Canvas.Left="442" Content="Bottone2" /> <Button Style="{StaticResource mioStile}" Canvas.Top="271" Canvas.Left="562" Content="Bottone3" /> </Canvas> |
produce lo stesso risultato

Gli stili non devono necessariamente essere associati ad un determinato tipo di controllo. nell’esempio precedente abbiamo visto che i setter vanno ad agire sulle proprietà del controllo Button, ma noi possiamo benissimo essere più generici nel definire lo Style. Nel seguente esempio infatti definiamo uno stile che va a definire le proprietà per un generico controllo e poi istanziamo diversi controlli associandogli lo stile definito.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <Canvas Width="825" Height="645" Background="#FF000000"> <Canvas.Resources> <Style x:Key="mioControlStile"> <Setter Property="Control.Height" Value="50" /> <Setter Property="Control.Width" Value="100" /> <Setter Property="Control.Opacity" Value="1" /> <Setter Property="Control.RenderTransform"> <Setter.Value> <RotateTransform Angle="-30"/> </Setter.Value> </Setter> </Style> </Canvas.Resources> <Button Style="{StaticResource mioControlStile}" Content="Bottone1" Canvas.Top="271" Canvas.Left="322" /> <TextBox Style="{StaticResource mioControlStile}" Text="TextBox" Canvas.Top="271" Canvas.Left="442"/> <CheckBox Style="{StaticResource mioControlStile}" Content="CheckBox" Foreground="white" Canvas.Top="271" Canvas.Left="562"/> </Canvas> |
produce

Gli stili nello XAML sono quello che potrebbero essere i CSS per il linguaggio HTML, ci permettono quindi di separare la struttura della nostra applicazione dalla sua rappresentazione visiva.
Silverlight nativamente supporta la grafica vettoriale, gli oggetti base che fanno capo al Namespace degli Shapes sono i seguenti:
- Ellipse
è una figura geometrica che rappresenta come dice il nome stesso un ellisse, in caso di stessa altezza e larghezza si ha un cerchio. E’ una figura chiusa, quindi possiede la propietà Fill che permette i specificare un riempimento (Brush) che può essere un gradiente, un colore o anche un ImageBrush (questi ultimi li abbiamo incontrati alla fine del post sulle immagini). Ha anche due propietà che sono comuni a tutti gli oggetti Shapes e sono Stroke e StrokeTickness, con la prima si può specificare il Brush con cui viene colorato il bordo del segmento che traccia la figura, la seconda invece ne indica lo spessore.
Vediamo un esempio con un Ellipse in cui la proprietà Fill contiene un ImageBrush1 2 3 4 5 6 7
<canvas width="333" height="266" background="#FF000000"> <ellipse height="91" width="137" canvas.left="132" canvas.top="117" stroke="#FFFF1F1F" strokethickness="7"> <ellipse.fill> <imagebrush imagesource="SilverLightLogo.png" stretch="Fill"></imagebrush> </ellipse.fill> </ellipse> </canvas>
produce

- Rectangle
un rettangolo, oltre allestesse propietà dell’Ellipse ha anche due propietà particolari: RadiusX e RadiusY, che identificano rispettivamente la larghezza e l’altezza dell’ellisse che disegna gli angoli, in modo da poter avere degli angoli smussati invece che vivi.
Vediamo un esempio di un Rectangle con le proprietà radius definite e con un ImageBrush in Fill1 2 3 4 5 6 7
<canvas width="333" height="266" background="#FF000000"> <rectangle height="54" width="106" canvas.left="46" canvas.top="22" stroke="#FF00FF1E" strokethickness="4" radiusx="5" radiusy="5"> <rectangle.fill> <imagebrush imagesource="SilverLightLogo.png" stretch="Fill"></imagebrush> </rectangle.fill> </rectangle> </canvas>
Produce

- Line
una semplice linea, definita tramite un punto di inizio (x,y) ed un punto di fine. Uniche proprietà sono Stroke e StrokeTickness.
Esempio1 2 3
<canvas width="333" height="266" background="#FF000000"> <line x1="100" y1="10" x2="10" y2="100" canvas.left="194" canvas.top="25" stroke="#FFFFF500" strokethickness="3"></line> </canvas>
produce

- Polygon
una figura chiusa con un determinato numero di lati, può essere quindi un pentagono, un esagono, un ottagono e così via. Ha le stesse proprietà dell’Ellipse.
Vediamo un esempio di un Polygon con soli tre lati1 2 3
<canvas width="333" height="266" background="#FF000000"> <polygon points="30,30 0,60 60,60" stroke="#FFFF0000" strokethickness="5" fill="#FFFDFF00" canvas.top="146" canvas.left="226"></polygon> </canvas>
produce

- Polyline
questo oggetto è simile a Polygon ma non necessariamente deve essere una figura chiua. Si può ottenere lo stesso risultato anche mettendo insieme delle Line.
In questo esempio vediamo che nonostante la Polyline non è una figura chiusa è possibile specificare comunque la propietà Fill1 2 3
<canvas width="333" height="266" background="#FF000000"> <polyline points="60,180 120,160 180,180 130,130" stroke="#FF0015FF" strokethickness="4" canvas.top="-42" canvas.left="125" fill="#FFD81919"></polyline> </canvas>
produce

- Path
questo oggetto definisce linee e figure complesse che possono essere composte da curve, archi e linee rette. Il Path possiede anche la proprietà Fill, quindi può essere riempito da un Brush.
Anche in questo esempio pur non essendo una figura chiusa abbiamo specificato la proprietà Fill1 2 3
<canvas width="333" height="266" background="#FF000000"> <path height="71.965" width="114" canvas.left="189" canvas.top="111.291" fill="#FF00A5A4" stretch="Fill" stroke="#FFF900FF" strokethickness="4" data="M226,158 C235,168 213,188 251,175 C289,162 274,152.99991 259,146.9998 C244,140.99969 289.99979,130.99953 299.99976,151.99989"></path> </canvas>
produce

Silverlight supporta due tipi di immagini, JPEG e PNG (anche con trasparenza). Le immagini possono essere visualizzate in vari modi, quello più diretto è l’utilizzo del control Image.
Guardiamo un esempio:
<Image Source=”silverlightlogo.jpg”>
il controllo in questo caso visualizza l’immagine nelle sue dimensioni originali (senza resize di nessun tipo) dato che non sono stati specificati i parametri Height e Width
img
Da sottolineare il fatto che i parametri Height e Width non si riferiscono strettamente alle dimensioni dell’immagine, ma piuttosto definiscono le dimensioni del rettangolo che conterrà l’immagine. L’immagine verrà poi disegnata all’interno di questo rettangolo seguendo la direttiva che viene specificata dal parametro Stretch (di default Stretch è impostato a None).
Il parametro Stretch può assumere i seguenti valori:
- None
in questo caso l’immagine mantiene le sue dimensioni reali - Fill
l’immagine viene ridimensionata (senza mantenerne le proporzioni) per riempire tutto il rettangolo che contiene l’immagine - Uniform
l’immagine viene ridimensionata per riempire la maggior superficie possibile del rettangolo che la contiene mantenendo le proporzioni. - UniformToFill
l’immagine viene ridimensionata per riempire tutto il rettangolo che la contiene ma vengono mantenute le proporzioni tagliando l’immagine per farla rientrare nel rettangolo che la contiene
Vediamo degli esempi:
Stretch=None
1 2 3 | <canvas height="120" background="#FF000000" width="200"> <img source="SilverLightLogo.png" stretch="None" canvas.left="17.904" canvas.top="13.207" height="96" width="170" /> </canvas> |
Produce il seguente effetto

Stretch=Fill
1 2 3 | <canvas height="120" background="#FF000000" width="200"> <img source="SilverLightLogo.png" stretch="Fill" canvas.left="17.904" canvas.top="13.207" height="96" width="170" /> </canvas> |
Produce il seguente effetto

Stretch=Uniform
1 2 3 | <canvas height="120" background="#FF000000" width="200"> <img source="SilverLightLogo.png" stretch="Uniform" canvas.left="17.904" canvas.top="13.207" height="96" width="170" /> </canvas> |
Produce il seguente effetto

Stretch=UniformToFill
1 2 3 | <canvas height="120" background="#FF000000" width="200"> <img source="SilverLightLogo.png" stretch="UniformToFill" canvas.left="17.904" canvas.top="13.207" height="96" width="170" /> </canvas> |
Produce il seguente effetto

Un’altro modo per visualizzare le immagini è di definirle come ImageBrush, per riempire delle figure (Rectangle, Ellipse etc.etc.). Gli ImageBrush, come gli Image, hanno una propietà che permette di definire come l’immagine deve riempire la figura geometrica. Questa propietà si chiama Stretch.
Vediamo un esempio
1 2 3 4 5 6 7 | <canvas height="120" background="#FF000000" width="200"> <rectangle stroke="Black" strokethickness="1" canvas.left="11" canvas.top="8" height="97" width="173"> <rectangle.fill> <imagebrush imagesource="SilverLightLogo.png" stretch="Fill"></imagebrush> </rectangle.fill> </rectangle> </canvas> |
Produce il seguente effetto

Agendo sul parametro Stretch dell’ImageBrush si posso avere gli effetti elencati sopra.
I layout controls in Silverlight sono principalmente dei contenitori. In base al tipo di contenitore si avranno alcune proprietà che ci permettono di posizionare vari oggetti nello spazio a disposizione.
I layout controls sono in tutto 5, li descriveremo partendo da quelli più semplici.
- Canvas
E’ il contenitore più semplice fra tutti, permette di posizionare oggetti (altri controlli) al suo interno in modo assoluto, specificando le coordinate Top e Left dell’angolo superiore sinitro di questi ultimi, nella figura seguente abbiamo un rettangolo blu dentro un canvas posizionato con Left 100 e top 80, naturalmente l’angolo superiore sinistro del canvas ha coordinate 0,0:

Tradotto in Xaml quanto sopra:1 2 3 4
<canvas> <rectangle height="49" width="100" fill="#FF4883B5" stroke="#FF000000" canvas.top="80" canvas.left="100"> </rectangle> </canvas>
I Canvas possono contenere al loro interno un numero indefinito di oggetti.
Infine il Canvas non permette il ridimensionamento del contenuto al suo interno, ma per ovviare a questo problema basta racchiudere il Canvas in un contenitore che permetta il ridimensionamento. - Border
Il Border è categorizzato come Layout Control anche se non lo è nel senso stretto del termine. Esso infatti non può essere utilizzato per posizionare oggetti nello spazio, dato che può contenere solo un oggetto al suo interno. Diciamo che viene utilizzato, come suggerisce il nome stesso, per fare da bordo-cornice per un altro controllo contenuto al suo interno. - StackPanel
Lo StackPanel è un contenitore che dispone i controlli figli uno sotto l’altro (se l’orientazione è impostata come verticale):1 2 3 4 5 6
<stackpanel height="178" width="141" orientation="Vertical"> <button content="Button"></button> <button content="Button"></button> <button content="Button"></button> <button content="Button"></button> </stackpanel>
genera:

oppure uno di fianco all’altro (se l’orientazione è impostata come orizzontale):1 2 3 4 5 6
<stackpanel height="178" width="141" orientation="Horizontal"> <button content="Button"></button> <button content="Button"></button> <button content="Button"></button> <button content="Button"></button> </stackpanel>
genera invece:

- ScrollViewer
Lo ScrollViewer permette al contenuto di essere più grande del contenitore, e il contenuto può essere visualizzato agendo sulle barre di scrolling (verticale ed orizzontale). Il seguente codice:1 2 3 4 5 6 7 8
<scrollviewer height="100" width="100" horizontalscrollbarvisibility="Auto" verticalscrollbarvisibility="Auto"> <stackpanel height="178" width="141" orientation="Horizontal"> <button content="Button"></button> <button content="Button"></button> <button content="Button"></button> <button content="Button"></button> </stackpanel> </scrollviewer>
Produce:

Come il Border anche lo ScrollViewer può contenere soltanto un oggetto. - Grid
Il Layout Control Grid è quello più complesso, permette di dividere l’area a disposizione in righe e colonne. La grandezza (intesa come larghezza o altezza) delle righe e delle colonne può essere definita in tre modi diversi:- Auto, in questo modo l’altezza/larghezza della riga o della colonna viene automaticamente ricavata dal controllo contenuto al suo interno.
- inPixel, specificando numericamente la dimensione in pixel.
- *, specificando asterisco seguito da un numero si utilizza proporzionalmente lo spazio a disposizione.
Descriviamo come la dimensione delle righe per esempio possa essere definita in modo proporzionale.
Il seguente XAML definisce una griglia con 3 righe, dove la prima riga ha altezza 1* che significa una quantità unitaria dello spazio a disposizione. La riga 2 invece ha un’altezza pari a 2* che indica due volte lo spazio a disposizione. Infine la terza riga ha un altezza pari a 3* che indica 3 volte lo spazio a disposizione. Quando viene disegnata la Grid, la sua altezza viene divisa in modo proporzionale sulle sue righe, e quindi la seconda riga sarà alta il doppio della prima, e la terza il triplo della prima:1 2 3 4 5 6 7 8 9 10
<grid> <grid.rowdefinitions> <rowdefinition height="1*"> <rowdefinition height="2*"> <rowdefinition height="3*"> </grid.rowdefinitions> <button horizontalalignment="Left" margin="0,0,0,0" width="Auto" grid.rowspan="1" content="Button" grid.row="0"></button> <button horizontalalignment="Left" margin="0,0,0,0" width="Auto" grid.rowspan="1" content="Button" grid.row="1"></button> <button horizontalalignment="Left" margin="0,0,0,0" width="Auto" grid.rowspan="2" content="Button" grid.row="2"></button> </grid>
produce:

Ridimensionando una grid il contenuto al suo interno viene automaticamente ridisposto per adattarsi alle nuove dimensioni.
In questo post sono stati descritti gli aspetti principali dei Layout Controls, ognuno di essi ha molte proprietà che ne caratterizzano la visualizzazione finale o gli effetti sugli oggetti che contengono.
Uno dei punti di forza del Silverlight è quello di rendere l’accesso e la lettura di servizi web molto facilitato. Possiamo per esempio accedere e leggere con facilità Web Services o file XML. Ma vi sono delle problematiche da tenere presente per evitare di impazzire quando un applicativo deve essere spostato dall’ambiente di sviluppo all’ambiente di produzione.
Supponiamo di avere un nostro sito web con un suo dominio ben definito (www.silverlight-blog.it). Su questo sito carichiamo una applicazione in Silverlight che tramite una semplice chiamata http legge gli RSS della prima pagina de IlSole24Ore.com (http://www.ilsole24ore.com/rss/primapagina.xml) per poi visualizzarli.
Il codice che si occupa di questo è il seguente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public partial class Page : UserControl { WebClient rssReadService; public Page() { InitializeComponent(); rssReadService = new WebClient(); rssReadService.DownloadStringCompleted += new DownloadStringCompletedEventHandler(rssReadService_DownloadStringCompleted); ssReadService.DownloadStringAsync(new Uri("http://www.ilsole24ore.com/rss/primapagina.xml")); } void rssReadService_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { if (e.Error == null) { XDocument xmlDoc = XDocument.Parse(e.Result); // Di seguito il codice per gestire il documento XML e visualizzarlo } } } |
Facendo partire il debug dell’applicazione e analizzando tramite uno sniffer HTTP le chiamate che vengono effettuare al dominio remoto (ilsole240re.com) vediamo che avvengono in questo ordine:
- Il primo url ad essere richiesto da Silverlight è http://www.ilsole24ore.com/clientaccesspolicy.xml
Se il file clientaccesspolicy.xml viene trovato ne viene analizzato il contenuto ed in base a quest’ultimo si procede alla chiamata 3 - Se il primo url non restituisce il file richiesto allora viene effettuata una seconda richiesta:
http://www.ilsole24ore.com/crossdomain.xml
Se il file crossdomain.xml esiste quest’ultimo viene analizzato per verificare se è possibile effettuare la richiesta 3 - Questa è la richiesta effettiva che abbiamo impostato noi nel codice
http://www.ilsole24ore.com/rss/primapagina.xml
tramite la quale possiamo leggere i feed rss della prima pagina del sole24ore.
Perchè invece di aprire direttamente l’url al punto 3 vengono effettuate le chiamate precedenti??
La risposta è abbastanza semplice e questa problematica viene definita come Cross Domain Policy.
Quando il proprietario di un sito web espone un servizio tramite il protocollo HTTP (che può essere unWebService, un RSS, un semplice file XML etc.etc.) può decidere se quest’ultimo può essere letto anche da applicazioni web (caso di Silverlight e di Flash) che risiedono su un dominio diverso da quello dove il servizio stesso è pubblicato. Quindi se chi espone il servizio non concede esplicitamente il permesso quest’ultimo è negato per default.
Il modo per permettere alle applicazioni web di accedere ai servizi è quello di utilizzare i file cross domain (introdotti da Flash) oppure i file clientaccesspolicy.xm (introdotti da Silverlight).
I file sopra descritti possono dare il permesso di accedere ai servizi esposti in modo molto granulare, specificando ad esempio da quale dominio le applicazioni web possono accedere. Se io creo un file chiamato clientaccesspolicy.xml sul sito www.ilsole24ore.com con questo contenuto:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <access-policy> <cross-domain-access> <policy> <allow-from> <domain uri="pippo.com"> </domain> <grant-to> <resource path="/" include-subpaths="true"> </resource> </grant-to> </allow-from> </policy> </cross-domain-access></access-policy> |
Voglio indicare che tutte le applicazioni Silverlight (o che usano il file clientaccesspolicy per richiedere l’autorizzazione) che risiedono sul dominio pippo.com possono accedere ai servizi presenti sul mio sito (ilsole24ore.com).
Attualmente sul sito del sole24ore è presente questo file crossdomain.xml:
1 2 3 | <cross-domain-policy> <allow-access-from domain="ilsole24ore.com" to-ports="80"></allow-access-from> </cross-domain-policy> |
Che indica che sono autorizzati ad accedere ai servizi esposti dal sito soltanto le web application che risiedono sul dominio ilsole24ore.com (le web app del sole24ore stesso).
Questo file sembrerebbe ridondante dato che le web app che già risiedono sullo stesso dominio in cui viene esposto il servizio possono accedervi, ma in questo caso il file è stato creato per permettere per esempio ad un applicazione flash che risiede su finanza.ilsole24ore.com di poter accedere ad un servizio che risiede si www.ilsole24ore.com
Alla luce di quanto sopra il codice indicato all’inizio dell’articolo, che voleva leggere gli rss, è destinato a sollevare un errore e quindi la nostra condizione:
if (e.Error == null)
Fallisce.
Il comportamento di Silverlight però allo stato attuale differisce da quello di Flash in modo sostanziale. Attualmente Silverlight 2 Beta 1 interroga i files dei permessi cross domain soltanto quando bisogna accedere ad un servizio web (web service, xml, rss etc.etc), invece per quanto riguarda i files multimediali (mp3, jpg, png, wmv…) possono essere liberamente caricati da un dominio diverso da quello su cui gira l’applicazione silverlight.
Quindi se nell’esempio sopra, invece di accedere al file primapagina.xml, avessi cercato di accedere ad un file immagine.jpg o ad un file audio.mp3 non avrei avuto nessun problema.
Creare un progetto Silverlight con VisualStudio 2008
Date: martedì aprile 8, 2008Posted in: Tutorials
Il primo passo per iniziare a sviluppare una applicazione Silverlight è quello di creare un progetto tramite Visual Studio. Praticamente il progetto può essere creato anche direttamente da Blend, ma in questo caso non sarà possibile fare il debug dell’applicazione tramite Visual Studio. Vi sono inoltre degli accorgimenti durante la creazione di quest’ultimo che faciliteranno la gestione del ciclo di vita dell’applicazione.
Vediamo passo passo come procedere :
- Dal Menu di VS selezionare File->New->Project e dalla schermata di creazione del progetto, come in figura, selezionare sotto Project Types: Silverlight e sotto Templates selezionare Silverligh Application.

- Dopo aver premuto OK nella schermata precedente VisualStudio ci chiede dove vogliamo che venga ospitata l’applicazione, le scelte a disposizione sono due. La prima aggiunge alla soluzione che stiamo creando un progetto Web .NET che contiene già le pagine con i tag necessari per richiamare l’applicazione Silverlight. La seconda (questa seconda opzione viene utilizzata implicitamente da Blend quando si crea un nuovo progetto Silverlight) invece aggiunge al progetto Silverlight solo una pagina web HTML che contiene i tag per richiamare l’applicazione Silverlight.
Le due scelte sembrano simili, ma solo con la prima si potrà poi effettuare il debug con VS. Quindi selezioniamo la prima opzione nella seguente schermata.

- Dopo aver premuto OK VisualStudio apre direttamente il progetto appena creato. Nel box del solution explorer vedremo la struttura della nostra solution:

noteremo quindi che la solution contiene 2 progetti. Il primo rappresentato è il progetto web che contiene 3 file (Default.aspx, NomeSoluzioneTestPage.aspx, NomeSoluzioneTestPage.html). La prima è una pagina vuota mentre la seconda e la terza sono due pagine che contengono entrambe i tag (sia in .NET che in semplice HTML) per richiamare la nostra applicazione Silverlight.
Adesso abbiamo creato il nostro progetto. Premendo F5 verrà eseguito correttamente il debug tramite il web server integrato in VisualStudio. Sarà inoltre possibile aprire normalmente la soluzione tramite Blend.
