.NET http://blogs.ugidotnet.org/bmatte/category/.NET.aspx .NET it-IT Matteo Baglini Subtext Version 2.6.0.0 Microsoft Community Tour: adesso tocca alla Toscana! http://blogs.ugidotnet.org/bmatte/archive/2010/01/07/microsoft-community-tour-adesso-tocca-alla-toscana.aspx <p> </p> <p><img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://dotnettoscana.org/cfs-filesystemfile.ashx/__key/CommunityServer.Components.SiteFiles/JL_2D00_Prod_2D00_Prod_2D00_Ban_5F00_728x90.gif" /> </p> <p> </p> <p>Oggi molti di voi saranno rientrati dalle ferie, quindi ne approfitto per ricordare che Martedì 12 Gennaio si terrà a Navacchio (PI) la tappa Toscana del <a href="http://www.microsoft.com/italy/lancio09/community.aspx" target="_blank">Community Tour</a>.</p> <p>L’evento è interamente dedicato allo <strong>Sviluppo Web</strong>, se volete registrarvi o ricevere maggiori informazioni su sessioni e location, visitate l’apposita <a href="http://dotnettoscana.org/content/MicrosoftCommunityTour2009.aspx" target="_blank">pagina dell’evento</a> sul nostro sito.</p> <p>Vi aspettiamo!!</p> <p> </p> <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:d0ebb833-689e-4208-a4f4-8243337cc910" class="wlWriterEditableSmartContent">Technorati Tag: <a href="http://technorati.com/tags/Community+Tour" rel="tag">Community Tour</a>,<a href="http://technorati.com/tags/DotNetToscana" rel="tag">DotNetToscana</a>,<a href="http://technorati.com/tags/Eventi" rel="tag">Eventi</a></div><img src="http://blogs.ugidotnet.org/bmatte/aggbug/97816.aspx" width="1" height="1" /> Matteo Baglini http://blogs.ugidotnet.org/bmatte/archive/2010/01/07/microsoft-community-tour-adesso-tocca-alla-toscana.aspx Thu, 07 Jan 2010 17:43:28 GMT http://blogs.ugidotnet.org/bmatte/archive/2010/01/07/microsoft-community-tour-adesso-tocca-alla-toscana.aspx#feedback http://blogs.ugidotnet.org/bmatte/comments/commentRss/97816.aspx http://blogs.ugidotnet.org/bmatte/services/trackbacks/97816.aspx WPF Functional Testing With White http://blogs.ugidotnet.org/bmatte/archive/2008/12/18/wpf-functional-testing-with-white.aspx <p>(@ <a href="http://blogs.ugidotnet.org/dsantarelli" target="_blank">Dario</a>: accetto la sfida!!! <img alt="smile_teeth" src="http://spaces.live.com/rte/emoticons/smile_teeth.gif" /> )</p> <p>Nel mio <a href="http://blogs.ugidotnet.org/bmatte/archive/2008/12/16/wpf-ui-test-framework.aspx" target="_blank">ultimo post</a> ho annunciato il rilascio di un framework per effettuare test funzionali per applicazioni desktop in maniera del tutto automatica. <a href="http://blogs.ugidotnet.org/dsantarelli" target="_blank">Dario</a> ha accettato la mia <a href="http://blogs.ugidotnet.org/bmatte/archive/2008/12/16/wpf-ui-test-framework.aspx#1405390" target="_blank">richiesta</a> rispondendo con un bel <a href="http://blogs.ugidotnet.org/dsantarelli/archive/2008/12/17/testapi-e-input-injection.aspx" target="_blank">post su TestApi e Input Injection</a>. Tutto ciò mi ha messo voglia di provare a rifare il solito test da lui proposto, però utilizzando <a href="http://www.codeplex.com/white" target="_blank">white</a>, così possiamo confrontare i due framework. Cominciamo!!</p> <p>Prima di tutto lo screenshot della mia applicazione, non è proprio identica a quella di Dario, ma va benissimo!</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/bmatte/WindowsLiveWriter/UIFunctionalTestingWithWhite_12787/ui%20test_2.png" target="_blank"><img title="ui test" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="232" alt="ui test" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/bmatte/WindowsLiveWriter/UIFunctionalTestingWithWhite_12787/ui%20test_thumb.png" width="384" border="0" /></a> </p> <p>Come sappiamo, lo scopo del test è quello di:</p> <ol> <li>Lanciare l'applicazione </li> <li>Selezione della modalità di filtraggio (ovvero selezione di un item della ComboBox) </li> <li>Inserimento della filterExpression (typing nella TextBox) </li> <li>Click del Button di ricerca </li> <li>Valutazione dei risultati nella ListBox </li> </ol> <p>Niente di più facile!! <img alt="smile_wink" src="http://spaces.live.com/rte/emoticons/smile_wink.gif" /> Come per le <a href="http://www.codeplex.com/TestApi" target="_blank">TestApi</a>, per prima cosa nello XAML dobbiamo impostare per ogni elemento interessato l’Attached Properties <a href="http://msdn.microsoft.com/en-us/library/system.windows.automation.automationproperties.automationid.aspx" target="_blank">AutomationProperties.AutomationId</a>, successivamente aggiungiamo un progetto di tipo Class Library per i test. Aggiungiamo come reference al progetto le librerie Core.dll, White.NUnit.dll e nunit.framework.dll, quest’ultima libreria viene fornita insieme ai binari di <a href="http://www.codeplex.com/white" target="_blank">white</a> però in realtà fa parte del framework <a href="http://www.nunit.org/" target="_blank">NUnit</a>. Adesso non ci resta che aggiungere una nuava classe e scrivere il metodo di test come mostrato nel seguente snippet:</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span>[TestFixture]</pre> <pre><span class="lnum"> 2: </span><span class="kwrd">public</span> <span class="kwrd">class</span> MainWindowTests</pre> <pre class="alt"><span class="lnum"> 3: </span>{</pre> <pre><span class="lnum"> 4: </span> <span class="kwrd">private</span> <span class="kwrd">const</span> <span class="kwrd">string</span> path = <span class="str">@"C:\…\WhiteDemoWithWpf.exe"</span>;</pre> <pre class="alt"><span class="lnum"> 5: </span> </pre> <pre><span class="lnum"> 6: </span> [Test]</pre> <pre class="alt"><span class="lnum"> 7: </span> <span class="kwrd">public</span> <span class="kwrd">void</span> When_click_search_should_filter_loaded_data_by_selected_mode_and_typed_expression()</pre> <pre><span class="lnum"> 8: </span> {</pre> <pre class="alt"><span class="lnum"> 9: </span> <span class="kwrd">string</span> productNameToMatch = <span class="str">"Chang"</span>;</pre> <pre><span class="lnum"> 10: </span> </pre> <pre class="alt"><span class="lnum"> 11: </span> <span class="rem">//Esecuzione dell'applicazione</span></pre> <pre><span class="lnum"> 12: </span> var application = Application.Launch(path);</pre> <pre class="alt"><span class="lnum"> 13: </span> </pre> <pre><span class="lnum"> 14: </span> <span class="rem">//Ottengo la Window e verifico che non sia Null</span></pre> <pre class="alt"><span class="lnum"> 15: </span> var window = application.GetWindow(<span class="str">"MainWindow"</span>, InitializeOption.NoCache);</pre> <pre><span class="lnum"> 16: </span> Assert.That(window,Is.Not.Null);</pre> <pre class="alt"><span class="lnum"> 17: </span> </pre> <pre><span class="lnum"> 18: </span> <span class="rem">//Seleziono un elemento della ComboBox</span></pre> <pre class="alt"><span class="lnum"> 19: </span> var lstFilterCriteria = window.Get&lt;ComboBox&gt;(<span class="str">"lstFilterCriteria"</span>);</pre> <pre><span class="lnum"> 20: </span> lstFilterCriteria.Select(3);</pre> <pre class="alt"><span class="lnum"> 21: </span> </pre> <pre><span class="lnum"> 22: </span> <span class="rem">//Scrivo il Product Name per il test</span></pre> <pre class="alt"><span class="lnum"> 23: </span> var txtProductName = window.Get&lt;TextBox&gt;(<span class="str">"txtProductName"</span>);</pre> <pre><span class="lnum"> 24: </span> txtProductName.Text = productNameToMatch;</pre> <pre class="alt"><span class="lnum"> 25: </span> </pre> <pre><span class="lnum"> 26: </span> <span class="rem">//Clicco il Button per effettuare la ricerca</span></pre> <pre class="alt"><span class="lnum"> 27: </span> var btnFilterProducts = window.Get&lt;Button&gt;(<span class="str">"btnFilterProducts"</span>);</pre> <pre><span class="lnum"> 28: </span> btnFilterProducts.Click();</pre> <pre class="alt"><span class="lnum"> 29: </span> </pre> <pre><span class="lnum"> 30: </span> <span class="rem">//Verifico che il numero totale di elementi della lista sia 1</span></pre> <pre class="alt"><span class="lnum"> 31: </span> var listViewProducts = window.Get&lt;ListView&gt;(<span class="str">"listViewProducts"</span>);</pre> <pre><span class="lnum"> 32: </span> Assert.That(listViewProducts.Rows.Count, Is.EqualTo(1));</pre> <pre class="alt"><span class="lnum"> 33: </span> </pre> <pre><span class="lnum"> 34: </span> <span class="rem">//Verifico il contenuto della cella contenente </span></pre> <pre class="alt"><span class="lnum"> 35: </span> <span class="rem">//il risultato della ricerca con il Product Name per il test</span></pre> <pre><span class="lnum"> 36: </span> var cell = listViewProducts.Rows[0].Cells[0];</pre> <pre class="alt"><span class="lnum"> 37: </span> Assert.That(cell.Text, Is.EqualTo(productNameToMatch));</pre> <pre><span class="lnum"> 38: </span> </pre> <pre class="alt"><span class="lnum"> 39: </span> <span class="rem">//Chiudo l'applicazione</span></pre> <pre><span class="lnum"> 40: </span> application.Kill();</pre> <pre class="alt"><span class="lnum"> 41: </span> }</pre> <pre><span class="lnum"> 42: </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> <p>I commenti descrivono chiaramente la logica del metodo. Lanciamo il test (sempre con le mani dietro alla testa <img alt="smile_wink" src="http://spaces.live.com/rte/emoticons/smile_wink.gif" />) e godiamoci il risultato:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/bmatte/WindowsLiveWriter/UIFunctionalTestingWithWhite_12787/CropperCapture%5B1%5D.png" target="_blank"><img title="CropperCapture[1]" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="196" alt="CropperCapture[1]" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/bmatte/WindowsLiveWriter/UIFunctionalTestingWithWhite_12787/CropperCapture%5B1%5D_thumb.png" width="862" border="0" /></a> </p> <p /> <p>Le prime tre righe sono “problemi” di <a href="http://www.codeplex.com/white/Wiki/View.aspx?title=Configuration&amp;referringTitle=Home" target="_blank">confgurazione</a> non essenziali per questa demo. </p> <p>Confrontando il solito metodo di test scritto con i due framework devo dire che <a href="http://www.codeplex.com/white" target="_blank">white</a> al momento offre un modello di pilotaggio della UI molto più ricco e semplice da utilizzare. Atro aspetto interessante è che <a href="http://www.codeplex.com/white" target="_blank">white</a> permette di testare anche applicazioni Java scritte in SWT!!</p> <p>Devo ammettere che vedere l’applicazione vivere di vita propria fa un certo effetto!!! <img alt="smile_teeth" src="http://spaces.live.com/rte/emoticons/smile_teeth.gif" /></p> <div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:79cbd1a6-410f-4088-86e4-0e83dd6c8349" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; 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/Windows+Presentation+Foundation" rel="tag">Windows Presentation Foundation</a>,<a href="http://technorati.com/tags/FunctionalTest" rel="tag">FunctionalTest</a>,<a href="http://technorati.com/tags/White" rel="tag">White</a></div><img src="http://blogs.ugidotnet.org/bmatte/aggbug/94978.aspx" width="1" height="1" /> Matteo Baglini http://blogs.ugidotnet.org/bmatte/archive/2008/12/18/wpf-functional-testing-with-white.aspx Thu, 18 Dec 2008 23:23:02 GMT http://blogs.ugidotnet.org/bmatte/archive/2008/12/18/wpf-functional-testing-with-white.aspx#feedback 2 http://blogs.ugidotnet.org/bmatte/comments/commentRss/94978.aspx http://blogs.ugidotnet.org/bmatte/services/trackbacks/94978.aspx WPF UI Test Framework http://blogs.ugidotnet.org/bmatte/archive/2008/12/16/wpf-ui-test-framework.aspx <p><a href="http://blogs.msdn.com/ivo_manolov/archive/2008/12/06/9181396.aspx" target="_blank">Ivo Manolov annumcia</a> sul proprio blog il <a href="http://www.codeplex.com/TestApi" target="_blank">rilascio di un tool open source</a> per automatizzare il test della UI sia essa in WPF pittosto che WinForm. Sempre sul suo blog potete leggere il <a href="http://blogs.msdn.com/ivo_manolov/archive/2008/12/15/9223397.aspx" target="_blank">primo post guida</a> del tool. Da questi post ho scoperto che esiste un <a href="http://blogs.msdn.com/wpftesting/" target="_blank">blog su MSDN dedicato al testing di WPF</a>. </p> <p>Esisteva già un tool open surce simile si chiama <a href="http://www.codeplex.com/white" target="_blank">white ed anche questo è hostato su CodePlex</a>.</p> <div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:f3edd854-9fff-40ea-bb0c-b788235ffd4d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tag: <a href="http://technorati.com/tags/UnitTest" rel="tag">UnitTest</a>,<a href="http://technorati.com/tags/UI+Test" rel="tag">UI Test</a></div><img src="http://blogs.ugidotnet.org/bmatte/aggbug/94957.aspx" width="1" height="1" /> Matteo Baglini http://blogs.ugidotnet.org/bmatte/archive/2008/12/16/wpf-ui-test-framework.aspx Tue, 16 Dec 2008 17:02:24 GMT http://blogs.ugidotnet.org/bmatte/archive/2008/12/16/wpf-ui-test-framework.aspx#feedback 3 http://blogs.ugidotnet.org/bmatte/comments/commentRss/94957.aspx http://blogs.ugidotnet.org/bmatte/services/trackbacks/94957.aspx Pattern Model-View-ViewModel, INotifyPropertyChanged, Static Reflection e Extension methods http://blogs.ugidotnet.org/bmatte/archive/2008/11/28/pattern-model-view-viewmodel-inotifypropertychanged-static-reflection-e-extension-methods.aspx <p>Anch’io nei miei progetti WPF per rendere testabile la logica della mia applicazione senza rinunciare alla pontenza del <em>DataBinding</em> utilizzo (anche) il Pattern Model-View-ViewModel. L’interfaccia <em>INotifyPropertyChanged</em> gioca un ruolo fondamentale nell’implementazione di questo pattern quindi ne faccio un uso massiccio. Quello che non mi è mai piaciuto di questa interfaccia è l’uso delle stringe per indicare qual è la proprietà modificata, vediamo un semplice esempio dell’uso di INotifyPropertyChanged:</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">public</span> <span class="kwrd">class</span> Person : INotifyPropertyChanged {</pre> <pre><span class="lnum"> 2: </span> <span class="kwrd">public</span> <span class="kwrd">event</span> PropertyChangedEventHandler PropertyChanged;</pre> <pre class="alt"><span class="lnum"> 3: </span> </pre> <pre><span class="lnum"> 4: </span> <span class="kwrd">private</span> <span class="kwrd">string</span> firstName = String.Empty;</pre> <pre class="alt"><span class="lnum"> 5: </span> <span class="kwrd">public</span> <span class="kwrd">string</span> FirstName {</pre> <pre><span class="lnum"> 6: </span> get { <span class="kwrd">return</span> firstName; }</pre> <pre class="alt"><span class="lnum"> 7: </span> set {</pre> <pre><span class="lnum"> 8: </span> <span class="kwrd">if</span> (firstName != <span class="kwrd">value</span>) {</pre> <pre class="alt"><span class="lnum"> 9: </span> firstName = <span class="kwrd">value</span>;</pre> <pre><span class="lnum"> 10: </span> RaisePropertyChanged(<span class="str">"FirstName"</span>);</pre> <pre class="alt"><span class="lnum"> 11: </span> }</pre> <pre><span class="lnum"> 12: </span> }</pre> <pre class="alt"><span class="lnum"> 13: </span> }</pre> <pre><span class="lnum"> 14: </span> </pre> <pre class="alt"><span class="lnum"> 15: </span> <span class="kwrd">private</span> <span class="kwrd">void</span> RaisePropertyChanged(<span class="kwrd">string</span> propertyName) {</pre> <pre><span class="lnum"> 16: </span> <span class="kwrd">if</span> (PropertyChanged != <span class="kwrd">null</span>)</pre> <pre class="alt"><span class="lnum"> 17: </span> PropertyChanged(<span class="kwrd">this</span>, <span class="kwrd">new</span> PropertyChangedEventArgs(propertyName));</pre> <pre><span class="lnum"> 18: </span> }</pre> <pre class="alt"><span class="lnum"> 19: </span>}</pre> </div> <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> <p /> <p>Se cambio il nome della proprietà <em>FirstName</em> Visual Studio si accorge del cambiamento e mi permette con un solo click di rinominare la proprietà ovunque venga utilizzata, però questo sistema di <em>refactoring</em> non è abbastanza <em>smart</em> da modificare la stringa <em>FirstName</em> (riga 10). Grazie alla <a href="http://ayende.com/Blog/archive/2005/10/29/StaticReflection.aspx" target="_blank">Static Reflection</a> possiamo eliminare questo problema, il “trucco” sta nel passare al metodo <em>RaisePropertyChanged</em> la proprietà come tipo <em><a href="http://msdn.microsoft.com/en-us/library/bb335710.aspx" target="_blank">Expression&lt;Func&lt;T&gt;&gt;</a>,</em> convertire successivamente il <em><a href="http://msdn.microsoft.com/en-us/library/system.linq.expressions.lambdaexpression.body.aspx" target="_blank">Body</a></em> nel tipo <em><a href="http://msdn.microsoft.com/en-us/library/system.linq.expressions.memberexpression.aspx" target="_blank">MemberExpression</a></em> ed in fine recuperare il nome tramite le proprietà <em><a href="http://msdn.microsoft.com/en-us/library/system.linq.expressions.memberexpression.member.aspx" target="_blank">Member</a></em>. Risultato:</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">public</span> <span class="kwrd">class</span> Person : INotifyPropertyChanged {</pre> <pre><span class="lnum"> 2: </span> <span class="kwrd">public</span> <span class="kwrd">event</span> PropertyChangedEventHandler PropertyChanged;</pre> <pre class="alt"><span class="lnum"> 3: </span> </pre> <pre><span class="lnum"> 4: </span> <span class="kwrd">private</span> <span class="kwrd">string</span> firstName = String.Empty;</pre> <pre class="alt"><span class="lnum"> 5: </span> <span class="kwrd">public</span> <span class="kwrd">string</span> FirstName {</pre> <pre><span class="lnum"> 6: </span> get { <span class="kwrd">return</span> firstName; }</pre> <pre class="alt"><span class="lnum"> 7: </span> set {</pre> <pre><span class="lnum"> 8: </span> <span class="kwrd">if</span> (firstName != <span class="kwrd">value</span>) {</pre> <pre class="alt"><span class="lnum"> 9: </span> firstName = <span class="kwrd">value</span>;</pre> <pre><span class="lnum"> 10: </span> RaisePropertyChanged(() =&gt; FirstName);</pre> <pre class="alt"><span class="lnum"> 11: </span> }</pre> <pre><span class="lnum"> 12: </span> }</pre> <pre class="alt"><span class="lnum"> 13: </span> }</pre> <pre><span class="lnum"> 14: </span> </pre> <pre class="alt"><span class="lnum"> 15: </span> <span class="kwrd">private</span> <span class="kwrd">void</span> RaisePropertyChanged&lt;T&gt;(Expression&lt;Func&lt;T&gt;&gt; property) { </pre> <pre><span class="lnum"> 16: </span> var expression = property.Body <span class="kwrd">as</span> MemberExpression;</pre> <pre class="alt"><span class="lnum"> 17: </span> var member = expression.Member;</pre> <pre><span class="lnum"> 18: </span> <span class="kwrd">if</span> (PropertyChanged != <span class="kwrd">null</span>)</pre> <pre class="alt"><span class="lnum"> 19: </span> PropertyChanged(<span class="kwrd">this</span>, <span class="kwrd">new</span> PropertyChangedEventArgs(member.Name));</pre> <pre><span class="lnum"> 20: </span> }</pre> <pre class="alt"><span class="lnum"> 21: </span>}</pre> </div> <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>Adesso il nostro codice supporta pienamente il <em>rename refactoring</em>. Come ultimo passo possiamo incapsulare la logica di manipolazione dei tipi <em>Expression</em> in un <em>Extension methods </em>rendendo il codice molto più leggibile: <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">class</span> PropertyExtensions {</pre> <pre><span class="lnum"> 2: </span> <span class="kwrd">public</span> <span class="kwrd">static</span> PropertyChangedEventArgs CreateChangeEventArgs&lt;T&gt;(<span class="kwrd">this</span> Expression&lt;Func&lt;T&gt;&gt; property) {</pre> <pre class="alt"><span class="lnum"> 3: </span> var expression = property.Body <span class="kwrd">as</span> MemberExpression;</pre> <pre><span class="lnum"> 4: </span> var member = expression.Member;</pre> <pre class="alt"><span class="lnum"> 5: </span> <span class="kwrd">return</span> <span class="kwrd">new</span> PropertyChangedEventArgs(member.Name);</pre> <pre><span class="lnum"> 6: </span> }</pre> <pre class="alt"><span class="lnum"> 7: </span>}</pre> <pre><span class="lnum"> 8: </span> </pre> <pre class="alt"><span class="lnum"> 9: </span><span class="kwrd">public</span> <span class="kwrd">class</span> Person : INotifyPropertyChanged {</pre> <pre><span class="lnum"> 10: </span> <span class="kwrd">public</span> <span class="kwrd">event</span> PropertyChangedEventHandler PropertyChanged;</pre> <pre class="alt"><span class="lnum"> 11: </span> </pre> <pre><span class="lnum"> 12: </span> <span class="kwrd">private</span> <span class="kwrd">string</span> firstName = String.Empty;</pre> <pre class="alt"><span class="lnum"> 13: </span> <span class="kwrd">public</span> <span class="kwrd">string</span> FirstName {</pre> <pre><span class="lnum"> 14: </span> get { <span class="kwrd">return</span> firstName; }</pre> <pre class="alt"><span class="lnum"> 15: </span> set {</pre> <pre><span class="lnum"> 16: </span> <span class="kwrd">if</span> (firstName != <span class="kwrd">value</span>) {</pre> <pre class="alt"><span class="lnum"> 17: </span> firstName = <span class="kwrd">value</span>;</pre> <pre><span class="lnum"> 18: </span> RaisePropertyChanged(() =&gt; FirstName);</pre> <pre class="alt"><span class="lnum"> 19: </span> }</pre> <pre><span class="lnum"> 20: </span> }</pre> <pre class="alt"><span class="lnum"> 21: </span> }</pre> <pre><span class="lnum"> 22: </span> </pre> <pre class="alt"><span class="lnum"> 23: </span> <span class="kwrd">private</span> <span class="kwrd">void</span> RaisePropertyChanged&lt;T&gt;(Expression&lt;Func&lt;T&gt;&gt; property) { </pre> <pre><span class="lnum"> 24: </span> <span class="kwrd">if</span> (PropertyChanged != <span class="kwrd">null</span>)</pre> <pre class="alt"><span class="lnum"> 25: </span> PropertyChanged(<span class="kwrd">this</span>, property.CreateChangeEventArgs());</pre> <pre><span class="lnum"> 26: </span> }</pre> <pre class="alt"><span class="lnum"> 27: </span>}</pre> </div> <p /> <div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:06f17728-e2aa-4822-ac20-75f4fcc5d3ad" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tag: <a href="http://technorati.com/tags/Model-View-ViewModel" rel="tag">Model-View-ViewModel</a>,<a href="http://technorati.com/tags/M-V-VM" rel="tag">M-V-VM</a>,<a href="http://technorati.com/tags/Extension+Methods" rel="tag">Extension Methods</a>,<a href="http://technorati.com/tags/INotifyPropertyChanged" rel="tag">INotifyPropertyChanged</a>,<a href="http://technorati.com/tags/Expression" rel="tag">Expression</a></div><img src="http://blogs.ugidotnet.org/bmatte/aggbug/94787.aspx" width="1" height="1" /> Matteo Baglini http://blogs.ugidotnet.org/bmatte/archive/2008/11/28/pattern-model-view-viewmodel-inotifypropertychanged-static-reflection-e-extension-methods.aspx Fri, 28 Nov 2008 16:06:28 GMT http://blogs.ugidotnet.org/bmatte/archive/2008/11/28/pattern-model-view-viewmodel-inotifypropertychanged-static-reflection-e-extension-methods.aspx#feedback 13 http://blogs.ugidotnet.org/bmatte/comments/commentRss/94787.aspx http://blogs.ugidotnet.org/bmatte/services/trackbacks/94787.aspx WPF Effects Library http://blogs.ugidotnet.org/bmatte/archive/2008/10/23/wpf-effects-library.aspx Una delle <a target="_blank" href="http://windowsclient.net/wpf/wpf35/wpf-whats-new-35sp1.aspx">novità di WPF 3.5 SP1</a> sono gli Shader Effects, adesso il Team di WPF ha pubblicato su <a target="_blank" href="http://www.codeplex.com/">CodePlex</a> la <a target="_blank" href="http://www.codeplex.com/wpffx">Windows Presentation Foundation Pixel Shader Effects Library</a>, una libreria  contenente molti Shader Effects, direttamente dalla home del progetto: <p>Initial seed includes: <br /> Effects: <br /> BandedSwirl, Bloom, BrightExtract, ColorKeyAlpha, ColorTone, ContrastAdjust, DirectionalBlur, Embossed, Gloom, GrowablePoissonDiskEffect, InvertColor, LightStreak, Magnify, Monochrome, Pinch, Pixelate, Ripple, Sharpen, SmoothMagnify, Swirl, Tone, Toon, and ZoomBlur <br /> Transition Effects: <br /> BandedSwirl, Blings, Blood, CircleReveal, CircleStretch, CircularBlur, CloudReveral, Cloudy, Crumble, Dissolve, DropFade, Fade, LeastBright, LineReveal, MostBright, PixelateIn, PixelateOut, Pixelate, RadialBlur, RadialWiggle, RandomCircleReveal, Ripple, Rotate, Saturate, Shrink, SlideIn, SmoothSwirl, Swirl, Water, Wave. </p> <p>Ora non resta che provarli tutti <img src="http://spaces.live.com/rte/emoticons/smile_teeth.gif" alt="smile_teeth" />.</p> <div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:444a6ae9-6664-415d-8b8a-b0d9cb107bfb" class="wlWriterEditableSmartContent">Technorati Tag: <a rel="tag" href="http://technorati.com/tags/WPF">WPF</a>,<a rel="tag" href="http://technorati.com/tags/Windows+Presentation+Foundation">Windows Presentation Foundation</a>,<a rel="tag" href="http://technorati.com/tags/Shader+Effects">Shader Effects</a></div><img src="http://blogs.ugidotnet.org/bmatte/aggbug/94837.aspx" width="1" height="1" /> Matteo Baglini http://blogs.ugidotnet.org/bmatte/archive/2008/10/23/wpf-effects-library.aspx Thu, 23 Oct 2008 10:47:00 GMT http://blogs.ugidotnet.org/bmatte/archive/2008/10/23/wpf-effects-library.aspx#feedback 1 http://blogs.ugidotnet.org/bmatte/comments/commentRss/94837.aspx http://blogs.ugidotnet.org/bmatte/services/trackbacks/94837.aspx Pubblicati i sorgenti del controllo WatermarkedTextBox http://blogs.ugidotnet.org/bmatte/archive/2008/10/22/pubblicati-i-sorgenti-del-controllo-watermarkedtextbox.aspx Fra i vari controlli presenti nelle prime versioni di Silverlight c’era la WatermarkedTextBox. Dalla release Beta2 tale controllo è stato rimosso. Adesso, pressati dalle forti richieste, il team di Silverlight ha rilasciato il codice sorgente del suddetto controllo. <ul> <li>Sorgenti: <a href="http://s3.amazonaws.com/timheuer-img/WatermarkedTextBox-Source.zip">WatermarkedTextBox-Source.zip</a></li> <li>Binari: <a href="http://s3.amazonaws.com/timheuer-img/WatermarkedTextBox-Binary.zip">WatermarkedTextBox-Binary.zip</a></li> </ul> <p>Fonte: <a href="http://timheuer.com/blog/archive/2008/10/22/silverlight-watermark-text-box-control.aspx" target="_blank">Silverlight 2 Watermarked TextBox Control</a></p> <div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e686344b-7a42-45bd-8696-9b52f54809db" style="margin: 0px; padding: 0px; display: inline; float: none;">Technorati Tag: <a href="http://technorati.com/tags/Silverlight" rel="tag">Silverlight</a></div><img src="http://blogs.ugidotnet.org/bmatte/aggbug/94836.aspx" width="1" height="1" /> Matteo Baglini http://blogs.ugidotnet.org/bmatte/archive/2008/10/22/pubblicati-i-sorgenti-del-controllo-watermarkedtextbox.aspx Wed, 22 Oct 2008 22:27:00 GMT http://blogs.ugidotnet.org/bmatte/archive/2008/10/22/pubblicati-i-sorgenti-del-controllo-watermarkedtextbox.aspx#feedback http://blogs.ugidotnet.org/bmatte/comments/commentRss/94836.aspx http://blogs.ugidotnet.org/bmatte/services/trackbacks/94836.aspx [WPF] Intercettare l’evento MouseDoubleClick di un ListBoxItem http://blogs.ugidotnet.org/bmatte/archive/2008/10/22/wpf-intercettare-levento-mousedoubleclick-di-un-listboxitem.aspx <p>Visual Studio 2008 Sp1 non visualizza l’evento MouseDoubleClick per un ListBoxITem, come se non esistesse:</p> <p> <a href="../../../../images/blogs_ugidotnet_org/bmatte/WindowsLiveWriter/a560dea00ac4_11015/ListBoxITemMouseDoubleClick_2.png"><img height="62" border="0" width="244" src="../../../../images/blogs_ugidotnet_org/bmatte/WindowsLiveWriter/a560dea00ac4_11015/ListBoxITemMouseDoubleClick_thumb.png" alt="ListBoxITemMouseDoubleClick" style="border-width: 0px; display: inline;" title="ListBoxITemMouseDoubleClick" /></a> </p> <p>In realtà tale evento esiste, è solo un problema di IntelliSense, quindi basta digitare il nome e tutto funziona:</p> <p> <a href="../../../../images/blogs_ugidotnet_org/bmatte/WindowsLiveWriter/a560dea00ac4_11015/ListBoxITemMouseDoubleClick2_2.png"><img height="52" border="0" width="244" src="../../../../images/blogs_ugidotnet_org/bmatte/WindowsLiveWriter/a560dea00ac4_11015/ListBoxITemMouseDoubleClick2_thumb.png" alt="ListBoxITemMouseDoubleClick2" style="border-width: 0px; display: inline;" title="ListBoxITemMouseDoubleClick2" /></a> </p> <p>Al seguente url è disponibile una piccola demo: <a target="_blank" href="http://makesimple.googlecode.com/svn/trunk/WPF/ListItemDoubleClickDemo/">ListItemDoubleClickDemo</a></p> <div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:c6d58023-12da-44ea-b225-0cf0fdfe31eb" class="wlWriterSmartContent">Technorati Tag: <a rel="tag" href="http://technorati.com/tags/WPF">WPF</a>,<a rel="tag" href="http://technorati.com/tags/Windows+Presentation+Foundation">Windows Presentation Foundation</a></div><img src="http://blogs.ugidotnet.org/bmatte/aggbug/94831.aspx" width="1" height="1" /> Matteo Baglini http://blogs.ugidotnet.org/bmatte/archive/2008/10/22/wpf-intercettare-levento-mousedoubleclick-di-un-listboxitem.aspx Wed, 22 Oct 2008 22:27:00 GMT http://blogs.ugidotnet.org/bmatte/archive/2008/10/22/wpf-intercettare-levento-mousedoubleclick-di-un-listboxitem.aspx#feedback 1 http://blogs.ugidotnet.org/bmatte/comments/commentRss/94831.aspx http://blogs.ugidotnet.org/bmatte/services/trackbacks/94831.aspx XAML - differenze fra Silverlight e WPF http://blogs.ugidotnet.org/bmatte/archive/2008/10/22/xaml-differenze-fra-silverlight-e-wpf.aspx <p>XAML è un linguaggio dichiarativo general-purpose, sviluppato da Microsoft e derivato dall’XML, atto alla rappresentazione di gerarchie di oggetti. Attualmente XAML è utilizzato in Silverlight, Windows Presentation Foundation (WPF) e Windows Workflow Foundation (WF), ognuno con il proprio parser e runtime. Sul sito MSDN possiamo trovare un <a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc917841%28VS.95%29.aspx">articolo</a> che spiega le differenze fra il parser di Silverlight e quello di WPF.</p> <div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:5b705c79-6ae2-4913-a657-8c68ee716b86" class="wlWriterEditableSmartContent">Technorati Tag: <a rel="tag" href="http://technorati.com/tags/Silverlight">Silverlight</a>,<a rel="tag" href="http://technorati.com/tags/WPF">WPF</a>,<a rel="tag" href="http://technorati.com/tags/Windows+Presentation+Foundation">Windows Presentation Foundation</a>,<a rel="tag" href="http://technorati.com/tags/XAML">XAML</a></div><img src="http://blogs.ugidotnet.org/bmatte/aggbug/94835.aspx" width="1" height="1" /> Matteo Baglini http://blogs.ugidotnet.org/bmatte/archive/2008/10/22/xaml-differenze-fra-silverlight-e-wpf.aspx Wed, 22 Oct 2008 22:14:00 GMT http://blogs.ugidotnet.org/bmatte/archive/2008/10/22/xaml-differenze-fra-silverlight-e-wpf.aspx#feedback 1 http://blogs.ugidotnet.org/bmatte/comments/commentRss/94835.aspx http://blogs.ugidotnet.org/bmatte/services/trackbacks/94835.aspx [WPF] RadioButton+Binding=BUG http://blogs.ugidotnet.org/bmatte/archive/2008/10/20/wpf-radiobuttonbindingbug.aspx <p>Questo post doveva essere pubblicato già da po’ di settimane, ma gli impegni sono sempre pronti a mettere il bastone fra le ruote.</p> <p>In WPF se mettete in Binding una proprietà di tipo boolean con un controllo RadioButton vi accorgerete presto di un bug nel motore di Binding.</p> <p>Maggiori info su questo <a target="_blank" href="http://groups.google.it/group/microsoft.public.it.dotnet.csharp/browse_frm/thread/93620107bb52fead/91937a77dd19f7ec?tvc=1#91937a77dd19f7ec">thread sul newsgroup di C#</a>.</p> <p>Grazie a <a target="_blank" href="../../../../corrado">Corrado</a> per la segnalazione</p> <div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e5e6233a-a132-4cda-8806-ba61169cece2" class="wlWriterEditableSmartContent">Technorati Tag: <a rel="tag" href="http://technorati.com/tags/Windows+Presentation+Foundation">Windows Presentation Foundation</a>,<a rel="tag" href="http://technorati.com/tags/WPF">WPF</a></div><img src="http://blogs.ugidotnet.org/bmatte/aggbug/94834.aspx" width="1" height="1" /> Matteo Baglini http://blogs.ugidotnet.org/bmatte/archive/2008/10/20/wpf-radiobuttonbindingbug.aspx Mon, 20 Oct 2008 22:22:00 GMT http://blogs.ugidotnet.org/bmatte/archive/2008/10/20/wpf-radiobuttonbindingbug.aspx#feedback 1 http://blogs.ugidotnet.org/bmatte/comments/commentRss/94834.aspx http://blogs.ugidotnet.org/bmatte/services/trackbacks/94834.aspx Expression Blend framework vs CompositeWPF framework http://blogs.ugidotnet.org/bmatte/archive/2008/10/20/expression-blend-framework-vs-compositewpf-framework.aspx <p>Un interessante confronto tra il framework di una WPF Composite Application (<a target="_blank" href="http://www.microsoft.com/expression/products/Overview.aspx?key=blend">Expression Blend</a>) e un framework per creare WPF Composite Application (<a target="_blank" href="http://www.codeplex.com/CompositeWPF">CompositeWPF</a>).</p> <p>Fonte: <a target="_blank" href="http://www.paulstovell.com/blog/expression-framework-versus-composite-wpf">Expression Framework versus Composite WPF</a></p> <div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:114d5c6c-4de7-4ce9-8df9-6ae7b3f4b9e6" class="wlWriterEditableSmartContent">Technorati Tag: <a rel="tag" href="http://technorati.com/tags/ExpressionBlend">ExpressionBlend</a>,<a rel="tag" href="http://technorati.com/tags/CompositeWPF">CompositeWPF</a>,<a rel="tag" href="http://technorati.com/tags/WPF">WPF</a>,<a rel="tag" href="http://technorati.com/tags/Windows+Presentation+Foundation">Windows Presentation Foundation</a></div><img src="http://blogs.ugidotnet.org/bmatte/aggbug/94833.aspx" width="1" height="1" /> Matteo Baglini http://blogs.ugidotnet.org/bmatte/archive/2008/10/20/expression-blend-framework-vs-compositewpf-framework.aspx Mon, 20 Oct 2008 21:51:00 GMT http://blogs.ugidotnet.org/bmatte/archive/2008/10/20/expression-blend-framework-vs-compositewpf-framework.aspx#feedback 1 http://blogs.ugidotnet.org/bmatte/comments/commentRss/94833.aspx http://blogs.ugidotnet.org/bmatte/services/trackbacks/94833.aspx