Principi di programmazione in Silverlight 1.0

di Alessio Leoncini, in Silverlight 1.0,

Realizzare un sito web ricco di animazioni e di interattività è un lavoro molto impegnativo ma altrettanto divertente e di grande soddisfazione, nelle tradizionali pagine web in semplice HTML le azioni dell'utente sono circoscritte alla lettura, alla visione delle immagini ed al click sui vari hyperlink per consultare altre pagine, in un sito web interattivo a queste azioni dell'utente corrispondono una serie di reazioni del sito stesso fino ad arrivare, nei progetti più curati, ad una cosiddetta esperienza multimediale coinvolgente ed emotiva.

Nei siti web interattivi è possibile fondere e gestire più contenuti multimediali come video, audio, immagini ed elementi animati ed anche il semplice testo può essere arricchito di animazioni per migliorare l'attenzione dell'utente ed invogliarlo a rivisitare il sito in futuro.

Concettualmente l'interattività può essere identificabile come la manipolazione nel tempo degli stati degli oggetti multimediali del sito, in funzione come detto delle azioni dell'utente ma anche autonomamente dal sito stesso a seguito del caricamento o di altri eventi preimpostati. Com'è intuibile questo concetto unisce sia i principi di animazione lineare, come un film o un cartone animato, sia la filosofiaipertestuale a cui ci siamo abituati negli anni nei siti web, in cui l'utente può scegliere cosa consultare saltando da un contenuto ad un altro in maniera discontinua rispetto all'eventuale sequenza definita dall'autore.

Tali attività sono possibili attraverso opportuni oggetti grafici che consentono animazioni ma soprattutto attraverso il monitoraggio e la gestione delle azioni dell'utente, intese come le azioni del mouse e gli input da tastiera; Silverlight mette a disposizione molti strumenti per semplificare tale impegno creando ampia libertà di realizzare qualunque idea.

Introduzione alla programmazione

In Silverlight 1.0 la gestione degli stati del plug-in, del codice XAML e delle azioni dell'utente è possibile attraverso il linguaggio di programmazione Javascript.

Javascript è il collaudato linguaggio di scripting utilizzato correntemente per aggiungere funzionalità alle pagine web in HTML; come linguaggio di scripting non è necessaria la compilazione del codice sorgente e può essere inserito direttamente nell'HTML della pagina scrivendolo all'interno del tag:

<script type="text/javascript">alert("Hello World Silverlight!");</script>

oppure riferendosi al codice di una libreria esterna attraverso la proprietà src:
<script type="text/javascript" src="../Silverlight.js"></script>

Il codice Javascript viene interpretato direttamente dal browser ed è proprio per questa caratteristica che consente la manipolazione dell'HTML e dello XAML in tempo reale rispetto alle azioni dell'utente, senza la necessità di ricaricamenti di pagina o elaborazioni da parte del web server.

Nel Javascript di una pagina web, la gestione del codice XAML è possibile attraverso l'accesso allo specifico Object Model esposto dal plug-in; in maniera molto simile al DOM di una pagina HTML, in Silverlight è possibile recuperare il riferimento agli oggetti dichiarati nello XAML ed ai loro rispettivi eventi, con il riferimento di un oggetto è possibile variarne le caratteristiche o aggiungere dinamicamente altri oggetti.

La programmazione in Javascript nasconde alcune insidie proprie della sua semplicità: non è type safe, le variabili dichiarate possono contenere nel ciclo di vita del codice oggetti di diverso tipo e non è case sensitive, ed anche se si possono adottare alcuni stratagemmi, non sono supportate tutte le specifiche del paradigma del linguaggio ad oggetti.

I programmatori Javascript troveranno grande facilità nello sviluppo con Silverlight, per gli altri Microsoft ha introdotto in Visual Studio 2008 e in Visual Web Developer una base di intellisense e di debugger, funzioni molto utili per velocizzare la scrittura e la verifica del funzionamento del codice.

Logica eventi / gestori, eventi del plugin

A seguito della creazione di un progetto web in Silverlight sulla base del template disponibile con l'SDK si può notare che il progetto stesso è ben strutturato alla gestione degli stati del plug-in attraverso Javascript, le stesse funzioni helper di creazione dell'istanza del plug-in, Silverlight.createObject e Silverlight.createObjectEx, sono scritte in Javascript ed espongono la gestione dei due eventi principali nelciclo di vita del plug-in: onError e onLoad.

L'evento onError è scatenato qualora si verifichi un'eccezione nel parsing dello XAML o un errore nel codice Javascript; usando le suddette funzioni helper si ha automaticamente a disposizione un gestore di tale evento che lancia deglialert con una buona descrizione della posizione del codice che ha generato l'errore. Dato l'impatto che ha un messaggio di alert per l'utente, è possibile inserire una propria implementazione del gestore dell'evento qualora si voglia renderizzare le eccezioni in modi diversi, meno invasivi per l'utente e più integrati nell'interfaccia del sito.

