WPF http://blogs.ugidotnet.org/PietroLibroBlog/category/WPF.aspx WPF it-IT Pietro Libro pietro.libro@libero.it Subtext Version 2.6.0.0 ASP.NET 4.5 e WebSocket: Real Time e Two-Way (parte 1) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/09/07/asp.net-4.5-e-websocket-real-time-e-two-way-parte.aspx Chi sviluppa per il Web, si scontra ogni giorno con le “limitazioni” del modello request-response di HTTP, il quale non è pensato “ad hoc” per applicazioni real time, o comunicazione bidirezionale client-server. Per questi scenari, spesso vengono utilizzate tecniche di polling, da parte del client, per verificare l’eventuale presenza di dati “freschi”, eseguendo continuamente delle richieste HTTP, comportando dei “costi”: il server deve utilizzare differenti connessioni TCP per ogni client (una per inviare informazioni ed una per rispondere alla richiesta di aggiornamenti), un continuo scambio di messaggi client-server (comportando quindi un aumento del traffico di rete). Potrebbe sembrare cosa da poco, ma se pensiamo ad applicazioni web con migliaia di client connessi, le risorse di server e banda potrebbero essere velocemente consumate (e dato che la nostra epoca è <em>affamata</em> di risorse potremmo trovarci in situazioni poco piacevoli). <p>Quindi, quale potrebbe essere la soluzione ? utilizzare una singola connessione TCP per gestire il traffico in entrambe le direzioni, ovvero il protocollo WebSocket, che se gestito mediante le WebSocket API (WSAPI), fornisce un’ottima alternativa alla tecnica di polling di cui parlavamo in precedenza. Possiamo utilizzare i WebSocket in diversi scenari: giochi, applicazioni di editing real time multi-utente, UI web che espongono dati lato server in tempo reale ecc .… tutto questo condividendo le porte standard HTTP 80 e 443, “attraversando” firewalls, proxies e router senza problemi. Possiamo riassumere le due “tecniche” discusse in precedenza con la figura seguente;</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/896b2c2d5b0f_5666/image_4.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/896b2c2d5b0f_5666/image_thumb_1.png" /></a></p> <p>dalla quale si evince come l’utilizzo del “polling” comporti una maggiore latenza nella trasmissione delle informazioni utili. Nell’immagine, nella comunicazione bidirezionale offerta dai WebSocket, come primo passo (dal client verso il server) c’è la voce “WebSocket upgrade”, cosa sarà mai ?, un passo per volta.</p> <p>Il protocollo è diviso in due parti: <em>handshakes</em> e <em>transfer data. </em>Durante la  prima parte (di negoziazione),  client e server comunicano scambiandosi dei pacchetti di controllo per stabilire una connessione WebSocket.  Il client invia una richiesta di questo tipo:</p> <pre> GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Origin: <a href="http://example.comSec-WebSocket-Version">http://example.com Sec-WebSocket-Version</a>: 13</pre> ed il server (normalmente) dovrebbe rispondere con: <pre> HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=</pre> <p>In dettaglio, il processo di connessione parte con una standard GET HTTP, e fin qui tutto regolare:</p> <pre>GET /echo HTTP/1.1 Host: example.microsoft.com</pre> <p>poi, <em>l’header</em> “Upgrade” richiede al server di cambiare il protocollo a livello di <em>application-layer</em> da HTTP a WebSocket:</p> <pre>Upgrade: websocket Connection: Upgrade</pre> <p>Il valore presente in <em>Sec-WebSocket-Key</em> inviato dal client verrà utilizzato dal server per far capire al chiamante che “comprende” la richiesta:</p> <pre>Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==</pre> <p>L’<em>header Sec-WebSocket-Version </em>identifica la versione del protocollo da utilizzare:</p> <pre>Sec-WebSocket-Version: 13</pre> <p>A questo punto, se il server “comprende” la nostra richiesta , il server eseguirà un “Upgrade” <em>dell’application-layer</em> e risponderà con lo stato HTTP 101. Il valore contenuto in <em>Sec-WebSocket-Accept </em>verrà utilizzato dal client per validare che il server è un WebSocket server e non un “semplice” HTTP server. </p> <p>Una volta che client e server hanno entrambi inviati i loro <em>handshakes</em>, (e <em>l’handshaking</em> ha avuto successo) può iniziare il trasferimento dati su un unico canale di comunicazione bidirezionale, tra client e server, sfruttando la connessione TCP precedentemente stabilita.</p> <p>I dati trasferiti tra le due parti sono racchiusi in unità logiche chiamate “messaggi”, ogni messaggio è fisicamente  composto da uno o più <em>frames</em>. </p> <p>Dopo la teoria la pratica…</p> <p>Il protocollo WebSocket, definisce due nuove tipologie di URI:</p> <ol> <li>ws://host [: port] path [? query] (di default usa la porta 80 e connessione non cifrata) </li> <li>wss://host [:port] path [? query] (di default utilizza la porta 443, ed una connessione cifrata HTTP over TLS) </li> </ol> <p>Le ultime specifiche del protocollo  sono definite nel documento <a href="http://tools.ietf.org/html/rfc6455" target="_blank">RFC 6455</a>. Per “sporcarci le mani” con i  WebSocket, possiamo sviluppare un semplice pagina web con estensione <em>.html</em>, come la seguente:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/896b2c2d5b0f_5666/image_6.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/896b2c2d5b0f_5666/image_thumb_2.png" width="244" height="174" /></a></p> <p>I bottoni <em>Open</em> e <em>Close</em>, sono rispettivamente utilizzati per aprire e chiudere la connessione del WebSocket, mentre il campo <em>text </em>per inviare un messaggio al server, il quale risponderà inviando al client la lunghezza della stringa inviata (ovviamente il livello pratico dell’esempio è praticamente nullo <img class="wlEmoticon wlEmoticon-smile" style="border-top-style: none; border-left-style: none; border-bottom-style: none; border-right-style: none" alt="Sorriso" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/896b2c2d5b0f_5666/wlEmoticon-smile_2.png" />).</p> <p>Per stabilire una connessione con il server, utilizziamo le seguenti righe di codice client-script:</p> <pre class="csharpcode"><span class="kwrd">var</span> uri = <span class="str">'ws://localhost:9915/WebSocketHandler.ashx'</span>; websocket = <span class="kwrd">new</span> WebSocket(uri);</pre> <p /><style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style>Per conoscere quando la connessione con il server è stata creata è necessario sottoscriversi all’evento <em>onopen:</em> <pre class="csharpcode"> websocket.onopen = <span class="kwrd">function</span> () { appendData(<span class="str">"Connected."</span>); appendData(uri); $(<span class="str">'#wsform'</span>).submit(<span class="kwrd">function</span> (<span class="kwrd">event</span>) { websocket.send($(<span class="str">'#inputbox'</span>).val()); $(<span class="str">'#inputbox'</span>).val(<span class="str">''</span>); <span class="kwrd">event</span>.preventDefault(); }); $(<span class="str">"#closeButton"</span>).removeAttr(<span class="str">"disabled"</span>); };</pre> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style>Con lo script precedente, all’apertura della connessione visualizziamo il messaggio “Connected.” e l’URI utilizzato per la connessione. Dopodiché ci registriamo all’evento <em>submit </em>per inviare al server, utilizzando l’API <em>Send,</em> messaggi al WebSocket server sotto forma di testo UTF-8 o Blobs. <p>Per ricevere messaggi, dobbiamo registrarsi all’evento <em>onmessagge</em> dell’oggetto <em>websocket</em> il quale riceve <em>messageEvent</em> che espone la proprietà <em>data</em>, contenente le informazioni inviate al client: </p> <pre class="csharpcode">websocket.onmessage = <span class="kwrd">function</span> (<span class="kwrd">messageEvent</span>) { <span class="kwrd">var</span> receivedData = <span class="kwrd">messageEvent</span>.data.toString(); appendData(receivedData); };</pre> <p>Il codice precedente è veramente banale, in quanto si limita a recuperare il testo inviato dal server in risposta al client e visualizzarlo sul browser tramite un <em>div</em>.</p> <p>Come per l’apertura, c’è una sorta di <em>handshaking</em> per la chiusura della connessione, che può essere iniziata indipendentemente dal client o dal server. Chi inizia il processo di chiusura, invia uno speciale frame, detto <em>close </em><em>frame, </em>che può contenere, opzionalmente, un codice di stato (il protocollo fornisce un insieme di codici di stato appropriati per la chiusura) e la ragione  (una descrizione testuale) della chiusura. Quando una delle due parti riceve un <em>close frame</em>, invia lo stesso frame all’altra parte (eventualmente, prima di rinviarlo, invia i messaggi <em>pending</em>) e la comunicazione viene chiusa.</p> <p>Per iniziare il processo di <em>close handshake</em>, bisogna invocare l’API <em>close:</em></p> <pre class="csharpcode"><span class="kwrd">function</span> closeWebSocket() { websocket.close(1000, <span class="str">"Normal."</span>); }</pre> <p>Il valore 1000 indica lo stato “Normal Closure”. Come “ragione” della chiusura specifichiamo il testo “Normal”. Per sapere quando la chiusura è stata completata, ci sottoscriviamo all’evento <em>onclose</em>:</p> <pre class="csharpcode">websocket.onclose = <span class="kwrd">function</span> () { appendData(<span class="str">"Closed."</span>); $(<span class="str">"#closeButton"</span>).attr(<span class="str">"disabled"</span>, <span class="str">"disabled"</span>); };</pre> <p>Con la funzione precedente, visualizziamo il messaggio “Closed.”, e disabilitiamo il <em>button </em>per la chiusura del WebSocket.</p> <p>La parte <em>server </em>è composta da una classe <em>IHttpHandler</em> che fa uso della classe <em>WebSocketContext </em>(.NET 4.5) utilizzata per accedere alle informazioni di WebSocket <em>handshake</em>. Attraverso altri semplici post, l’obiettivo è realizzare una semplice “lavagna” interattiva real time, utilizzando sia un browser web, che un client WPF, come mostrato seguente:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/896b2c2d5b0f_5666/image_8.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/896b2c2d5b0f_5666/image_thumb_3.png" width="244" height="120" /></a></p> <p>A tal fine, utilizzeremo lato Windows, la classe <em>ClientWebSocket</em>, presente nel namespace <em>System.Net.WebSockets</em>, la quale fornisce un client per connettersi a servizi esposti tramite WebSocket.</p> <div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:c48c848e-1b4e-4e73-8296-91ef7c42d243" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"><p>Source Code <a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/896b2c2d5b0f_5666/WebSocketsSample.zip" target="_blank">Source Code</a></p></div><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/101203.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/09/07/asp.net-4.5-e-websocket-real-time-e-two-way-parte.aspx Fri, 07 Sep 2012 07:58:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2012/09/07/asp.net-4.5-e-websocket-real-time-e-two-way-parte.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/101203.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/101203.aspx Bing Maps WPF Control (Beta) http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/08/24/bing-maps-wpf-control-beta.aspx <p>SDK per utilizzare le mappe di Bing all’interno delle nostre applicazioni WPF. Una volta installato, è sufficiente trascinare il controllo “Map” all’interno del Designer di WPF e scrivere praticamente nulla, piccolo esempio:</p> <div id="codeSnippetWrapper" class="csharpcode-wrapper"> <pre id="codeSnippet" class="csharpcode">&lt;my:Map HorizontalAlignment=<span class="str">"Center"</span> Margin=<span class="str">"0"</span> Name=<span class="str">"map1"</span> VerticalAlignment=<span class="str">"Center"</span> <br /> Height=<span class="str">"270"</span> Width=<span class="str">"500"</span> CredentialsProvider=<span class="str">"BING_KEY"</span> Mode=<span class="str">"AerialWithLabels"</span> <br /> Center=<span class="str">"41.90,12.60"</span> ZoomLevel=<span class="str">"10"</span> /&gt;</pre> <br /></div> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WPF-Bing-Maps_981E/image_2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/Windows-Live-Writer/WPF-Bing-Maps_981E/image_thumb.png" width="244" height="158" /></a></p> <p>Ovviamente per l’utilizzo è necessario essere in possesso di una Bing Map Key. Download del controllo <a href="http://www.microsoft.com/download/en/details.aspx?id=27165" target="_blank">qui</a>.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/100295.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/08/24/bing-maps-wpf-control-beta.aspx Wed, 24 Aug 2011 12:24:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/08/24/bing-maps-wpf-control-beta.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/100295.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/100295.aspx WPF, Windows Xp e file .ico http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/08/03/wpf-windows-xp-e-file-.ico.aspx <p>Post promemoria. Se dopo aver <em>deployato</em> con ClickOnce un’applicazione WPF  (composta da due WPF Windows, senza nessuna forma di connessione a database) all’avvio si riscontra un errore del tipo:</p> <p><em>Application: X <br />Framework Version: v4.0.30319 <br />Description: The process was terminated due to an unhandled exception. <br />Exception Info: System.Windows.Markup.XamlParseException <br />Stack: <br />   at System.Windows.Markup.XamlReader.RewrapException(System.Exception, System.Xaml.IXamlLineInfo, System.Uri) <br />   at System.Windows.Markup.WpfXamlLoader.Load(System.Xaml.XamlReader, System.Xaml.IXamlObjectWriterFactory, Boolean, System.Object, System.Xaml.XamlObjectWriterSettings, System.Uri)</em></p> <p><em>….</em></p> <p>Allora è importante verificare che l’applicazione non utilizzi file icona al di fuori dello standard Windows XP. Maggiori dettagli sulla soluzione proposta su <a href="http://connect.microsoft.com/VisualStudio/feedback/details/321285/wpf-application-fails-if-window-icon-is-a-vista-ico-file" target="_blank">Connect - WPF application fails if Window.Icon is a Vista .ico file</a>.</p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/100248.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/08/03/wpf-windows-xp-e-file-.ico.aspx Wed, 03 Aug 2011 11:35:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2011/08/03/wpf-windows-xp-e-file-.ico.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/100248.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/100248.aspx In the box - MVVM Training http://blogs.ugidotnet.org/PietroLibroBlog/archive/2010/12/07/in-the-box-mvvm-training.aspx <h6>What is In the Box?</h6> <p><em>In the Box is a high quality, multi-media training that is consumed within Visual Studio 2010.  Content is navigated and delivered using a next generation computer based training (CBT) experience, the Visual Studio 2010 Feature Extension</em></p> <p><em>Link: </em><a href="http://karlshifflett.wordpress.com/2010/11/07/in-the-box-ndash-mvvm-training/">In the Box – MVVM Training</a></p><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/99538.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2010/12/07/in-the-box-mvvm-training.aspx Tue, 07 Dec 2010 07:31:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2010/12/07/in-the-box-mvvm-training.aspx#feedback 2 http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/99538.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/99538.aspx WPF: System.Windows.Threading.Dispatcher e BeginInvoke http://blogs.ugidotnet.org/PietroLibroBlog/archive/2010/08/28/wpf-system.windows.threading.dispatcher-e-begininvoke.aspx <p>Spesso, quando si lavora con applicazioni multithread (soprattutto in applicazioni Windows Form), siamo abituati a ricorrere alla proprietà <em>InvokeRequierd</em> dei controlli per verificare se il thread chiamante è proprietario del controllo o se lo è un altro, e   nel caso, utilizzare un delegate per utilizzare la proprietà del controllo a cui siamo interessati.  Per un elemento WPF  dobbiamo utilizzare un’istanza di della classe <em>System.Windows.Threading.Dispatcher</em>, presente tra le proprietà che un elemento WPF espone. Ad esempio, supponiamo di utilizzare un’istanza della classe <em>System.Timers.Timer</em> per visualizzare l’ora corrente in un elemento Label:</p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1"> 1:</span> _timer = <span style="color: #0000ff">new</span> System.Timers.Timer();</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2"> 2:</span> _timer.Interval = 1000;</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3"> 3:</span> _timer.Elapsed += <span style="color: #0000ff">new</span> System.Timers.ElapsedEventHandler(timer_Elapsed);</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4"> 4:</span> _timer.Start();</pre> <!--CRLF--></div> </div> <p>La variabile _timer è dichiarata a livello di modulo nel code-behind di una Window WPF. Se nel gestore dell’evento <em>Elapsed</em> del Timer scrivessimo del codice simile al seguente:</p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1"> 1:</span> <span style="color: #0000ff">void</span> timer_Elapsed(<span style="color: #0000ff">object</span> sender, System.Timers.ElapsedEventArgs e)</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2"> 2:</span> {</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3"> 3:</span> label1.Content = DateTime.Now.ToLongTimeString(); </pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4"> 4:</span> }</pre> <!--CRLF--></div> </div> <p>Verrebbe sollevata un’eccezione del tipo <em>InvalidOperationException</em> riportante  il seguente messaggio: <em>“The calling thread cannot access this object because a different thread owns it.”  </em></p> <p>Proviamo a scrivere un po’ di codice per utilizzare il Dispatcher:</p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1"> 1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">delegate</span> <span style="color: #0000ff">void</span> onTickTimerDelegate(); </pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2"> 2:</span>  </pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3"> 3:</span> <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> UpdateTimeLabel()</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4"> 4:</span> {</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5"> 5:</span> <span style="color: #0000ff">if</span> (label1.Dispatcher.Thread == Thread.CurrentThread)</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6"> 6:</span> {</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7"> 7:</span> </pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8"> 8:</span> label1.Content = DateTime.Now.ToLongTimeString();</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9"> 9:</span> }</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10"> 10:</span> <span style="color: #0000ff">else</span></pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11"> 11:</span> {</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12"> 12:</span> onTickTimerDelegate tickTimerDelegate = <span style="color: #0000ff">new</span> onTickTimerDelegate(UpdateTimeLabel);</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13"> 13:</span> label1.Dispatcher.BeginInvoke(tickTimerDelegate,</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14"> 14:</span> System.Windows.Threading.DispatcherPriority.Normal,</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15"> 15:</span> <span style="color: #0000ff">null</span>);</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum16"> 16:</span> }</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum17"> 17:</span> }</pre> <!--CRLF--></div> </div> <p>Se scriviamo il gestore di  <em>Elapsed</em> in questo modo:</p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1"> 1:</span> <span style="color: #0000ff">void</span> timer_Elapsed(<span style="color: #0000ff">object</span> sender, System.Timers.ElapsedEventArgs e)</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2"> 2:</span> {</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3"> 3:</span> UpdateTimeLabel();</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4"> 4:</span> }</pre> <!--CRLF--></div> </div> <p>Tutto funziona correttamente. Facciamo un ulteriore passo  e modifichiamo il codice in modo che la il nostro metodo (e associato delegate) accetti anche un parametro:</p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1"> 1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">delegate</span> <span style="color: #0000ff">void</span> onTickTimerDelegateWithParameter(<span style="color: #0000ff">object</span> par);</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2"> 2:</span> <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> UpdateTimeLabel(<span style="color: #0000ff">object</span> par)</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3"> 3:</span> {</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4"> 4:</span> <span style="color: #0000ff">if</span> (label1.Dispatcher.Thread == Thread.CurrentThread)</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5"> 5:</span> {</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6"> 6:</span> label1.Content = DateTime.Now.ToLongTimeString() + <span style="color: #006080">" PAR: "</span> + par.ToString();</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7"> 7:</span> }</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8"> 8:</span> <span style="color: #0000ff">else</span></pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9"> 9:</span> {</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10"> 10:</span> onTickTimerDelegateWithParameter tickTimerDelegateWithParameter = <span style="color: #0000ff">new</span> onTickTimerDelegateWithParameter(UpdateTimeLabel);</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11"> 11:</span> label1.Dispatcher.BeginInvoke(tickTimerDelegateWithParameter,</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12"> 12:</span> System.Windows.Threading.DispatcherPriority.Normal,</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13"> 13:</span> par);</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14"> 14:</span> }</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15"> 15:</span> }</pre> <!--CRLF--></div> </div> <p>In questo caso, nella contenuto della label visualizzeremo una stringa rappresentante l’ora  (ore, minuti e secondi) concatenata ad una stringa che “rappresenta” l’oggetto passato come argomento. Ad esempio, se scrivessimo:</p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1"> 1:</span> <span style="color: #0000ff">void</span> timer_Elapsed(<span style="color: #0000ff">object</span> sender, System.Timers.ElapsedEventArgs e)</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2"> 2:</span> {</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3"> 3:</span> UpdateTimeLabel(<span style="color: #0000ff">new</span> Random().Next());</pre> <!--CRLF--> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4"> 4:</span> }</pre> <!--CRLF--></div> </div> <p /> <p>Oltre l’ora, verrebbe visualizzato un numero (intero) generato dalla classe Random.</p> <p>Citando <a href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.aspx" target="_blank">MSDN</a>, la classe <em>Dispatcher</em> rappresenta una coda con priorità dei work item associati ad uno specifico thread. In particolare, in WPF, un oggetto <em>Dispatcher</em> può essere acceduto solo dal relativo  <em>Dispatcher</em>: ad esempio un thread di Background non può essere utilizzato per aggiornare il contenuto di un Button (o una Label come nel caso specifico del post), perché quest’ultimo è associato con il <em>Dispatcher</em> dell’interfaccia utente (sollevando l’eccezione precedentemente descritta). Possiamo quindi utilizzre <em>Invoke</em> e <em>BeginInvoke</em> secondo se vogliamo utilizzare rispettivamente un approccio sincrono o asincrono per l’esecuzione dell’operazione da noi richiesta. Quando aggiungiamo le operazioni ad una coda è importante specificare con quale priorità vogliamo aggiungerla rispetto alle altre operazioni presenti: per far questo utilizziamo l’enum <a href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherpriority.aspx" target="_blank">System.Windows.Threading.DispatcherPriority</a>. I valori dell’enum variano da 0 a 10 (in verità da –1 a 10), in ordine di priorità crescente:</p> <ul> <li>0, l’operazione non è processata (Inactive) </li> <li>1, l’operazione è processata quando il sistema è idle (SystemIdle) </li> <li>2, l’operazione è processata quanto l’applicazione è idle (ApplicationIdle) </li> <li>3, l’operazione è processata dopo che le operazioni di background sono state completate (ContextIdle) </li> <li>4, le operazioni sono processate dopo che tutte le operazioni non-idle sono state completate (Background) </li> <li>5, le operazioni sono processate con la stessa priorità dell’input (Input) </li> <li>6, le operazioni sono processate quando il layout ed il render hanno terminato, ma prima delle operazioni Input </li> <li>7, le operazioni sono processate con la stessa priorità del Render (Render) </li> <li>8, le operazioni sono processate con la stessa priorità del Data Binding (DataBinding) </li> <li>9, le operazioni sono processate a priorità normale (tipica dell’applicazione) (Normal) </li> <li>10, le operazioni sono processare prima delle operazioni asincrone, rappresenta la priorità più alta (Send) </li> </ul><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/99120.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2010/08/28/wpf-system.windows.threading.dispatcher-e-begininvoke.aspx Sat, 28 Aug 2010 20:12:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2010/08/28/wpf-system.windows.threading.dispatcher-e-begininvoke.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/99120.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/99120.aspx WPF: PriorityBinding http://blogs.ugidotnet.org/PietroLibroBlog/archive/2010/04/07/wpf-prioritybinding.aspx <p> </p> <p>Può capitare di dover mostrare un risultato non  immediatamente disponibile per la lettura, perché, ad esempio, il suo valore dipende da altri parametri e deve quindi essere calcolato. A tal fine, vogliamo mostrare un messaggio all’utente per indicare che l’applicazione è in esecuzione e che non è in una fase di stallo,  qualcosa di simile quando utilizziamo un <em>UpdateProgress</em> dell’Ajax Control Toolkit (o corrispondenti soluzioni custom) nelle nostre pagine Web. In WPF, possiamo utilizzare il <em>PriorityBiding</em> per fare qualcosa di simile (ma non solo). Il <em>PriorityBinding</em> permette di associare ad una proprietà di un elemento, un elenco di associazioni (invece di una singola associazione dati come nel “normale” Binding). Tra le associazioni, viene considerata la prima che restituisce correttamente un valore: ovvero se il Path del Binding viene risolto correttamente, se il valore restituito da un <em>Converter</em> è valido (sempre che ne venga utilizzato uno) o se il valore è valido per la proprietà di destinazione. Supponiamo di avere una classe <em>Data</em> come la seguente:</p> <p /> <div class="csharpcode"> <pre><span class="lnum"> 1: </span> <span class="kwrd">public</span> <span class="kwrd">class</span> Data : INotifyPropertyChanged</pre> <pre><span class="lnum"> 2: </span> {</pre> <pre><span class="lnum"> 3: </span> <span class="kwrd">private</span> <span class="kwrd">double</span> _salary = 0;</pre> <pre><span class="lnum"> 4: </span> <span class="kwrd">private</span> <span class="kwrd">string</span> _employeeName = <span class="str">""</span>;</pre> <pre><span class="lnum"> 5: </span> <span class="kwrd">public</span> <span class="kwrd">event</span> PropertyChangedEventHandler PropertyChanged;</pre> <pre><span class="lnum"> 6: </span> </pre> <pre><span class="lnum"> 7: </span> <span class="kwrd">public</span> <span class="kwrd">string</span> EmployeeName</pre> <pre><span class="lnum"> 8: </span> {</pre> <pre><span class="lnum"> 9: </span> get { <span class="kwrd">return</span> _employeeName; }</pre> <pre><span class="lnum"> 10: </span> set</pre> <pre><span class="lnum"> 11: </span> {</pre> <pre><span class="lnum"> 12: </span> _employeeName = <span class="kwrd">value</span>;</pre> <pre><span class="lnum"> 13: </span> OnPropertyChanged(<span class="str">"EmployeeName"</span>);</pre> <pre><span class="lnum"> 14: </span> }</pre> <pre><span class="lnum"> 15: </span> }</pre> <pre><span class="lnum"> 16: </span> </pre> <pre><span class="lnum"> 17: </span> <span class="kwrd">public</span> <span class="kwrd">void</span> Calculate() { OnPropertyChanged(<span class="str">"Salary"</span>); }</pre> <pre><span class="lnum"> 18: </span> </pre> <pre><span class="lnum"> 19: </span> <span class="kwrd">public</span> <span class="kwrd">double</span> Salary</pre> <pre><span class="lnum"> 20: </span> {</pre> <pre><span class="lnum"> 21: </span> get</pre> <pre><span class="lnum"> 22: </span> {</pre> <pre><span class="lnum"> 23: </span> _salary = 0;</pre> <pre><span class="lnum"> 24: </span> <span class="kwrd">if</span> (!<span class="kwrd">string</span>.IsNullOrEmpty(_employeeName))</pre> <pre><span class="lnum"> 25: </span> {</pre> <pre><span class="lnum"> 26: </span> <span class="rem">//Supponiamo un'operazione che impieghi un certo tempo...</span></pre> <pre><span class="lnum"> 27: </span> System.Threading.Thread.Sleep(3000);</pre> <pre><span class="lnum"> 28: </span> </pre> <pre><span class="lnum"> 29: </span> <span class="kwrd">switch</span> (_employeeName.ToLower())</pre> <pre><span class="lnum"> 30: </span> {</pre> <pre><span class="lnum"> 31: </span> <span class="kwrd">case</span> <span class="str">"pietro"</span>:</pre> <pre><span class="lnum"> 32: </span> _salary = 1000;</pre> <pre><span class="lnum"> 33: </span> <span class="kwrd">break</span>;</pre> <pre><span class="lnum"> 34: </span> <span class="kwrd">case</span> <span class="str">"giovanni"</span>:</pre> <pre><span class="lnum"> 35: </span> _salary = 2000;</pre> <pre><span class="lnum"> 36: </span> <span class="kwrd">break</span>;</pre> <pre><span class="lnum"> 37: </span> <span class="kwrd">default</span>:</pre> <pre><span class="lnum"> 38: </span> _salary = 0;</pre> <pre><span class="lnum"> 39: </span> <span class="kwrd">break</span>;</pre> <pre><span class="lnum"> 40: </span> }</pre> <pre><span class="lnum"> 41: </span> }</pre> <pre><span class="lnum"> 42: </span> <span class="kwrd">return</span> _salary;</pre> <pre><span class="lnum"> 43: </span> }</pre> <pre><span class="lnum"> 44: </span> }</pre> <pre><span class="lnum"> 45: </span> </pre> <pre><span class="lnum"> 46: </span> <span class="kwrd">protected</span> <span class="kwrd">void</span> OnPropertyChanged(<span class="kwrd">string</span> prop)</pre> <pre><span class="lnum"> 47: </span> {</pre> <pre><span class="lnum"> 48: </span> <span class="kwrd">if</span> (PropertyChanged != <span class="kwrd">null</span>) PropertyChanged(<span class="kwrd">this</span>, <span class="kwrd">new</span> PropertyChangedEventArgs(prop));</pre> <pre><span class="lnum"> 49: </span> }</pre> <pre><span class="lnum"> 50: </span> </pre> <pre><span class="lnum"> 51: </span> <span class="kwrd">public</span> <span class="kwrd">string</span> WaitMessage1 { get { <span class="kwrd">return</span> <span class="str">"Loading..."</span>; } }</pre> <pre><span class="lnum"> 52: </span> </pre> <pre><span class="lnum"> 53: </span> <span class="kwrd">public</span> <span class="kwrd">string</span> WaitMessage2</pre> <pre><span class="lnum"> 54: </span> {</pre> <pre><span class="lnum"> 55: </span> get</pre> <pre><span class="lnum"> 56: </span> {</pre> <pre><span class="lnum"> 57: </span> System.Threading.Thread.Sleep(2000);</pre> <pre><span class="lnum"> 58: </span> <span class="kwrd">return</span> <span class="str">"Loading...please wait"</span>;</pre> <pre><span class="lnum"> 59: </span> }</pre> <pre><span class="lnum"> 60: </span> }</pre> </div> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style><style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p>Il cui funzionamento è abbastanza semplice: secondo del nome dell’impiegato selezionato tramite la proprietà <em>EmployeeName</em> quando viene richiamato <em>Calculate() </em>viene eseguita una notifica di cambiamento tramite <em>OnPropertyChanged(“…”) </em>della proprietà <em>Salary </em>(Ci servirà nel codice XAML). Particolare attenzione  deve essere posta alle proprietà <em>WaitMessage1</em> e <em>WaitMessage2</em>, utilizzate nella UI per visualizzare due messaggi di attesa per l’utente: il primo subito, il secondo da visualizzare nel caso in cui l’operazione “di calcolo” si prolunghi oltre un certo tempo.</p> <p>Per testare il funzionamento della classe utilizziamo una Windows WPF molto semplice:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/WPFPriorityBinding_EDB4/image_2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/WPFPriorityBinding_EDB4/image_thumb.png" width="244" height="174" /></a> </p> <p>Il codice XAML associato alla controllo label in cui viene visualizzato il salario dell’impiegato (calcolato), e a cui è associato il PriorityBinding è il seguente:</p> <p> </p><div class="csharpcode"> <div class="csharpcode"> <pre><span class="lnum"> 1: </span><span class="kwrd">&lt;</span><span class="html">Label.Content</span><span class="kwrd">&gt;</span></pre> <pre><span class="lnum"> 2: </span> <span class="kwrd">&lt;</span><span class="html">PriorityBinding</span><span class="kwrd">&gt;</span></pre> <pre><span class="lnum"> 3: </span> <span class="kwrd">&lt;</span><span class="html">Binding</span> <span class="attr">Path</span><span class="kwrd">="Salary"</span> <span class="attr">Source</span><span class="kwrd">="{StaticResource es}"</span> <span class="attr">IsAsync</span><span class="kwrd">="True"</span> <span class="kwrd">/&gt;</span></pre> <pre><span class="lnum"> 4: </span> <span class="kwrd">&lt;</span><span class="html">Binding</span> <span class="attr">Path</span><span class="kwrd">="WaitMessage2"</span> <span class="attr">IsAsync</span><span class="kwrd">="True"</span> <span class="attr">Source</span><span class="kwrd">="{StaticResource es}"</span><span class="kwrd">/&gt;</span></pre> <pre><span class="lnum"> 5: </span> <span class="kwrd">&lt;</span><span class="html">Binding</span> <span class="attr">Path</span><span class="kwrd">="WaitMessage1"</span> <span class="attr">IsAsync</span><span class="kwrd">="False"</span> <span class="attr">Source</span><span class="kwrd">="{StaticResource es}"</span><span class="kwrd">/&gt;</span></pre> <pre><span class="lnum"> 6: </span> <span class="kwrd">&lt;/</span><span class="html">PriorityBinding</span><span class="kwrd">&gt;</span></pre> <pre><span class="lnum"> 7: </span><span class="kwrd">&lt;/</span><span class="html">Label.Content</span><span class="kwrd">&gt;</span></pre> </div> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style></div> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <p /> <p /> <p>Associamo i <em>Binding </em>nell’ordine in cui vogliamo vengano eseguiti: Salary, ritorna il valore dello stipendio secondo dell’impiegato specificato nel campo TextBox, <em>WaitMessage2</em> è il messaggio che dovrebbe essere visualizzato se l’operazione di calcolo necessità più di due secondi, <em>WaitMessage1 </em>è il primo messaggio da visualizzare non appena viene fatto click sul bottone <em>Calcola Stipendio</em>. Affinché tutto funzioni è necessario che la proprietà <em>IsAsync </em>del <em>Binding</em> sulle proprietà <em>Salary</em> e <em>WaitMessage2 </em>sia impostato su <em>True </em>altrimenti l’operazione attenderà il completamento dell’associazione prima di eseguire il prossimo (eventuale) <em>Binding </em>(perdendo i vantaggi del <em>PriorityBinding</em>)<em>.</em></p> <p>La risorsa statica <em>es, </em>è dichiarata a livello di Windows in questo modo: </p> <pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Window.Resources</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;</span><span class="html">local:Data</span> <span class="attr">x:Key</span><span class="kwrd">="es"</span><span class="kwrd">/&gt;</span> <span class="kwrd">&lt;/</span><span class="html">Window.Resources</span><span class="kwrd">&gt;</span></pre> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:1f531d89-8d61-4f7a-b3e2-6a89e10dbb9b" class="wlWriterEditableSmartContent">Technorati Tag: <a href="http://technorati.com/tags/WPF" rel="tag">WPF</a>,<a href="http://technorati.com/tags/PriorityBinding" rel="tag">PriorityBinding</a></div> <style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/98323.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2010/04/07/wpf-prioritybinding.aspx Wed, 07 Apr 2010 12:07:00 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2010/04/07/wpf-prioritybinding.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/98323.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/98323.aspx WPF: Control Template http://blogs.ugidotnet.org/PietroLibroBlog/archive/2008/11/06/wpf-control-template.aspx <p>In WPF, l'aspetto grafico di un controllo può essere cambiato utilizzando un C<em>ontrol Template</em>, ovvero un'insieme di risorse, triggers ed elementi che descrivono il comportamento grafico del controllo. I C<em>ontrol Template</em> sono utili ogni qual volta si vuole modificare l'aspetto grafico di un controllo, ma allo stesso tempo conservare le funzionalità del controllo stesso. Senza WPF, magari saremmo costretti a costruire un nuovo controllo replicando funzionalità e riscrivendo del codice funzionante. Supponiamo ad esempio di voler cambiare l'aspetto del solito controllo Button, rendendolo <em>fashion</em> e <em>trendy</em>. Quello che vogliamo ottenere è qualcosa del tipo:</p> <p> <a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/WPFControlTemplate_A54A/image_10.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="182" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/WPFControlTemplate_A54A/image_thumb_4.png" width="244" border="0" /></a> <a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/WPFControlTemplate_A54A/image_12.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="182" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/WPFControlTemplate_A54A/image_thumb_5.png" width="244" border="0" /></a> </p> <p>Nella seconda figura, è mostrato il comportamento del controllo Button quando il cursorse del mouse è posizionato sopra. </p> <p>Uno dei metodi più semplici per cambiare il <em>Template</em> del controllo è quello di scrivere il codice XAML di descrizione direttamente all'interno del tag <em>Button.Template, </em> ad esempio:</p> <div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:eca17d13-f288-46bd-8b4c-9fac319fb353" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Button </span><span style="color: #FF0000;">Height</span><span style="color: #0000FF;">="16"</span><span style="color: #FF0000;"> Margin</span><span style="color: #0000FF;">="51,0,42,12"</span><span style="color: #FF0000;"> Name</span><span style="color: #0000FF;">="button2"</span><span style="color: #FF0000;"> VerticalAlignment</span><span style="color: #0000FF;">="Bottom"</span><span style="color: #FF0000;"> Content</span><span style="color: #0000FF;">="Bottone"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">2</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Button.Template </span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">ControlTemplate</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Grid</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">5</span> <span style="color: #000000;"> </span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;"> codice XAML </span><span style="color: #008000;">--&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">6</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Grid</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">7</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">ControlTemplate</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">8</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Button.Template </span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">9</span> <span style="color: #000000;" /><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Button</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Volendo cambiare l'aspetto di tutti i controlli Button presenti in una Form WPF, andiamo ad utilizzare un oggetto <em>Style,</em> aggiungendolo  alla collezione delle risorse della Window WPF su cui stiamo lavorando:</p> <p> </p><div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:aa5d5659-fe7a-4021-9b3d-cf3ec0dedc25" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Window.Resources</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">2</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Style </span><span style="color: #FF0000;">TargetType</span><span style="color: #0000FF;">="Button"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Setter </span><span style="color: #FF0000;">Property</span><span style="color: #0000FF;">="Template"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">4</span> <span style="color: #000000;"> ... </span><span style="color: #008080;">5</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Setter</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">6</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Style</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">7</span> <span style="color: #000000;" /><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Window.Resources</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">8</span> <span style="color: #000000;" /></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Utilizzando una classe <em>Setter</em>, andiamo ad impostare la proprietà <em>Template</em> del generico controllo Button, aggiungendo in cascata, una <em>Grid</em>, un <em>Border</em> ed un <em>Rectangle. </em></p> <p> </p><div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:b64c89a7-4774-4dc6-913f-c1fc351dbc8c" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;"> 1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Grid</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 2</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Border </span><span style="color: #FF0000;">BorderBrush</span><span style="color: #0000FF;">="Aquamarine"</span><span style="color: #FF0000;"> BorderThickness</span><span style="color: #0000FF;">="1"</span><span style="color: #FF0000;"> Name</span><span style="color: #0000FF;">="borderButton"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Rectangle </span><span style="color: #FF0000;">Name</span><span style="color: #0000FF;">="sfondo"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Rectangle.Fill</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 5</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">LinearGradientBrush </span><span style="color: #FF0000;">StartPoint</span><span style="color: #0000FF;">="0,0"</span><span style="color: #FF0000;"> EndPoint</span><span style="color: #0000FF;">="1,0"</span><span style="color: #FF0000;"> Opacity</span><span style="color: #0000FF;">="1"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 6</span> <span style="color: #000000;"> ... </span><span style="color: #008080;"> 7</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">LinearGradientBrush</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 8</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Rectangle.Fill</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 9</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Rectangle</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">10</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Border</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">11</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">ContentPresenter </span><span style="color: #FF0000;">HorizontalAlignment</span><span style="color: #0000FF;">="Center"</span><span style="color: #FF0000;"> VerticalAlignment</span><span style="color: #0000FF;">="Center"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">12</span> <span style="color: #000000;" /><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Grid</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>E' importante spendere qualche parola su <em>ContentPresenter. ContentPresenter</em> serve a visualizzare il contenuto (in questo caso la semplice stringa "Button") di un <em>ContentControl</em> come ad esempio <em>Frame</em>, <em>ToolTip</em>, <em>Label</em>, <em>GroupItem,ButtonBase</em> etc...Se non utilizzassimo <em>ContentPresenter</em> durante la definizione del <em>Template</em> del nostro Button, in fase di Rendering, non verrebbe visualizzata nessuna dicitura sul nostro Button, semplicemente perchè non abbiamo detto a WPF dove vogliamo visualizzarla. Possiamo vedere il <em>ContentPresenter</em> come un segnaposto per indicare dove visualizzare il <em>Content</em>. Utilizzando una <em>Grid</em>, come in questo caso, ci assicuriamo che i vari oggetti siano tutti visualizzati in un'unica cella della griglia. Impostando <em>HorizontalAlignment </em>e <em>VerticalAlignment</em> su <em>Center, </em>ci assicuriamo di visualizzare il contenuto del controllo al centro.</p> <p>Per cambiare il <em>Background</em> del Button quando il cursorse del mouse viene posizionato sopra la superficie del controllo, come per <em>Style, </em>anche per <em>ControlTemplate </em>abbiamo a disposizione  i <em>Triggers </em>da sfruttare<em>:</em></p> <p> </p><div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:ff7f5467-2e26-4976-9460-4e4472baab91" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;"> 1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">ControlTemplate.Triggers</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 2</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Trigger </span><span style="color: #FF0000;">Property</span><span style="color: #0000FF;">="IsMouseOver"</span><span style="color: #FF0000;"> Value</span><span style="color: #0000FF;">="true"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Setter </span><span style="color: #FF0000;">TargetName</span><span style="color: #0000FF;">="sfondo"</span><span style="color: #FF0000;"> Property</span><span style="color: #0000FF;">="Fill"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 5</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">LinearGradientBrush </span><span style="color: #FF0000;">StartPoint</span><span style="color: #0000FF;">="0,0"</span><span style="color: #FF0000;"> EndPoint</span><span style="color: #0000FF;">="1,0"</span><span style="color: #FF0000;"> Opacity</span><span style="color: #0000FF;">="0.8"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 6</span> <span style="color: #000000;"> ... </span><span style="color: #008080;"> 7</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">LinearGradientBrush</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 8</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 9</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Setter</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">10</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Trigger</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">11</span> <span style="color: #000000;" /><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">ControlTemplate.Triggers</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Molto semplicemente, quando ci troviamo con il cursore del mouse sul Button, il <em>Trigger </em> cambia "il valore" (in verità l'oggetto <em>LinearGradientBrush</em>) della proprietà <em>Fill</em> dell'oggetto che ha la proprietà <em>Name</em> impostata su <em>Sfondo. </em>Nel procedente codice XAML, questo è <em>Rectangle, </em>posto all'interno dell'oggetto <em>Border</em> , di nome <em>borderButton</em>.</p> <p>Fino  a questo punto, abbiamo raggiunto il nostro primo obiettivo.  Supponiamo ora di voler aggiungere un'ulteriore funzione grafica al nostro controllo. Supponiamo di voler aggiungere un effetto luce diffusa <em>(Glow), </em>quando ci troviamo ad indicare il button con il mouse (sfruttando in pratica lo stesso <em>Trigger</em> per <em>IsMouseOver</em>)<em>. </em>A questo punto, niente di più facile, dato che l'oggetto <em>Border</em> espone una proprietà <em>BitmapEffect. S</em>crivendo del codice XAML simile a questo:</p> <p> </p><div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:f1af2575-ec9a-4772-8214-ae6290682f48" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Setter </span><span style="color: #FF0000;">TargetName</span><span style="color: #0000FF;">="borderButton"</span><span style="color: #FF0000;"> Property</span><span style="color: #0000FF;">="BitmapEffect"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">2</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Setter.Value </span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">OuterGlowBitmapEffect </span><span style="color: #FF0000;">GlowColor</span><span style="color: #0000FF;">="Yellow"</span><span style="color: #FF0000;"> GlowSize</span><span style="color: #0000FF;">="10"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">5</span> <span style="color: #000000;" /><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Setter</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Otterremo l'effetto desiderato:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/WPFControlTemplate_A54A/image_14.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="182" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/WPFControlTemplate_A54A/image_thumb_6.png" width="244" border="0" /></a> </p> <p>Personalmente penso che le potenzialità che il WPF offre per personalizzare l'aspetto dei controll sia veramente impressionante. Utilizzando <a href="http://www.microsoft.com/expression/products/Overview.aspx?key=blend" target="_blank">Expression Blend</a> si possono sviluppare delle applicazioni davvero accattivanti (soprattutto se si ha un pò di dimestichezza con la grafica :-))</p> <p><a href="http://www.pietrolibro.name/sources/ButtonTemplate.zip" target="_blank">Codice XAML completo della Window WPF</a></p> <div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:cf2f1324-80a6-4636-94b5-3f2f3158efa1" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tag: <a href="http://technorati.com/tags/WPF" rel="tag">WPF</a>,<a href="http://technorati.com/tags/ControlTemplate" rel="tag">ControlTemplate</a></div><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/94536.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2008/11/06/wpf-control-template.aspx Thu, 06 Nov 2008 14:05:03 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2008/11/06/wpf-control-template.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/94536.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/94536.aspx WPF: Style, Trigger e Multitrigger http://blogs.ugidotnet.org/PietroLibroBlog/archive/2008/09/17/94063.aspx <p>Supponiamo di avere una Window WPF, contentente un singolo controllo TextBox. Vogliamo, senza utilizzare il <em>code-behind</em>, che a secondo del contenuto del TextBox, questo cambi il colore di background. Nello specifico, se nel TextBox c'è scritto "SI", il Background deve essere Verde, se c'è scritto "NO" rosso. Piccola prefazione: uno <em>Style, </em>è<em> </em>generalmente<em> </em>un'insieme di proprietà che applicato ad un'insieme di contenuti quali testi o immagini, ne determina l'aspetto grafico. Parlando di <em>Style</em>, in WPF, questo non è solo un semplice insieme di proprietà, dato che, include comportamenti specifici come la possibilità di cambiare l'aspetto di un controllo basandosi sugli eventi dell'utente, utilizzando gli <em>event trigger</em>. Per lo scopo del post, utilizzeremo invece dei <em>Property Triggers</em>, ovvero dei <em>Trigger</em>, che "osservano" una particolare <em>Dependency Property </em>per verificare se assume un certo valore. Nel caso in cui, il valore "osservato" sia quello atteso, si può impostare una qualche proprietà del  controllo <em>Target</em>, ad esempio il Background o il testo del ToolTip. </p> <p>Aggiungiamo il codice del nostro <em>Style</em> personalizzato alla collezione delle risorse presenti nella Window:</p> <p></p> <div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:ebb14797-4d59-4a31-bbc3-f5c2205fed24" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;"> 1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Style </span><span style="color: #FF0000;">x:Key</span><span style="color: #0000FF;">="CustomTextBoxStyle"</span><span style="color: #FF0000;"> TargetType</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{x:Type TextBox}</span><span style="color: #0000FF;">"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 2</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Style.Triggers</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Trigger </span><span style="color: #FF0000;">Property</span><span style="color: #0000FF;">="Text"</span><span style="color: #FF0000;"> Value</span><span style="color: #0000FF;">="SI"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Setter </span><span style="color: #FF0000;">Property</span><span style="color: #0000FF;">="Background"</span><span style="color: #FF0000;"> Value</span><span style="color: #0000FF;">="Green"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 5</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Setter </span><span style="color: #FF0000;">Property</span><span style="color: #0000FF;">="ToolTip"</span><span style="color: #FF0000;"> Value</span><span style="color: #0000FF;">="Il valore SI è corretto"</span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 6</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Trigger</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 7</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Trigger </span><span style="color: #FF0000;">Property</span><span style="color: #0000FF;">="Text"</span><span style="color: #FF0000;"> Value</span><span style="color: #0000FF;">="NO"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 8</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Setter </span><span style="color: #FF0000;">Property</span><span style="color: #0000FF;">="Background"</span><span style="color: #FF0000;"> Value</span><span style="color: #0000FF;">="Red"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 9</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Trigger</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">10</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Style.Triggers</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">11</span> <span style="color: #000000;"></span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Style</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p>Il codice su esposto è relativamente semplice: in entrambi i <em>trigger</em> andiamo a monitorare la proprietà Text del controllo TextBox. Se questo assume il valore "SI" (<em>case-sensitive</em>), impostiamo  la proprietà Background del controllo su Green ed il testo da visualizzare con il ToolTip. Se invece Text è uguale a "NO" allora impostiamo il colore di Background su Red.</p> <p>Il codice XAML della Window è il seguente:</p> <div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:94b901f6-668b-436b-8cfc-9cc28f93abcb" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #000000;"> [...] </span><span style="color: #008080;">2</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Grid</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Grid.RowDefinitions</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">RowDefinition </span><span style="color: #FF0000;">Height</span><span style="color: #0000FF;">="117*"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">5</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">RowDefinition </span><span style="color: #FF0000;">Height</span><span style="color: #0000FF;">="145*"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">6</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Grid.RowDefinitions</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">7</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">TextBox </span><span style="color: #FF0000;">Margin</span><span style="color: #0000FF;">="66,48,77,30"</span><span style="color: #FF0000;"> Name</span><span style="color: #0000FF;">="textBox1"</span><span style="color: #FF0000;"> Style</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{StaticResource CustomTextBoxStyle}</span><span style="color: #0000FF;">"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">8</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Grid</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">9</span> <span style="color: #000000;"></span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Window</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Supponiamo invece, di voler cambiare il valore del Background sul Giallo, quando si verificano più condizioni contemporaneamente, ad esempio quando il controllo TextBox ha il Focus e non contiene Testo. Per questo scopo utilizziamo invece un <em>MultiTrigger</em>:</p> <div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:6ba62c21-e0ae-463c-a56f-24d630e57852" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">MultiTrigger</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">2</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">MultiTrigger.Conditions</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Condition </span><span style="color: #FF0000;">Property</span><span style="color: #0000FF;">="Text"</span><span style="color: #FF0000;"> Value</span><span style="color: #0000FF;">=""</span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Condition </span><span style="color: #FF0000;">Property</span><span style="color: #0000FF;">="IsFocused"</span><span style="color: #FF0000;"> Value</span><span style="color: #0000FF;">="True"</span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">5</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">MultiTrigger.Conditions</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">6</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Setter </span><span style="color: #FF0000;">Property</span><span style="color: #0000FF;">="Background"</span><span style="color: #FF0000;"> Value</span><span style="color: #0000FF;">="Yellow"</span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">7</span> <span style="color: #000000;"></span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">MultiTrigger</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p><a href="http://www.pietrolibro.name/Download/triggerwindows.zip" target="_blank">Codice XAML completo della Window WPF</a>.</p> <div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4eddd76a-2baf-4f79-a9ce-f37705c9f2f7" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tag: <a href="http://technorati.com/tags/WPF" rel="tag">WPF</a>,<a href="http://technorati.com/tags/Style" rel="tag">Style</a>,<a href="http://technorati.com/tags/Property%20Trigger" rel="tag">Property Trigger</a>,<a href="http://technorati.com/tags/MultiTrigger" rel="tag">MultiTrigger</a></div><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/94063.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2008/09/17/94063.aspx Wed, 17 Sep 2008 12:15:21 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2008/09/17/94063.aspx#feedback http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/94063.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/94063.aspx WPF: XmlDataProvider http://blogs.ugidotnet.org/PietroLibroBlog/archive/2008/08/31/93879.aspx <p>Supponiamo di avere un file XML molto semplice, del tipo:</p> <p></p> <p></p> <div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:a18fa1a2-3247-44bb-ba33-37df94bca613" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;"> 1</span> <span style="color: #0000FF;">&lt;?</span><span style="color: #FF00FF;">xml version="1.0" encoding="utf-8" </span><span style="color: #0000FF;">?&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 2</span> <span style="color: #000000;"></span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">books</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">book </span><span style="color: #FF0000;">id</span><span style="color: #0000FF;">="1"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">title</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">Introducing To Microsoft LINQ</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">title</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 5</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">isbn</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">43554354523</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">isbn</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 6</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">book</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 7</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">book </span><span style="color: #FF0000;">id</span><span style="color: #0000FF;">="2"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 8</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">title</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">Pro WPF Windows Presentation Foundation in dot NET 3.0</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">title</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 9</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">isbn</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">232132142</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">isbn</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">10</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">book</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">11</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">book </span><span style="color: #FF0000;">id</span><span style="color: #0000FF;">="3"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">12</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">title</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">Foundations of F#</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">title</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">13</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">isbn</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">772337271</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">isbn</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">14</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">book</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">15</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">book </span><span style="color: #FF0000;">id</span><span style="color: #0000FF;">="4"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">16</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">title</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">Algorithms In Bioinformatics</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">title</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">17</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">isbn</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">12345678</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">isbn</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">18</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">book</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">19</span> <span style="color: #000000;"></span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">books</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p>Vogliamo mostrare il contenuto del documento XML in un controllo WPF ListView o ListBox. Per effettuare il <em>binding</em> con i dati XML, WPF mette a disposizione degli sviluppatori la classe <em>XmlDataProvider</em>, la quale permette d'impostare in modo  rapido e semplice  l'uso di elementi XML come <em>binding source</em> per i controlli delle nostre applicazioni. Trattando nell'esempio un'applicazione WPF Windows Form, nel dizionario delle risorse della Window, aggiungiamo un'istanza della classe <em>XmlDataProvider</em>, specificando la chiave (<em>key</em>) d'identificazione all'interno della collezione, il <em>Source</em>, ovvero il percorso del file XML contenente i dati e l'espressione <em>XPath</em> da utilizzare per il recupero dei nodi interessati.</p> <p></p> <p></p> <div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:378f4c35-0139-46e8-8cbb-914951cbe95f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; width: 618px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Window.Resources</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">2</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">XmlDataProvider </span><span style="color: #FF0000;">x:Key</span><span style="color: #0000FF;">="BooksProvider"</span><span style="color: #FF0000;"> Source</span><span style="color: #0000FF;">="Data.xml"</span><span style="color: #FF0000;"> XPath</span><span style="color: #0000FF;">="./books/book"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Window.Resources</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <p>Per visualizzare i dati in un ListView, nel codice XAML possiamo scrivere:</p> <div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:aeba3ce7-424f-40d8-9bb4-d7e215fff005" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;"> 1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">ListView </span><span style="color: #FF0000;">Margin</span><span style="color: #0000FF;">="12,45,12,117"</span><span style="color: #FF0000;"> Name</span><span style="color: #0000FF;">="listView1"</span><span style="color: #FF0000;"> DataContext</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{StaticResource BooksProvider}</span><span style="color: #0000FF;">"</span><span style="color: #FF0000;"> ItemsSource</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{Binding}</span><span style="color: #0000FF;">"</span><span style="color: #FF0000;"> </span><span style="color: #008080;"> 2</span> <span style="color: #FF0000;"> SelectionChanged</span><span style="color: #0000FF;">="listView1_SelectionChanged"</span><span style="color: #FF0000;"> MouseDoubleClick</span><span style="color: #0000FF;">="listView1_MouseDoubleClick"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">ListView.View </span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">GridView</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 5</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">GridViewColumn </span><span style="color: #FF0000;">Header</span><span style="color: #0000FF;">="ID"</span><span style="color: #FF0000;"> Width</span><span style="color: #0000FF;">="50"</span><span style="color: #FF0000;"> DisplayMemberBinding</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{Binding XPath=@id}</span><span style="color: #0000FF;">"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">GridViewColumn</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 6</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">GridViewColumn </span><span style="color: #FF0000;">Header</span><span style="color: #0000FF;">="Title"</span><span style="color: #FF0000;"> Width</span><span style="color: #0000FF;">="250"</span><span style="color: #FF0000;"> DisplayMemberBinding</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{Binding XPath=title}</span><span style="color: #0000FF;">"</span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">GridViewColumn</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 7</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">GridViewColumn </span><span style="color: #FF0000;">Header</span><span style="color: #0000FF;">="ISBN"</span><span style="color: #FF0000;"> Width</span><span style="color: #0000FF;">="150"</span><span style="color: #FF0000;"> DisplayMemberBinding</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{Binding XPath=isbn}</span><span style="color: #0000FF;">"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 8</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">GridViewColumn</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 9</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">GridView</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">10</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">ListView.View</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">11</span> <span style="color: #000000;"></span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">ListView</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Notiamo come la proprietà <em>DataContext</em> del ListView sia impostata sull'istanza del <em>XmlDataProvider </em>dichiarata nelle risorse,e per il <em>binding</em>, invece di utilizzare la proprietà <em>Path</em>, andiamo ad utilizzare la proprietà <em>XPath</em>, anteponendo in caso di attributi, il carattere @.</p> <p>Se invece di utilizzare un controllo ListView, volessimo presentare i dati utilizzando un ListBox, il codice XAML da scrivere potrebbe essere simile al seguente:</p> <div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:a659709b-7575-429f-9862-b7f255083265" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;"> 1</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">ListBox </span><span style="color: #FF0000;">Margin</span><span style="color: #0000FF;">="12,0,12,25"</span><span style="color: #FF0000;"> Name</span><span style="color: #0000FF;">="listBox1"</span><span style="color: #FF0000;"> DataContext</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{StaticResource BooksProvider}</span><span style="color: #0000FF;">"</span><span style="color: #FF0000;"> </span><span style="color: #008080;"> 2</span> <span style="color: #FF0000;"> ItemsSource</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{Binding}</span><span style="color: #0000FF;">"</span><span style="color: #FF0000;"> Height</span><span style="color: #0000FF;">="76"</span><span style="color: #FF0000;"> VerticalAlignment</span><span style="color: #0000FF;">="Bottom"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">ListBox.ItemTemplate</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">DataTemplate </span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 5</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">StackPanel </span><span style="color: #FF0000;">Orientation</span><span style="color: #0000FF;">="Horizontal"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 6</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">TextBlock </span><span style="color: #FF0000;">Text</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{Binding XPath=@id}</span><span style="color: #0000FF;">"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> - </span><span style="color: #008080;"> 7</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">TextBlock </span><span style="color: #FF0000;">Text</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{Binding XPath=title}</span><span style="color: #0000FF;">"</span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">TextBlock</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 8</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">TextBlock</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 9</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">StackPanel</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">10</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">DataTemplate</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">11</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">ListBox.ItemTemplate</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">12</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">ListBox</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Nel caso in cui volessimo associare del codice sull'evento Double-Click del ListView per ottenere informazioni sul nodo correttamente selezionato, come suggerito da <a href="http://blogs.ugidotnet.org/spaccabit/Default.aspx" target="_blank">Giuseppe Lippolis</a>, possiamo scrivere nel codice XAML:</p> <p> </p><div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:80b32c74-29d8-4e61-b308-643f52f76ef4" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">ListView </span><span style="color: #FF0000;">Margin</span><span style="color: #0000FF;">="12,45,12,117"</span><span style="color: #FF0000;"> Name</span><span style="color: #0000FF;">="listView1"</span><span style="color: #FF0000;"> DataContext</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{StaticResource BooksProvider}</span><span style="color: #0000FF;">"</span><span style="color: #FF0000;"> ItemsSource</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{Binding}</span><span style="color: #0000FF;">"</span><span style="color: #FF0000;"> ListViewItem.MouseDoubleClick</span><span style="color: #0000FF;">="Item_MouseDoubleClick"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">2</span> <span style="color: #000000;">.... </span><span style="color: #008080;">3</span> <span style="color: #000000;"></span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">ListView </span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Nel code-behind:</p> <div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:d3891af4-796c-4cf0-82e5-507b04a1b314" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> Item_MouseDoubleClick(</span><span style="color: #0000FF;">object</span><span style="color: #000000;"> sender, MouseButtonEventArgs e) </span><span style="color: #008080;">2</span> <span style="color: #000000;">{ </span><span style="color: #008080;">3</span> <span style="color: #000000;">ListView lsv </span><span style="color: #000000;">=</span><span style="color: #000000;"> (ListView)e.Source; </span><span style="color: #008080;">4</span> <span style="color: #000000;">XmlElement book </span><span style="color: #000000;">=</span><span style="color: #000000;"> (XmlElement)lsv.SelectedItem; </span><span style="color: #008080;">5</span> <span style="color: #000000;"></span><span style="color: #0000FF;">string</span><span style="color: #000000;"> message </span><span style="color: #000000;">=</span><span style="color: #000000;"> String.Format(</span><span style="color: #800000;">"</span><span style="color: #800000;">Double Click: {0} - {1} - {2}</span><span style="color: #800000;">"</span><span style="color: #000000;">, </span><span style="color: #008080;">6</span> <span style="color: #000000;">book.GetAttribute(</span><span style="color: #800000;">"</span><span style="color: #800000;">id</span><span style="color: #800000;">"</span><span style="color: #000000;">), book[</span><span style="color: #800000;">"</span><span style="color: #800000;">title</span><span style="color: #800000;">"</span><span style="color: #000000;">].InnerText, </span><span style="color: #008080;">7</span> <span style="color: #000000;">book[</span><span style="color: #800000;">"</span><span style="color: #800000;">isbn</span><span style="color: #800000;">"</span><span style="color: #000000;">].InnerText); </span><span style="color: #008080;">8</span> <span style="color: #000000;">MessageBox.Show(message); </span><span style="color: #008080;">9</span> <span style="color: #000000;">} </span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p></p> <div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:97214b3a-f98d-400b-b5a3-9162bbfc6ac0" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tag: <a href="http://technorati.com/tags/WPF" rel="tag">WPF</a>,<a href="http://technorati.com/tags/XmlDataProvider" rel="tag">XmlDataProvider</a></div><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/93879.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2008/08/31/93879.aspx Sun, 31 Aug 2008 12:43:11 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2008/08/31/93879.aspx#feedback 2 http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/93879.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/93879.aspx WPF + LINQ + CollectionViewSource = Rss Reader http://blogs.ugidotnet.org/PietroLibroBlog/archive/2008/08/27/93837.aspx <p>Questo post è nato con uno scopo diverso da quello dell'implementazione di un Rss Reader, dato che, è sufficiente cercare su internet per trovarne di belli e pronti, ma per enfatizzare alcune proprietà molto interessanti dei controlli WPF, come  la possibilità di eseguire il raggruppamento dei dati nei controlli ListBox o ListView. Piccola parentesi: per chi volesse conoscere in dettaglio le specifiche RSS 2.0 le può trovare <a href="http://www.rssboard.org/rss-specification" target="_blank">qui</a>. Iniziamo sviluppando un <em>set </em>di classi come riassunto dal seguente <em>Class Diagram</em>:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/WPFLINQCollectionViewSourceRssReader_E870/image_2.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/WPFLINQCollectionViewSourceRssReader_E870/image_thumb.png" width="235" border="0" /></a> </p> <p>Nel resto dell'esempio saranno prese in considerazione solo istanze di tipo Rss e RssItem. Generalmente, senza considerare gli elementi opzionali, la struttura xml di un documento RSS è il seguente:</p> <div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:e5c0d61e-f7e6-4957-92be-0adb2300c1d9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;"> 1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">rss </span><span style="color: #FF0000;">version</span><span style="color: #0000FF;">="2.0"</span><span style="color: #FF0000;"> xmlns:dc</span><span style="color: #0000FF;">="http://purl.org/dc/elements/1.1/"</span><span style="color: #FF0000;"> ... </span><span style="color: #008080;"> 2</span> <span style="color: #FF0000;"> &lt;channel</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">title</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">Il blog di Pietro Libro</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">title</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">link</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">http://blogs.ugidotnet.org/PietroLibroBlog/Default.aspx</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">link</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 5</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">description </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 6</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">language</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">it-IT</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">language</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 7</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">copyright</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">Pietro Libro</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">copyright</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 8</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">managingEditor</span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">managingEditor</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 9</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">generator</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">Subtext Version 1.9.5.176</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">generator</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">10</span> <span style="color: #000000;"> ... </span><span style="color: #008080;">11</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">item</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">12</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">title</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">Adeona, il software </span><span style="color: #FF0000;">&amp;amp;</span><span style="color: #000000;">quot;salva</span><span style="color: #FF0000;">&amp;amp;</span><span style="color: #000000;">quot; notebook</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">title</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">13</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">category</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">OT</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">category</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">14</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">category</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">Varie ed eventuali</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">category</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">15</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">link</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">http://blogs.ugidotnet.org/PietroLibroBlog/archive/2008/08/26/93820.aspx</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">link</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">16</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">description</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">...</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">description</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">17</span> <span style="color: #000000;"> .... </span><span style="color: #008080;">18</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">item</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Per leggere un tale documento, utilizziamo un'istanza della classe <em>XDocument</em>, presente nel namespace <em>System.Xml.Linq</em>, contenente metodi che permettono la navigazione dei nodi del documento in maniera molto semplice. Se a questo aggiungiamo la potenza di Linq, veramente c'è poco da dire. Prima di tutto creiamo un'istanza  di <em>XDocument</em> e leggiamo il documento passando direttamente l'uri del fornitore del feed RSS:</p> <p> </p><div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:f84a27f6-7338-4fe1-b674-d2d06bfa73a2" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #000000;">XDocument xDocument </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> XDocument(); </span><span style="color: #008080;">2</span> <span style="color: #000000;">xDocument </span><span style="color: #000000;">=</span><span style="color: #000000;"> XDocument.Load(blogUri);</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Per recuperare tutti gli elementi <em>item</em> contenuti nel documento, utilizziamo Linq. Per far questo utilizziamo il metodo <em>Descendants </em>passando come parametro la stringa "Item":</p> <p> </p><div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:e28f058d-2c78-41b2-9a13-8972c4f3e69e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #000000;">_items </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #008080;">2</span> <span style="color: #000000;"> (from item </span><span style="color: #0000FF;">in</span><span style="color: #000000;"> xDocument.Descendants(</span><span style="color: #800000;">"</span><span style="color: #800000;">item</span><span style="color: #800000;">"</span><span style="color: #000000;">) </span><span style="color: #008080;">3</span> <span style="color: #000000;"> select </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> RssItem </span><span style="color: #008080;">4</span> <span style="color: #000000;"> { </span><span style="color: #008080;">5</span> <span style="color: #000000;"> Title </span><span style="color: #000000;">=</span><span style="color: #000000;"> item.Element(</span><span style="color: #800000;">"</span><span style="color: #800000;">title</span><span style="color: #800000;">"</span><span style="color: #000000;">).Value, </span><span style="color: #008080;">6</span> <span style="color: #000000;"> Description </span><span style="color: #000000;">=</span><span style="color: #000000;">item.Element (</span><span style="color: #800000;">"</span><span style="color: #800000;">description</span><span style="color: #800000;">"</span><span style="color: #000000;">).Value, </span><span style="color: #008080;">7</span> <span style="color: #000000;"> Category </span><span style="color: #000000;">=</span><span style="color: #000000;"> item.Element(</span><span style="color: #800000;">"</span><span style="color: #800000;">category</span><span style="color: #800000;">"</span><span style="color: #000000;">) </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #0000FF;">null</span><span style="color: #000000;"> </span><span style="color: #000000;">?</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">Nessuna Categoria</span><span style="color: #800000;">"</span><span style="color: #000000;"> : item.Element(</span><span style="color: #800000;">"</span><span style="color: #800000;">category</span><span style="color: #800000;">"</span><span style="color: #000000;">).Value , </span><span style="color: #008080;">8</span> <span style="color: #000000;"> Link </span><span style="color: #000000;">=</span><span style="color: #000000;"> item.Element(</span><span style="color: #800000;">"</span><span style="color: #800000;">link</span><span style="color: #800000;">"</span><span style="color: #000000;">) </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #0000FF;">null</span><span style="color: #000000;"> </span><span style="color: #000000;">?</span><span style="color: #000000;"> </span><span style="color: #800000;">""</span><span style="color: #000000;">: item.Element(</span><span style="color: #800000;">"</span><span style="color: #800000;">link</span><span style="color: #800000;">"</span><span style="color: #000000;">).Value </span><span style="color: #008080;">9</span> <span style="color: #000000;"> }).ToList</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">RssItem</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">();</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p> <em>_items </em>è una lista tipizzata di oggetti <em>RssItem</em>.</p> <p>Per presentare i dati recuperati  utilizziamo una Window WPF. Il nostro obiettivo è mostrare i dati raggruppati per categoria, ovvero ottenere qualcosa del tipo:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/WPFLINQCollectionViewSourceRssReader_E870/image_4.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="168" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/PietroLibroBlog/WindowsLiveWriter/WPFLINQCollectionViewSourceRssReader_E870/image_thumb_1.png" width="244" border="0" /></a> </p> <p>Per raggiungere il <em>goal</em>,  invece di utilizzare la proprietà <em>ItemSource</em> esposta dal controllo ListBox, utilizziamo un'istanza di oggetto di tipo <em>CollectionViewSource </em>la quale altro non è una che un Proxy della classe <em>CollectionView</em>.<em> </em>Quest'ultima permette di eseguire operazioni di raggruppamento, ordinamento, navigazione e ricerca su di una collezione di dati. Definiamo un'istanza di tipo <em>CollectionViewSource</em> nella collezione <em>Window.Resources</em> della nostra Window WPF:</p> <p> </p><div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:7fc65c71-8203-4310-b845-81716ee5bc04" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">CollectionViewSource </span><span style="color: #FF0000;">x:Key</span><span style="color: #0000FF;">="cvs"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">2</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">CollectionViewSource.GroupDescriptions</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">PropertyGroupDescription </span><span style="color: #FF0000;">PropertyName</span><span style="color: #0000FF;">="Category"</span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">CollectionViewSource.GroupDescriptions</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">5</span> <span style="color: #000000;"></span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">CollectionViewSource</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Così facendo, aggiungiamo alla collezione <em>GroupDescriptions</em> un oggetto di tipo <em>GroupDescription</em> che descrive il criterio in base al quale i  dati devono essere raggruppati nella vista, nello specifico in base al valore della proprietà <em>Category. </em></p> <p>Tramite codice XAML, andiamo a descrivere come devono essere visualizzati i nostri Gruppi:</p> <div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:d8dcf354-87c3-490b-b315-961b34bd8f4a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;"> 1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Style </span><span style="color: #FF0000;">x:Key</span><span style="color: #0000FF;">="CustomGroupStyle"</span><span style="color: #FF0000;"> TargetType</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{x:Type GroupItem}</span><span style="color: #0000FF;">"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 2</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Setter </span><span style="color: #FF0000;">Property</span><span style="color: #0000FF;">="Margin"</span><span style="color: #FF0000;"> Value</span><span style="color: #0000FF;">="0,0,0,5"</span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Setter </span><span style="color: #FF0000;">Property</span><span style="color: #0000FF;">="Template"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 5</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">ControlTemplate </span><span style="color: #FF0000;">TargetType</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{x:Type GroupItem}</span><span style="color: #0000FF;">"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 6</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Expander </span><span style="color: #FF0000;">IsExpanded</span><span style="color: #0000FF;">="False"</span><span style="color: #FF0000;"> BorderBrush</span><span style="color: #0000FF;">="#FFA4B97F"</span><span style="color: #FF0000;"> BorderThickness</span><span style="color: #0000FF;">="0,0,0,1"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 7</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Expander.Header</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 8</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">DockPanel</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;"> 9</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">TextBlock </span><span style="color: #FF0000;">FontWeight</span><span style="color: #0000FF;">="Bold"</span><span style="color: #FF0000;"> Text</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{Binding Path=Name}</span><span style="color: #0000FF;">"</span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">10</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">TextBlock </span><span style="color: #FF0000;">FontWeight</span><span style="color: #0000FF;">="Bold"</span><span style="color: #FF0000;"> Text</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{Binding Path=ItemCount, </span><span style="color: #008080;">11</span> <span style="color: #808000;"> Converter={StaticResource CustomConverter}, </span><span style="color: #008080;">12</span> <span style="color: #808000;"> ConverterParameter=' - Numero di post ({0}) '}</span><span style="color: #0000FF;">"</span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">13</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">DockPanel</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">14</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Expander.Header</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">15</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Expander.Content</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">16</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">ItemsPresenter </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">17</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Expander.Content</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">18</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Expander</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">19</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">ControlTemplate</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">20</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">21</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Setter</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">22</span> <span style="color: #000000;"></span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Style</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>E gli elementi in essi contenuti:</p> <div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:9fc85a15-059e-450d-a289-885b0f87b352" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">DataTemplate </span><span style="color: #FF0000;">x:Key</span><span style="color: #0000FF;">="ItemTemplate"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">2</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">StackPanel</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">TextBlock </span><span style="color: #FF0000;">Text</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{Binding Path=Title}</span><span style="color: #0000FF;">"</span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">TextBlock</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">TextBlock</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">5</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Hyperlink </span><span style="color: #FF0000;">NavigateUri</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{Binding Path=Link}</span><span style="color: #0000FF;">"</span><span style="color: #FF0000;"> Click</span><span style="color: #0000FF;">="Hyperlink_Click"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">Visualizza</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Hyperlink</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">6</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">TextBlock</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">7</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">StackPanel</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">8</span> <span style="color: #000000;"></span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">DataTemplate</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Non resta che definire il controllo ListBox:</p> <p> </p><div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:006c92bc-bc95-4c9a-8509-9c5021363426" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #0000FF;">&lt;</span><span style="color: #800000;">ListBox </span><span style="color: #FF0000;">Name</span><span style="color: #0000FF;">="lstBox"</span><span style="color: #FF0000;"> ItemTemplate</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{StaticResource ItemTemplate}</span><span style="color: #0000FF;">"</span><span style="color: #FF0000;"> Margin</span><span style="color: #0000FF;">="12,41,12,12"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">2</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">ListBox.GroupStyle</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">3</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">GroupStyle </span><span style="color: #FF0000;">ContainerStyle</span><span style="color: #0000FF;">="</span><span style="color: #808000;">{StaticResource CustomGroupStyle}</span><span style="color: #0000FF;">"</span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">4</span> <span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">ListBox.GroupStyle</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #008080;">5</span> <span style="color: #000000;"></span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">ListBox</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Utilizzando un controllo Button per recuperare il contenuto del documento RSS, scriviamo il seguente codice C#:</p> <p> </p><div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:8ac5a0ee-ef6e-4cac-9501-a2d6b091fd75" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:White;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"><div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --><span style="color: #008080;">1</span> <span style="color: #000000;">LinqRss.Rss rss </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> LinqRss.Rss(); </span><span style="color: #008080;">2</span> <span style="color: #000000;"></span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (rss.Load(</span><span style="color: #800000;">"</span><span style="color: #800000;">http://blogs.ugidotnet.org/PietroLibroBlog/Rss.aspx</span><span style="color: #800000;">"</span><span style="color: #000000;">)) </span><span style="color: #008080;">3</span> <span style="color: #000000;">{ </span><span style="color: #008080;">4</span> <span style="color: #000000;"> CollectionViewSource collectionViewSource </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.FindResource(</span><span style="color: #800000;">"</span><span style="color: #800000;">cvs</span><span style="color: #800000;">"</span><span style="color: #000000;">) </span><span style="color: #0000FF;">as</span><span style="color: #000000;"> CollectionViewSource ; </span><span style="color: #008080;">5</span> <span style="color: #000000;"> collectionViewSource.Source </span><span style="color: #000000;">=</span><span style="color: #000000;"> rss.Items; </span><span style="color: #008080;">6</span> <span style="color: #000000;"> lstBox.ItemsSource </span><span style="color: #000000;">=</span><span style="color: #000000;"> collectionViewSource.View; </span><span style="color: #008080;">7</span> <span style="color: #000000;">}</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>In sintesi, recuperata l'istanza di <em>CollectionViewSource </em>contenuta nelle risorse della nostra Window WPF,  impostiamo la proprietà <em>Source</em> dell'oggetto <em>CollectionViewSource</em> utilizzando la collezione <em>Items</em> esposta dall'istanza <em>Rss</em>. Non resta che impostare la proprietà <em>ItemSource</em> del controllo ListBox con la proprietà <em>View</em> esposta da <em>CollectionViewSource</em>. Osservazione: i <em>GroupItem</em> sono costituiti da controlli <em>Expander. </em>Nell'I<em>temTemplate</em> è presente anche un <em>HyperLink</em> che permette la navigazione verso il post d'interesse.</p> <p><a href="http://www.pietrolibro.name/sources/LinqWpfRssReader.zip" target="_blank">Codice C# e XAML</a></p> <div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:902c7c58-3a46-42dd-a906-877a496df2f1" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tag: <a href="http://technorati.com/tags/CollectionViewSource" rel="tag">CollectionViewSource</a></div><img src="http://blogs.ugidotnet.org/PietroLibroBlog/aggbug/93837.aspx" width="1" height="1" /> Pietro Libro http://blogs.ugidotnet.org/PietroLibroBlog/archive/2008/08/27/93837.aspx Wed, 27 Aug 2008 14:30:58 GMT http://blogs.ugidotnet.org/PietroLibroBlog/archive/2008/08/27/93837.aspx#feedback 9 http://blogs.ugidotnet.org/PietroLibroBlog/comments/commentRss/93837.aspx http://blogs.ugidotnet.org/PietroLibroBlog/services/trackbacks/93837.aspx