di .NET e di altre amenità

Silverlight: Aggiornato il controllo

Ho aggiornato il controllo che ho pubblicato alcuni giorni orsono per semplificare la realizzazione di pagine ASPX che contengano applicazioni scritte con Silverlight. In particolare ho aggiunto una serie di proprietà che coprono le esigenze che ancora non erano state implementate nella versione precedente.

1) ScriptFile per referenziare un file .js che contiene gli script di gestione dell'applicazione

2) WindowsLess per gestire l'omonima proprietà

Download: Elite.Silverlight.Commodities.zip

Technorati tags: ,

Silverlight: Pixel Fonts a go-go

Chi si fosse chiesto se in Silverlight è possibile usare dei font diversi da quelli di sistema, potrebbe aver scoperto che la risposta a questa domanda è affermativa (e ci mancherebbe!!!). La cosa non è esattamente immediata, e soprattutto occorre considerare che Silverlight non supporta il font-embedding alla stregua di flash. Diversamente, almeno finchè nel team di sviluppo non si siano convinti del contrario, è necessario usare l'elemento <glyphs> per poter inserire spezzoni di testo che facciano uso di font diversi.

<Glyphs Width="650" Height="10" FontUri="./files/FFFHARMO.TTF" Fill="#AAA" FontRenderingEmSize="8" UnicodeString="my pixel font" />

Diventa così possibile usare i "pixel fonts" che da tempo sono apprezzatissimi in flash per la loro leggerezza e per la precisione del dettaglio. Il pixel fonts, per chi non li conoscesse sono dei particolati caratteri studiati appositamente per l'uso all'interno di flash. Richiedono il rispetto di due regole, seguendo le quali si otterranno con certezza eccellenti risultati:

1) posizionamento a coordinate intere, occhio quindi che in caso di posizionamento dinamico, conviene sempre arrotondare con Math.Round(posizione, 0).

2) uso di una dimensione fissa, solitamente quella nominale stabilita dall'autore del font stesso

Una buona sorgente per questo tipo di fonts è (Fonts for Flash). Vi troverete alcuni font molto piacevoli e di qualità veramente elevata, alcun di essi scaricabili anche gratuitamente.

Technorati tags: , ,

Silverlight: Mettere un'applicazione al 100% in Firefox

Ho scoperto le prime differenze di comportamento tra Firefox e Internet Explorer del plugin che fa da host a Silverlight. In realtà la differenza non è propria di Silverlight, ma piuttosto è un comportamento anomalo del tag <embed> che in Firefox viene usato per inserire i componenti ActiveX e quindi anche l'host in questione.

Mentre se con Internet Explore mettete Width e Height al 100% ottenete immediatamente il risultato voluto, con firefox non è così. La dimensione verticale infatti è gestita male da Firefox che si limiterà ad occupare una piccola porzione della pagina. Per ottenere un comportamento analogo al buone IE (io uso la 7.0) bisognerà usare il seguente css:

/* hide from ie5 mac \*/ html { height: 100%; overflow: hidden; } form { height: 100%; } .wpf { height: 100%; } /* end hide */ body { height: 100%; margin: 0; padding: 0; background-color: #666; }

la classe "wpf" andrà applicata ad un <DIV> apposto intorno al tag <EMBED>. Se usate il controllo che ho e che ho presentato in un precedente basterà usare la proprietà CssClass.

Technorati tags: , , ,

Appunti di WPF: ComponentOne public Beta

ComponentOne ha da qualche settimana iniziato una fase di beta test su prodotti dedicati a windows Presentation Foundation. La beta è pubblica ed è possibile iscriversi ad essa dal seguente indirizzo:

Link:

PortableApps: Il mondo su una chiavetta USB

Ieri sera ho scoperto un sito presso il quale è possibile scaricare una serie di applicazioni freeware, customizzate per poter girare da una chiavetta USB. Il sito presente un bel numero di applicazioni, alcune delle quali molto conosciute quali (Firefox, Thunderbird e Filezilla). La più utile in assoluto per quanto mi riguarda è Portable Firefox che mi ha risolto più di un problema.

Ecco l'elenco delle applicazioni Internet:

FileZilla Portable - the full-featured FTP client
FireFTP Extension (for Firefox) - a lightweight extension
Gaim Portable - chat with AOL, MSN and Yahoo users in an easy-to-use interface
Miranda IM Portable - chat with AOL, MSN and Yahoo users in a customizable interface
Mozilla Firefox, Portable Edition - the award-winning web browser that's safe and secure
Mozilla Thunderbird, Portable Edition - the handy email client
Nvu Portable & KompoZer Portable - the easy-to-use webpage editor
PuTTY Portable - lightweight telnet and SSH client
Sage Extension (for Firefox) - A full-featured RSS extension

Link:

Technorati tags: ,

 

Developer Highway Code

Sul sito di MSDN è stato pubblicato un libro gratuito a proposito di Security. Ovviamente nn ho ancora fatto a tempo a leggerlo, ma da una prima scansione veloce il libro, che conta 147 pagine, pare fatto bene.

Il libro viene illustrato come segue:

These security engineering activities have been developed by Microsoft patterns & practices to build on, refine and extend core lifecycle activities with a set of security-specific activities. These include identifying security objectives, applying design guidelines for security, threat modelling, security architecture and design reviews, security code reviews and security deployment reviews.

Se siete interessati potete scaricarlo gratuitamente da qui:

Silverlight: Un controllo ASP.NET per semplificare

Ho trovato un po' troppo laborioso e ripetitivo scrivere il codice necessario per inserire un contenuto realizzato con Silverlight in una pagina web. Comeprimo esercizio perciò mi sono creato un piccolo controllo ASP.NET che fa tutto ciò che serve. Non che sia difficile predisporre quel minimo di codice javascript che serve, ma secondo me il controllo è molto più efficace e immediato, a patto che usiate una pagina aspx per ospitarlo. Ecco come si inserisce:

 

SilverlightHost Control - Copy Code
1 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> 2 <%@ Register TagPrefix="wpf" 3 Namespace="Elite.Silverlight.Commodities" 4 Assembly="Elite.Silverlight.Commodities" %> 5 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 6 <html xmlns="http://www.w3.org/1999/xhtml"> 7 <head runat="server"> 8 <title>Silverlight Test Page</title> 9 </head> 10 <body> 11 <form id="form1" runat="server"> 12 <asp:ScriptManager ID="ScriptManager1" runat="server" /> 13 <wpf:SilverlightHost 14 runat="server" 15 ID="host0" 16 Width="300px" 17 Height="300px" 18 BackColor="#dddddd" 19 XamlFile="~/myxaml.xaml" 20 MaxFrameRate="30" /> 21 </asp:Wizard> 22 </form> 23 </body> 24 </html>

Il controllo si occupa di: inserire un <div> che fa da host per il plugin, di immettere il codice Javascript personalizzabile mediante le sue proprietà e di includere il file aghost.js come risorsa embedded dall'assembly. Naturalmente è scritto in modo tale da permettere l'inserimento di più di un contenuto wpf per singola pagina.

Come al solito il codice è disponibile per il download:

ASP.NET 2.0: DataBinding alla WPF

Da programmatore ASP.NET quale sono c'è una cosa che invidio a Windows Presentation Foundation. Non si tratta certo di animazioni, 3D e quant'altro che sono lontane anni luce da quel poco che si può fare con ASP.NET e con le recenti librerie AJAX e quindi non vale nemmeno la pena di invidiarle. Piuttosto se guardiamo al DataBinding, laddove ci sono delle profonde somiglianze, vi è anche una marcata differenza per quanto riguarda l'uso che se ne può fare in WPF quando ad esempio si collegano più controlli tra di loro. La prima volta che ho visto uno dei tanti esempi di DataBinding usato per questo scopo, sono rimasto letteralmente affascinato pensando a quanto codice mi avrebbe risparmiato il poter usare una sintassi simile in ASP.NET. Nulla di trascendentale, magari un checkbox che abilita o disabilita un pannello, un porzione di pagina che cambia colore in accordo con il valore di una DropDowList e così via, tutte cose che grazie al BindingEngine di WPF sono di una banalità impressionante ma che richiedono molto codice ridondante in ASP.NET.

Beh, la bella notizia è che con un po' di astuzia e con una buona conoscenza del funzionamento del modello di compilazione di ASP.NET (detto con tutta la modestia possibile, sia chiaro) la cosa si può fare eccome, e le differenze con WPF sono davvero minime, dettate soprattutto dal flusso di eventi che porta al rendering della pagina più che da altre sottigliezze. Ma prima di entrare nel merito di questa proof-of-concept che ho realizzato nelle serate della recente vacanza in Svizzera e che potete scaricare in coda a questo post, vale la pena di approfondire meglio con un piccolo esempio il funzionamento di WPF.

Binding, ElementName & Path

In WPF per realizzare il DataBinding si fa uso di quella che comunemente viene definita una Markup Extension. Le Merkup Extension che ora non è il caso di approfondire sono delle estensioni che permettono di semplificare la sintassi di XAML per introdurre referenze ed estensioni che arricchiscono il suo significato. "Binding" è la markup extension che si incarica di collegare i dati agli elementi compositivi dell'interfaccia. La cosa curiosa è che mediante Binding è possibile specificare come sorgente dati un elemento dell'interfaccia stessa.

<Border Margin="{Binding ElementName=sldDistance, Path=Value}"></Border>

Con una sintassi come quella specificata nel riquadro è possibile ad esempio specificare uno slider come sorgente dati di un Border. Il risultato sarà che spostando lo slider varia il margine del bordo. ElementName infatti specifica il legame con un ipotetico controllo Slider che porta questo nome mentre path referenzia la sua proprietà Value.

Penso sia evidente a tutti la potenza di una sintassi del genere che nel caso di WPF consente di applicare delle logiche anche molto complesse grazie anche all'uso di Converter che nella fase di binding sono in grado di applicare delle conversioni ai dati che transitano in una direzione e nell'altra. Per un esempio completo di quanto descritto vi invito ad approfondire un tempo fa.

Do it in ASP.NET

E' giunto il momento di mettere assieme i tasselli della soluzione che ho architettato per mimare in ASP.NET questo stesso comportamento. Il primo di essi si chiama ExpressionBuilder. Il più usato e famoso degli ExpressionBuilder è quello che in ASP.NET consente di specificare le risorse localizzate in una pagina. Si tratta semplicemente di un codeblock il cui prefisso è il simbolo del dollaro ($) che si comporta in modo molto particolare. Esso infatti viene valutato al momento della compilazione della pagina e da adito ad una piccola porzione di codice che assegna una attributo di un server control. Questo pezzetto di codice, generato per mezzo di CodeDOM viene inserito nella pagina compilata dal runtime ed è in grado di valorizzare la proprietà dui è associato applicando delle logiche particolari. Per una spiegazine estensiva vi invito a leggere un .

L'idea che mi è venuta è quella di sfruttare un ExpressionBuilder per simulare la markup extension di WPF. Una cosa che occorre tenere presente è che la stringa che funge da parametro di un ExpressionBuilder viene passata per intero al metodo responsabile di generare il codice perciò è molto semplice introdurre una sintassi simile, se non identica a quella delle markup extension.

BackColor="<%$ Binding: ElementName=ddlColor, Path=SelectedValue %>"

L'idea era buona, ma il problema è che il codice generato dalla ExpressionBuilder deve condurre all'assegnazione della proprietà cui è associata. Per questo mi ci è voluto un po' per arrivare ad un metodo alternativo, ma poi, meditando sull'uso degli Anonymous Methods ho trovato la giusta soluzione che ora provo ad illustrare.

Il primo passo è stato creare un metodo statico, nella classe che rappresenta il Builder, il quale si occupi di raccogliere le informazioni dei controlli specificati nel Binding e le utilizzi nel metodo anonimo associato all'evento load della pagina. Ecco il metodo in questione:

public static T MakeBinding<T>( Page page, string boundControlId, string boundPropertyName, string targetControlId, string targetPropertyName, string converter, string converterParameter) { page.Load += delegate(object sender, EventArgs e) { Control bound = page.Form.FindControl(boundControlId); if (bound == null) return; Control target = page.Form.FindControl(targetControlId); if (target == null) return; Type boundType = bound.GetType(); PropertyInfo boundProperty = boundType.GetProperty(boundPropertyName); if (boundProperty == null) return; Type targetType = target.GetType(); PropertyInfo targetProperty = targetType.GetProperty(targetPropertyName); if (targetProperty == null) return; object targetValue = targetProperty.GetValue(target, null); IValueConverter converterInstance = CreateConverter(converter); boundProperty.SetValue(bound, converterInstance.Convert( targetValue, boundProperty.PropertyType, converterParameter, CultureInfo.CurrentUICulture), null); }; return default(T); }

Il metodo è un Generico perchè deve restituire un tipo conforme con la proprietà cui è associato il Binding. Esso poi riceve in ingresso i parametri che vengono estratti dalla stringa dell'ExpressionBuilder. In prima istanza non fa altro che agganciare un anonymous method all'evento load della pagina. Al momento in cui l'evento viene sollevato i parametri vengono usati per  trovare i controlli referenziati nella pagina e copiare i valori opportunamente trasformati dal convertitore prescelto oppure da quello di Default. Il convertitore altro non è che una classe che implementa l'interfaccia IValueConverter, la stessa che fa capo ai convertitori di WPF. Infine il metodo ritorna il valore di default per il tipo generico.

L'expressionBuilder non fa altro che forgiare una chiamata al metodo statico MakeBinding<T>() con gli opportuni parametri:

public override CodeExpression GetCodeExpression( BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) { Dictionary<string, string> values = Parse(entry.Expression); return new CodeSnippetExpression( string.Format( @"Elite.Web.UIDataBinding.BindingExpressionBuilder.MakeBinding<{0}>" + @"(this, ""{1}"", ""{2}"", ""{3}"", ""{4}"", ""{5}"", ""{6}"")", entry.PropertyInfo.PropertyType.FullName, entry.ControlID, entry.PropertyInfo.Name, values["ElementName"], values["Path"], values.ContainsKey("Converter") ? values["Converter"] : null, values.ContainsKey("ConverterParameter") ? values["ConverterParameter"] : null)); }

Si potrebbe fare meglio, usando bene le classi e i metodi di CodeDOM, ma per questo esempio è sufficiente. Tutto sommato il mio obbiettivo è di provare che il meccanismo funziona a dovere. Scaricando il codice troverete un piccolo esempio che associa ad AJAX l'utilizzo dell'ExpressionBuilder. La cosa ce vi invito a notare è che per realizzarlo non è stato necessario scrivere alcun codice nel codebehind della pagina perchè tutte i comportamenti sono conferiti mediante l'Expression Builder. Chi intendesse utilizzarlo tenga presenta che si tratta di poco più che un test, e che ha alcune limitazioni rispetto a WPF, dovute più che altro alla mancata implementazione:

  1. La proprietà Path non consente di specificare un vero e proprio Path come in WPF ma solo il Control ID.
  2. I controlli vengono cercati solo al primo livello della gerarchia
  3. Specificare un converter è un po' difficile perchè richiede di immettere il namespace e la classe. Sarebbe meglio trovare un metodo per abbreviare la sintassi che altrimenti rischia di essere un po' troppo logorroico.-
  4. Le proprietà composte di ASP.NET non sono supportate (es. Font-Size)

Tutte queste limitazioni sono facilmente superabili e probabilmente un po' alla volta cercherò di pubblicare nuove versioni se il Binder incontrerà il successo che ha avuto ASP.NET. Per il momento vi invito a provare l'esempio di cui potete vedere uno spezzone in questo riquadro:

<div class="panel"> <asp:Panel id="pnlFont" runat="server" CssClass="scroll-panel" Height="100px"> <asp:Image id="imgSpiderman" runat="server" ImageUrl="images/spiderman.jpg" Width="<%$ Binding: ElementName=ddlSize, Path=SelectedValue, Converter=Elite.Web.UIDataBinding.UnitConverter %>" Height="<%$ Binding: ElementName=ddlSize, Path=SelectedValue, Converter=Elite.Web.UIDataBinding.UnitConverter %>" /> </asp:Panel> <p class="control-row"><label>Size:</label> <asp:DropDownList ID="ddlSize" runat="server" AutoPostBack="true"> <asp:ListItem Text="25%" Value="25" /> <asp:ListItem Text="50%" Value="50" /> <asp:ListItem Text="100%" Value="100" Selected="True" /> <asp:ListItem Text="200%" Value="200" /> <asp:ListItem Text="400%" Value="400" /> </asp:DropDownList></p> </div>

Download: Elite.Web.UIDataBinding.zip (23,4 Kb)

Video: Demo (72 KB)

XeDotNet: WCF è andata... prossima tappa WF

Venerdì sera si è consumato il meeting su Windows Comunication Foudation, che ha visto uno strepitoso Davide Bedin che alla sua prima apprizione in pubblico ha affrontato questa ostica piattaforma con dovizia di particolari, dando soprattutto il polso di chi come lui ne ha già avuto a che fare per il lavoro reale.

Ora, scrivo queste due righe in roaming GPRS da un paesino al confine tra svizzera e Germania per ricordare che il prossimo 11 Maggio avremo l'onore di ospitare Raffaele Rialdi, che ci metterà al corrente della sua esperienz con Workflow Foundation, probabilmente delle tre W*F quella che più incuriosisce, ma che promette molto bene...

A presto!!!

Appunti di WPF: Expression distribuite con MSDN

Probabilmente la notizia è già girata ieri, ma la ribadisco perché serva da informazione di completamento per chi mi ha seguito al meeting di un mese fa. In buona sostanza è stato annunciato che l'uscita dalla beta degli strumenti della linea "expression" li vedrà disponibili al pubblico all'interno di MSDN Premium.
La notizia non è per nulla scontata dato che precedenti rumors davano questi prodotti per completamente esclusi da MSDN.

Applied KISS

Più volte ho avuto modo di dire come la penso a proposito del valore della semplicità. In questi giorni ho avuto l'ennesima conferma della bontà delle mie opinioni provando alcuni reader rss per il mio PDA. L'occasione mi è stata data dalla prova di due software, NewsBreak e PocketRSS. Si tratta di due applicazioni molto diverse tra loro che però hanno lo stesso obbiettivo. Tra i due quello che sembra più completo è PocketRSS, che gode di innumerevoli funzioni, alcune anche molto raffinate che difficilmente si trovano anche in software per pc. Ma alla fine, dopo due giorni di prove ho optato per NewsBreak perché nonostante manchi di tutta una serie di gingilli,ha una gestione dei tasti splendida, che mi permette di sfogliare i post con una sola mano. Ecco, questo è proprio quello che intendo quando parlo di semplicità... tutti sono in grado di aggiungere funzioni alle proprie applicazioni, ma alla fine la parte difficile è semplificare per trovare quelle che veramente danno un valore aggiunto.

E c'era bisogno di dirlo?

Stamane me la sono spassata e ho bellamente evitato il pc per tutto il giorno. Ecco perché vengo a conoscenza solo ora della notizia che all'amico Davide Vernole è stato rinnovato quest'anno per la quinta volta il premio di MVP. Congratulazioni Davide... per quanto mi riguarda non c'era bisogno di un premio per confermare il tuo valore... ma male non fa.