L'evento onLoad si genera alla fine del caricamento e del parsing di tutti gli oggetti XAML inseriti nell'istanza del plug-in, a seguito dell'evento onLoad, che corrisponde alla completa inizializzazione di tutti gli oggetti, è possibile accedere ad alcune proprietà e gestire ulteriori eventi che possono essere generati dal plug-in stesso:

<script type="text/javascript">
    function createSilverlight()
    {  
        Silverlight.createObjectEx({
        source: '#Scene1xaml',         

        parentElement:parentElement,   

        id:'myPlugin',                 

        properties:{                   

            width:'100%',              

            height:'100%',              

            inplaceInstallPrompt:false,

            background:'white',        

            isWindowless:'false',      

            framerate:'24',            

            version:'1.0'},            

        events:{
            onError:null,              

            onLoad:Plugin_onLoad
            },              

        initParams:"plugin #Scene1xaml",               

        context:"contesto del plugin"});                            

    }
    
    function Plugin_onLoad(plugIn, userContext, rootElement)
    {
        plugIn.settings.EnableFramerateCounter 
= true;
        plugIn.settings.BackGround = "Black";
        
        alert(plugIn.isVersionSupported("1.0"));
        alert(plugIn.Source);
        
        alert(plugIn.initParams);
        alert(userContext);
        alert("Dimensioni dell'istanza del plugin 
(WxH): " + plugIn.content.ActualWidth + "x" + plugIn.content.ActualHeight);

        plugIn.content.OnResize = function()
        {
            alert("Dimensioni 
dell'istanza del plugin (WxH): " + plugIn.content.ActualWidth + "x" + plugIn.content.ActualHeight);
            
            plugIn.content.Root["Canvas.Left"] 
= (plugIn.content.ActualWidth - plugIn.content.Root.Width)/2;
            plugIn.content.Root["Canvas.Top"] 
= (plugIn.content.ActualHeight - plugIn.content.Root.Height)/2;
            
        };
    }
</script> 

Nel codice del precedente esempio l'evento onLoad è gestito attraverso la funzione Plugin_onLoad, questo evento contiene tre parametri plugIn, userContext, rootElement riferiti rispettivamente all'istanza del plug-in e al valore di context inserito nella funzione di creazione ed al primo elemento, il Canvas, della gerarchia dello XAML.

Attraverso il parametro plugin è possibile accedere a due proprietà:settings e content, con settings si gestiscono alcune delle caratteristiche del plug-in impostate nella funzione createObjectEx; tra le più utili c'è sicuramente EnableFramerateCounter che consente la visione nella barra di stato di Internet Explorer dei frame per secondo con i quali vengono renderizzate a video le animazioni della scena, può essere molto utile per confrontare le prestazioni di diversi PC rispetto al valore di framerate impostato nella funzione.

La proprietà content corrisponde al codice XAML della scena ed oltre a dare accesso a tutta la gerarchia degli oggetti espone una serie informazioni comeRoot, ActualWidth e ActualHeight che corrispondono rispettivamente all'istanza del primo oggetto della gerarchia dello XAML ed alla larghezza e altezza effettiva del plug-in.

L'oggetto content espone anche alcuni eventi molto utili: OnResize che è generato al ridimensionamento del plug-in e OnFullScreenChange scatenato al passaggio a schermo interno.

Nell'esempio precedente è stata impostata una larghezza ed una altezza del plug-in al 100% in modo che occupi tutto lo spazio disponibile del DIV contenitore; nell'eventoonLoad è stato inserito direttamente il gestore dell'evento OnResize ed in esso è stato fatto accesso alla larghezza ed all'altezza effettiva del plug-in per centrare nella pagina l'oggetto principale.

Questo è stato possibile grazie alla modifica delle Attached PropertiesCanvas.Left e Canvas.Top del Canvas corrispondente alla proprietà Root dell'oggetto content :

plugIn.content.Root["Canvas.Top"]

Racchiudendo tra parentesi quadre e tra virgolette il nome dell'Attached Property da gestire è possibile conoscerne e modificarne il valore. A molte delle proprietà degli oggetti si può accedere con la consueta notazione punto:

plugIn.content.Root.Height

Visualizza l'esempio 1

Con la proprietà content e l'oggetto Root si ha l'accesso a tutta la struttura dello XAML della scena attraverso più metodi: Root corrisponde all'istanza del Canvas principale e come tale espone la proprietà children che restituisce una collezione VisualCollectiondegli oggetti al suo interno.

Come collezione, VisualCollection espone alcuni metodi di gestione degli elementi come Add, Clear, FindName, GetItem, Insert, Remove, RemoveAt; degno di nota è sicuramente il metodo FindName con il quale è possibile ottenere l'istanza dell'oggetto al quale corrisponde il nome specificato come parametro al valore impostato con l'attributo x:Name; la ricerca avviene in tutta la gerarchia dello XAML e nel caso non sia trovata corrispondenza è restituito null.

var _HelloTextBlock1 = plugIn.content.Root.FindName("HelloTextBlock1");

4 pagine in totale: 1 2 3 4

Attenzione: Questo articolo contiene un allegato.

Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti