<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>WPF</title>
        <link>http://blogs.ugidotnet.org:443/dsantarelli/category/WPF.aspx</link>
        <description>WPF</description>
        <language>it-IT</language>
        <copyright>Dario Santarelli</copyright>
        <generator>Subtext Version 2.6.0.0</generator>
        <item>
            <title>[AOP] UI e dintorni con PostSharp</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2011/10/16/aop-ui-e-dintorni-con-postsharp.aspx</link>
            <description>&lt;p&gt;L’AOP ormai sta diventando un paradigma di programmazione sempre più diffuso specialmente nel mondo .NET dove strumenti come &lt;a href="http://www.postsharp.org/"&gt;PostSharp&lt;/a&gt;, &lt;a href="http://dotspect.tigris.org/"&gt;DotSpect&lt;/a&gt; (&lt;em&gt;Compile-time&lt;/em&gt; s&lt;em&gt;tatic injection) &lt;/em&gt;e &lt;a href="http://www.springframework.net/"&gt;Spring.NET&lt;/a&gt;, &lt;a href="http://www.castleproject.org/container/index.html"&gt;Castle Windsor&lt;/a&gt;, &lt;a href="http://www.codeplex.com/entlib"&gt;Enterprise Library&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/dd139982.aspx"&gt;Policy Injection Application Block&lt;/a&gt; (&lt;em&gt;Dynamic Proxy&lt;/em&gt;) rendono sempre più semplice la gestione dei “&lt;em&gt;&lt;a target="_blank" href="http://en.wikipedia.org/wiki/Cross-cutting_concern"&gt;cross-cutting concerns&lt;/a&gt;&lt;/em&gt;” che provengono dal mondo Object-Oriented. Personalmente sono stato sempre un entusiasta di &lt;a target="_blank" href="http://www.sharpcrafters.com/"&gt;PostSharp&lt;/a&gt; e in questo post vorrei citare un paio di aspect che ho sempre valutato positivamente nella gestione di codice “vicino” alla UI, specialmente nel mondo Windows Forms e WPF.&lt;/p&gt;
&lt;p&gt;Il primo aspect ha a che vedere con il DataBinding. Sappiamo tutti come implementare l’interfaccia &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx"&gt;INotifyPropertyChanged&lt;/a&gt; sia noioso ed anche a fronte di snippet per velocizzare il processo di scrittura il risultato che otteniamo si allontana dall’idea di avere codice (almeno) esteticamente “impeccabile”. Per questo l’aspect che PostSharp introduce a riguardo è tanto semplice quanto geniale in quanto permette, tramite un banale attributo, di agganciare l’implementazione dell’interfaccia &lt;em&gt;INotifyPropertyChanged&lt;/em&gt; ad un oggetto ed eventualmente alle sue specializzazioni. Ad esempio, se definissimo un oggetto &lt;em&gt;Customer&lt;/em&gt; nel seguente modo…&lt;/p&gt;
&lt;pre class="code"&gt;&lt;strong&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;NotifyPropertyChanged&lt;/span&gt;]&lt;/strong&gt; &lt;br /&gt;&lt;span style="color: blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Customer &lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;{   &lt;/span&gt;&lt;/pre&gt;
&lt;pre class="code"&gt;   &lt;span style="color: blue;"&gt;public string &lt;/span&gt;Name { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }   &lt;br /&gt;   &lt;span style="color: blue;"&gt;public string &lt;/span&gt;Surname { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }   &lt;br /&gt;   &lt;span style="color: blue;"&gt;public string &lt;/span&gt;Email { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt;   ... &lt;/pre&gt;
&lt;pre class="code"&gt;}&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;
…tramite l’attributo &lt;em&gt;[NotifyPropertyChanged]&lt;/em&gt; impostato a livello di classe otteniamo nell’assembly di output una injection della solita implementazione dell’interfaccia &lt;em&gt;INotifyPropertyChanged&lt;/em&gt;. L’ implementazione dell’aspect, riportata anche nel sito di PostSharp, è la seguente…&lt;/p&gt;
&lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;Serializable&lt;/span&gt;] &lt;br /&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;IntroduceInterface&lt;/span&gt;(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;INotifyPropertyChanged&lt;/span&gt;),OverrideAction = &lt;span style="color: rgb(43, 145, 175);"&gt;InterfaceOverrideAction&lt;/span&gt;.Ignore)] &lt;br /&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;MulticastAttributeUsage&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;MulticastTargets&lt;/span&gt;.Class, Inheritance = &lt;span style="color: rgb(43, 145, 175);"&gt;MulticastInheritance&lt;/span&gt;.Strict)] &lt;br /&gt;&lt;span style="color: blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;NotifyPropertyChangedAttribute &lt;/span&gt;: &lt;span style="color: rgb(43, 145, 175);"&gt;InstanceLevelAspect&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;INotifyPropertyChanged &lt;br /&gt;&lt;/span&gt;{           &lt;br /&gt;  [&lt;span style="color: rgb(43, 145, 175);"&gt;ImportMember&lt;/span&gt;(&lt;span style="color: rgb(163, 21, 21);"&gt;"OnPropertyChanged"&lt;/span&gt;, IsRequired = &lt;span style="color: blue;"&gt;false&lt;/span&gt;)]    &lt;br /&gt;   &lt;span style="color: blue;"&gt;public &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;gt; OnPropertyChangedMethod;           &lt;br /&gt;&lt;br /&gt;  [&lt;span style="color: rgb(43, 145, 175);"&gt;IntroduceMember&lt;/span&gt;(Visibility = &lt;span style="color: rgb(43, 145, 175);"&gt;Visibility&lt;/span&gt;.Family, &lt;br /&gt;                   IsVirtual = &lt;span style="color: blue;"&gt;true&lt;/span&gt;, &lt;br /&gt;                   OverrideAction = &lt;span style="color: rgb(43, 145, 175);"&gt;MemberOverrideAction&lt;/span&gt;.Ignore)]    &lt;br /&gt;  &lt;span style="color: blue;"&gt;public void &lt;/span&gt;OnPropertyChanged(&lt;span style="color: blue;"&gt;string &lt;/span&gt;propertyName)    &lt;br /&gt;  {      &lt;br /&gt;    &lt;span style="color: blue;"&gt;if &lt;/span&gt;(&lt;span style="color: blue;"&gt;this&lt;/span&gt;.PropertyChanged != &lt;span style="color: blue;"&gt;null&lt;/span&gt;)       &lt;br /&gt;    {          &lt;br /&gt;      &lt;span style="color: blue;"&gt;this&lt;/span&gt;.PropertyChanged(&lt;span style="color: blue;"&gt;this&lt;/span&gt;.Instance, &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PropertyChangedEventArgs&lt;/span&gt;(propertyName));       &lt;br /&gt;    }    &lt;br /&gt;  }           &lt;br /&gt;&lt;br /&gt;  [&lt;span style="color: rgb(43, 145, 175);"&gt;IntroduceMember&lt;/span&gt;(OverrideAction = &lt;span style="color: rgb(43, 145, 175);"&gt;MemberOverrideAction&lt;/span&gt;.Ignore)]    &lt;br /&gt;  &lt;span style="color: blue;"&gt;public event &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PropertyChangedEventHandler &lt;/span&gt;PropertyChanged;            &lt;br /&gt;&lt;br /&gt;  [&lt;span style="color: rgb(43, 145, 175);"&gt;OnLocationSetValueAdvice&lt;/span&gt;]    &lt;br /&gt;  [&lt;span style="color: rgb(43, 145, 175);"&gt;MulticastPointcut&lt;/span&gt;(Targets = &lt;span style="color: rgb(43, 145, 175);"&gt;MulticastTargets&lt;/span&gt;.Property, Attributes = &lt;span style="color: rgb(43, 145, 175);"&gt;MulticastAttributes&lt;/span&gt;.Instance)]    &lt;br /&gt;  &lt;span style="color: blue;"&gt;public void &lt;/span&gt;OnPropertySet(&lt;span style="color: rgb(43, 145, 175);"&gt;LocationInterceptionArgs &lt;/span&gt;args)    &lt;br /&gt;  {                   &lt;br /&gt;    &lt;span style="color: blue;"&gt;if &lt;/span&gt;(args.Value == args.GetCurrentValue()) &lt;span style="color: blue;"&gt;return&lt;/span&gt;;       &lt;br /&gt;    args.ProceedSetValue();       &lt;br /&gt;    &lt;span style="color: blue;"&gt;this&lt;/span&gt;.OnPropertyChangedMethod.Invoke(args.Location.Name);    &lt;br /&gt;  } &lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;
Il codice è abbastanza autoesplicativo. La feature degna di nota in particolare è la possibilità di estendere automaticamente questo aspect anche alle classi ereditate semplicemente impostando a livello di classe &lt;span style="color: rgb(43, 145, 175);"&gt;MulticastAttributeUsage.&lt;/span&gt;Inheritance = &lt;span style="color: rgb(43, 145, 175);"&gt;MulticastInheritance&lt;/span&gt;.Strict.  &lt;/p&gt;
&lt;p&gt;Un altro aspect che ho sempre ritenuto molto utile ha a che vedere con il thread dispatching, ovvero con la gestione dell’esecuzione di un metodo sul thread dell’interfaccia piuttosto che su un worker thread (es. in WPF controllando il thread associato al &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchersynchronizationcontext.aspx"&gt;DispatcherSynchronizationContext&lt;/a&gt; corrente). Anche in questo ambito PostSharp permette di definire due attributi&lt;em&gt; &lt;/em&gt;&lt;em&gt;[OnGuiThread]&lt;/em&gt; e &lt;em&gt;[OnWorkerThread]&lt;/em&gt; a livello di metodo, che iniettano la comune logica di controllo del SynchronizationContext in modo da forzare l’esecuzione del metodo rispettivamente sul thread dell’interfaccia o su un thread secondario (&lt;a target="_blank" href="http://www.sharpcrafters.com/solutions/multithreading"&gt;link al codice sorgente&lt;/a&gt;).     &lt;br /&gt;
Come risultato, diventa molto semplice applicare questi aspect anche su codice legacy.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;strong&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;OnWorkerThread&lt;/span&gt;]&lt;/strong&gt; &lt;br /&gt;&lt;span style="color: blue;"&gt;void &lt;/span&gt;SaveCustomer() &lt;br /&gt;{    &lt;br /&gt;  Customer.Save();    &lt;br /&gt;  ShowMessage(&lt;span style="color: rgb(163, 21, 21);"&gt;"Customer Saved!"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class="code"&gt;}  &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;OnGuiThread&lt;/span&gt;]&lt;/strong&gt; &lt;br /&gt;&lt;span style="color: blue;"&gt;void &lt;/span&gt;ShowMessage(&lt;span style="color: blue;"&gt;string &lt;/span&gt;message) &lt;br /&gt;{ &lt;br /&gt;  &lt;span style="color: rgb(43, 145, 175);"&gt;MessageBox&lt;/span&gt;.Show(message); &lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;
Il pacchetto di istallazione di PostSharp (disponibile anche su &lt;a target="_blank" href="http://nuget.codeplex.com/wikipage?title=Getting%20Started"&gt;NuGet&lt;/a&gt;) aggiunge a Visual Studio due toolbox veramente utili: l’&lt;em&gt;Aspect Browser&lt;/em&gt; che ci permette navigare su quelli che sono gli aspect utilizzati nell’intera solutione e l’ &lt;em&gt;Affected code&lt;/em&gt; toolbox che ci riassume tutte le classi e i metodi che sono soggetti ad aspects. Inoltre, l’intellisense viene esteso in modo da visualizzare dei summary sulle static injections che gli aspect introducono nell’assembly. Ad esempio, per quanto riguarda il precedente aspect &lt;em&gt;NotifyPropertyChanged&lt;/em&gt;, i tooltip che otteniamo sono i seguenti:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://img534.imageshack.us/img534/4948/customer.jpg" /&gt;  &lt;br /&gt;
&lt;img alt="" src="http://img14.imageshack.us/img14/3687/customersetter.png" /&gt; &lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:87428868-7cd2-42df-9e21-563fdb52b8bf" style="margin: 0px; padding: 0px; float: none; display: inline;"&gt;Technorati tags: &lt;a rel="tag" href="http://technorati.com/tags/AOP"&gt;AOP&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/WPF"&gt;WPF&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/GUI"&gt;GUI&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/100454.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2011/10/16/aop-ui-e-dintorni-con-postsharp.aspx</guid>
            <pubDate>Sun, 16 Oct 2011 21:29:26 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2011/10/16/aop-ui-e-dintorni-con-postsharp.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/100454.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/100454.aspx</trackback:ping>
        </item>
        <item>
            <title>[WPF] Drag and Drop con Rx</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2011/08/25/wpf-drag-and-drop-con-rx.aspx</link>
            <description>Le &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/data/gg577609"&gt;Reactive Extensions (Rx)&lt;/a&gt; del framework .NET sono un set di API dedicate a ciò che nella letteratura prende il nome di “&lt;a href="http://en.wikipedia.org/wiki/Reactive_programming"&gt;reactive programming&lt;/a&gt;”. Rx nasce dalla distinzione di due scenari:
&lt;ul&gt;
    &lt;li&gt;&lt;em&gt;pull&lt;/em&gt;: un programma agisce estraendo dati dall’ambiente in modo interattivo (es. un’iterazione su una sequenza di dati prelevati dall’ambiente).&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;push&lt;/em&gt;: un programma reagisce ai dati che l’ambiente “spinge” verso di esso (es. un event-handler è un esempio di reazione in uno scenario push)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Data questa distinzione, Rx si basa sulla &lt;strong&gt;&lt;a href="http://en.wikipedia.org/wiki/Duality_%28mathematics%29"&gt;&lt;em&gt;dualità&lt;/em&gt;&lt;/a&gt; tra il pattern &lt;a href="http://en.wikipedia.org/wiki/Iterator_pattern"&gt;Iterator&lt;/a&gt; e il pattern &lt;a href="http://en.wikipedia.org/wiki/Observer_pattern"&gt;Observer&lt;/a&gt;&lt;/strong&gt;. In breve, il pattern &lt;em&gt;Observer&lt;/em&gt; in uno scenario &lt;em&gt;push&lt;/em&gt; è analogo al pattern &lt;em&gt;Iterator&lt;/em&gt; in uno scenario &lt;em&gt;pull&lt;/em&gt;.  Nel pattern Iterator, infatti, l’Iterator è l’attore che accede all'insieme degli elementi di un contenitore in modo interattivo. Il pattern Observer può essere interpretato in modo equivalente se si considera che l’ambiente genera spontaneamente i singoli elementi e li spinge verso il programma, ad esempio attraverso eventi. Quando uno stesso evento viene scatenato più volte, di fatto viene prodotta una sequenza di elementi di tipo “evento”, il che rende ovvia a questo punto la relazione con il pattern Iterator.  Rx è stato introdotto quindi per mettere a disposizione degli sviluppatori un modello di programmazione &lt;em&gt;push-based&lt;/em&gt;, duale rispetto al ben più conosciuto &lt;em&gt;pull-based, &lt;/em&gt;pur&lt;em&gt; &lt;/em&gt;non aggiungendo nulla di nuovo rispetto a quest’ultimo. Semplicemente, il modello &lt;em&gt;push-based&lt;/em&gt; offre modi diversi se non più semplici per approcciare problemi comuni legati alla programmazione asincrona ed alla composizione di eventi. &lt;/p&gt;
&lt;p&gt;Rx implementa il pattern Observer tramite le due interfacce &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd783449.aspx"&gt;IObserver&amp;lt;T&amp;gt;&lt;/a&gt; e &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd990377.aspx"&gt;IObservable&amp;lt;T&amp;gt;&lt;/a&gt;, corrispondenti a IEnumerator/IEnumerable del pattern Iterator. IObservable&amp;lt;T&amp;gt; costituisce una sorta di “collezione asincrona” di elementi (generati in momenti diversi quando si parla di eventi). La relazione tra IObservable&amp;lt;T&amp;gt; e IObserver&amp;lt;T&amp;gt; si trova nel fatto che ad un IObservable&amp;lt;T&amp;gt; è possibile registrare uno o più IObserver&amp;lt;T&amp;gt; (tramite il metodo &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd782981.aspx"&gt;IObservable&amp;lt;T&amp;gt;.Subscribe(IObserver&amp;lt;T&amp;gt; observer)&lt;/a&gt; ). IObserver&amp;lt;T&amp;gt; possiede tre metodi: &lt;em&gt;OnNext(…)&lt;/em&gt;, &lt;em&gt;OnCompleted()&lt;/em&gt; e &lt;em&gt;OnError(…)&lt;/em&gt;. Essi vengono invocati dall’ IObservable&amp;lt;T&amp;gt; rispettivamente quando possiede nuovi dati, completa un’operazione e si verifica un errore.  &lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: small;"&gt;&lt;strong&gt;Drag and Drop e LINQ-to-events&lt;/strong&gt;&lt;/span&gt;  &lt;/p&gt;
&lt;p&gt;Nella pratica, uno dei (classici) casi in cui Rx mostra la sua potenza è nell’implementazione del Drag and Drop di un oggetto grafico. Infatti, a differenza delle comuni soluzioni event-based che intercettano eventi e sincronizzano variabili di stato con lo scopo di aggiornare correttamente la posizione dell’oggetto grafico, &lt;span style="text-decoration: underline;"&gt;le Reactive Extensions consentono di convertire gli eventi .NET di interesse in sequenze osservabili che possiamo interrogare tramite query LINQ&lt;/span&gt;.  Vediamo un esempio concreto. Uno dei classici approcci per implementare il drag and drop in WPF (come in Windows Froms o Silverlight) si basa sostanzialmente sulla sincronizzazione di tre eventi logici di un oggetto grafico: &lt;em&gt;MouseDown&lt;/em&gt;, &lt;em&gt;MouseUp&lt;/em&gt; e &lt;em&gt;MouseMove&lt;/em&gt;. Nello specifico, in WPF, supponendo di avere il seguente XAML… &lt;/p&gt;
&lt;pre style="margin: 0px; padding: 0px; width: 100%; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Window&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;x&lt;/span&gt;:&lt;span style="color: rgb(255, 0, 0);"&gt;Class&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"WebRequestWithRxSample.MainWindow"&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(255, 0, 0);"&gt;xmlns&lt;/span&gt;="&lt;span style="color: rgb(0, 0, 255);"&gt;http://schemas.microsoft.com/winfx/2006/xaml/presentation&lt;/span&gt;"&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(255, 0, 0);"&gt;xmlns&lt;/span&gt;:&lt;span style="color: rgb(255, 0, 0);"&gt;x&lt;/span&gt;="&lt;span style="color: rgb(0, 0, 255);"&gt;http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(255, 0, 0);"&gt;Title&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"MainWindow"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;Loaded&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"Window_Loaded"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Canvas&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;StackPanel&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;Name&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"myPanel"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Rectangle&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;Fill&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"Maroon"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;Width&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"100"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;Height&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"100"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;StackPanel&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Canvas&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Window&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;… per gestire il drag and drop dello StackPanel “myPanel” potremmo sincronizzarne i tre eventi &lt;em&gt;MouseLeftButtonDown&lt;/em&gt;, &lt;em&gt;MouseLeftButtonUp&lt;/em&gt; e &lt;em&gt;MouseMove&lt;/em&gt; in modo da gestirne il riposizionamento nel Canvas per ogni evento &lt;em&gt;MouseMove&lt;/em&gt; compreso temporalmente tra un &lt;em&gt;MouseLeftButtonDown&lt;/em&gt; ed un &lt;em&gt;MouseLeftButtonUp&lt;/em&gt;. Quindi, ogni volta che si verifica l’evento &lt;em&gt;MouseLeftButtonDown, &lt;/em&gt;per ogni successivo evento &lt;em&gt;MouseMove&lt;/em&gt; aggiorniamo la posizione dello StackPanel all’interno del Canvas, tenendo conto della posizione del cursore relativa all’angolo in alto a sinistra dello StackPanel. Il tutto finché non viene scatenato l’evento &lt;em&gt;MouseLeftButtonUp&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;&lt;span style="font-size: 8.5pt;"&gt;Point&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt; relativeMouseDownPosition = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Point&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;myPanel.MouseLeftButtonDown += (s, e) =&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;  &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt; (myPanel.CaptureMouse())&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;     {&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;          relativeMouseDownPosition = e.GetPosition(myPanel);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;     }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;myPanel.MouseLeftButtonUp += (s, e) =&amp;gt; { myPanel.ReleaseMouseCapture(); };&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;myPanel.MouseMove += (s, e) =&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;   &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;  if&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt; (myPanel.IsMouseCaptured)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;     {&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;       &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    Point&lt;/span&gt; absoluteMousePosition = e.GetPosition(&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;       &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    Point&lt;/span&gt; newPanelPosition = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Point&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;(absoluteMousePosition.X - relativeMouseDownPosition.X,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;                                                                                 absoluteMousePosition.Y - relativeMouseDownPosition.Y);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;       &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    Canvas&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.SetLeft(myPanel, newPanelPosition.X);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;       &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    Canvas&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.SetTop(myPanel, newPanelPosition.Y);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;   &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Il codice qua sotto implementa la stessa cosa tramite Rx. All’inizio la sintassi può sembrare un po’ meno chiara, ma con il tempo ci si accorge di come in realtà sia molto più leggibile e soprattutto manutenibile rispetto al codice precedente, in quanto si basa su un modello “push” query-based. &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span style="font-size: 8.5pt;"&gt; var &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;relativeMouseDownPositions = &lt;span style="color: rgb(43, 145, 175);"&gt;Observable&lt;/span&gt;.FromEventPattern&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;MouseButtonEventArgs&lt;/span&gt;&amp;gt;(myPanel, &lt;span style="color: rgb(163, 21, 21);"&gt;"MouseLeftButtonDown"&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;)&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                                      &lt;span style="font-size: 8.5pt;"&gt;.Do(evt =&amp;gt; myPanel.CaptureMouse())&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt;                                             .Select(evt =&amp;gt; evt.EventArgs.GetPosition(myPanel));&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span style="font-size: 8.5pt;"&gt; var &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;mouseUpEvents = &lt;span style="color: rgb(43, 145, 175);"&gt;Observable&lt;/span&gt;.FromEventPattern&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;MouseButtonEventArgs&lt;/span&gt;&amp;gt;(myPanel, &lt;span style="color: rgb(163, 21, 21);"&gt;"MouseLeftButtonUp"&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;)&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                           &lt;span style="font-size: 8.5pt;"&gt;.Do(evt =&amp;gt; myPanel.ReleaseMouseCapture());&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span style="font-size: 8.5pt;"&gt; var &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;absoluteMousePositions = &lt;span style="color: rgb(43, 145, 175);"&gt;Observable&lt;/span&gt;.FromEventPattern&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;MouseEventArgs&lt;/span&gt;&amp;gt;(myPanel, &lt;span style="color: rgb(163, 21, 21);"&gt;"MouseMove"&lt;/span&gt;) &lt;br /&gt;                                        &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.Select(evt =&amp;gt; evt.EventArgs.GetPosition(&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;));&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;&lt;span style="font-size: 8.5pt;"&gt; IObservable&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Point&lt;/span&gt;&amp;gt; dragPoints = &lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt; relativeMouseDownPosition &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt; relativeMouseDownPositions&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt;                                 &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt; absoluteMousePosition &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt; absoluteMousePositions.TakeUntil(mouseUpEvents)&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt;                                 &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;select&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Point&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;(absoluteMousePosition.X - relativeMouseDownPosition.X,&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt;                                                  absoluteMousePosition.Y - relativeMouseDownPosition.Y); &lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt; &lt;br /&gt;&lt;br /&gt; dragPoints.ObserveOn(&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;SynchronizationContext&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.Current).Subscribe(point =&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt; {&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt;    &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Canvas&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.SetLeft(myPanel, point.X);&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt;    &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Canvas&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.SetTop(myPanel, point.Y);&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt; });  &lt;/span&gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Alcune considerazioni &lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;La prima cosa che salta all’occhio è come sia possibile convertire un evento .NET in una sequenza osservabile tramite il metodo &lt;span style="color: rgb(43, 145, 175);"&gt;&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.fromeventpattern(v=vs.103).aspx"&gt;Observable.FromEventPattern&lt;/a&gt;(…)&lt;/span&gt; , il quale permette di specificare il tipo di &lt;em&gt;EventArgs&lt;/em&gt; dell’evento, l’oggetto che espone l’evento da convertire ed il nome dell’evento. In particolare, la seconda riga di codice denota come sia possibile convertire l’evento &lt;em&gt;MouseLeftButtonUp&lt;/em&gt; dello StackPanel in una sequenza osservabile di tipo &lt;span style="color: rgb(43, 145, 175);"&gt;&lt;span style="font-size: 8.5pt;"&gt;IObservable&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;EventPattern&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;MouseButtonEventArgs&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&amp;gt;&amp;gt;&lt;/span&gt;.&lt;/li&gt;
    &lt;li&gt;Rx definisce un suo set di extension methods per comporre sequenze osservabili nello stesso modo in cui LINQ to Objects compone sequenze enumerabili. Ad esempio, il metodo &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/hh229530(v=VS.103).aspx"&gt;Observable.TakeUntil&amp;lt;TSource, TOther&amp;gt;(…)&lt;/a&gt; ritorna tutti gli elementi della sequenza osservabile sorgente finché l’altra sequenza osservabile non produce un valore. Nel nostro esempio, questo extension method è stato usato per filtrare gli eventi &lt;em&gt;MouseMove&lt;/em&gt; tra un evento &lt;em&gt;MouseLeftButtonDown&lt;/em&gt; ed un &lt;em&gt;MouseLeftButtonUp&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;Il metodo &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.observeon(v=VS.103).aspx"&gt;Observable.ObserveOn&amp;lt;TSource&amp;gt;(…)&lt;/a&gt; permette di fare in modo che le notifiche asincrone agli observer vengano effettuate su un thread o uno scheduler specificato. Nel mondo WPF, come in altre piattaforme che supportano un &lt;a target="_blank" href="http://msdn.microsoft.com/it-it/library/system.threading.synchronizationcontext(v=vs.95).aspx"&gt;SynchronizationContext&lt;/a&gt;, per evitare eccezioni cross-thread quando si interagisce con la UI di solito si interagisce con il contesto di sincronizzazione tramite la chiamata &lt;span style="font-size: 8.5pt;"&gt;ObserveOn(&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;SynchronizationContext&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.Current) &lt;/span&gt;che in WPF in particolare è costituito da un oggetto di tipo &lt;a target="_blank" href="http://msdn.microsoft.com/it-it/library/system.windows.threading.dispatchersynchronizationcontext.aspx"&gt;DispatcherSynchronizationContext&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;strong&gt;Note di installazione&lt;/strong&gt;: se stiamo lavorando su Visual Studio 2010, il modo più veloce per integrare Rx nel nostro progetto è &lt;a target="_blank" href="http://www.nuget.org/"&gt;NuGet&lt;/a&gt;. Digitando “Rx” sulla textbox di ricerca dovremmo ottenere la seguente schermata. In particolare, il package &lt;em&gt;Rx-Main&lt;/em&gt; referenzia l’assembly System.Reactive.dll mentre il package &lt;em&gt;Rx-Testing&lt;/em&gt; referenzia l’assembly Microsoft.Reactive.Testing.dll.&lt;/p&gt;
&lt;p&gt;  &lt;img alt="" src="http://img695.imageshack.us/img695/1229/immaginepgx.jpg" /&gt;&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/100299.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2011/08/25/wpf-drag-and-drop-con-rx.aspx</guid>
            <pubDate>Thu, 25 Aug 2011 17:27:33 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2011/08/25/wpf-drag-and-drop-con-rx.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/100299.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/100299.aspx</trackback:ping>
        </item>
        <item>
            <title>[WPF 4.0] Esportare dati dal controllo DataGrid</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/11/16/wpf-4.0-esportare-dati-dal-controllo-datagrid.aspx</link>
            <description>&lt;div&gt;
&lt;div&gt;         Il controllo DataGrid di WPF 4.0 permette di ottenere “gratis” l’esportazione         dei dati associati alla griglia in diversi formati tra cui plain text, CSV e HTML.         Tale funzionalità è esposta semplicemente tramite l’invocazione         del comando &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.applicationcommands.copy.aspx"&gt;             Copy&lt;/a&gt; sul controllo, che trasferisce nella Clipboard i dati contenuti nelle         celle selezionate, supportando i formati sopra citati (ovviamente i formati CSV         e HTML sono i più interessanti nell’ottica dell’esportazione         verso altre applicazioni). Nel seguente esempio viene mostrato come generare un file         CSV contenente tutte le righe visualizzate in un DataGrid, includendo le intestazioni         di colonna sulla prima riga.Il codice è veramente banale:&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;     &lt;span style="font-family: consolas;"&gt;myDataGrid.SelectAllCells();         &lt;br /&gt;
myDataGrid.ClipboardCopyMode = &lt;span style="color: rgb(43, 145, 175);"&gt;DataGridClipboardCopyMode&lt;/span&gt;.IncludeHeader;         &lt;br /&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;ApplicationCommands&lt;/span&gt;.Copy.Execute(&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;, myDataGrid);         &lt;br /&gt;
myDataGrid.UnselectAllCells();         &lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; csvData = (&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;)&lt;span style="color: rgb(43, 145, 175);"&gt;Clipboard&lt;/span&gt;.GetData(&lt;span style="color: rgb(43, 145, 175);"&gt;DataFormats&lt;/span&gt;.CommaSeparatedValue);         &lt;br /&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;Clipboard&lt;/span&gt;.Clear();         &lt;br /&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; (&lt;span style="color: rgb(43, 145, 175);"&gt;StreamWriter&lt;/span&gt;         writer = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;             StreamWriter&lt;/span&gt;(&lt;span style="color: rgb(163, 21, 21);"&gt;"C:\\test.csv"&lt;/span&gt;))         { writer.Write(csvData); }&lt;/span&gt;&lt;/div&gt;
&lt;span&gt;
&lt;div&gt;         &lt;br /&gt;
Se invece si sceglie l’HTML come formato di esportazione, ci dobbiamo attendere         un simpatico header aggiuntivo collocato fuori dal DOM che indica dove iniziano         e dove finiscono le differenti porzioni di dati. Si possono utilizzare tali informazioni         per esportare sia una pagina web intera piuttosto che soltanto il frammento relativo         alla tabella dati da inserire eventualmente in un’altro documento. In questo         caso l’esempio precedente va semplicemente modificato specificando &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dataformats.html.aspx"&gt;             DataFormats.Html&lt;/a&gt; come formato di estrazione dati dalla clipboard. Il risultato         che otteniamo è il seguente:&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;span style="font-family: consolas;"&gt;&lt;span style="font-family: consolas;"&gt;&lt;span style="font-family: consolas;"&gt;         &lt;span style="font-family: consolas;"&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;                 &lt;span style="font-family: consolas;"&gt;Version:1.0&lt;/span&gt;&lt;/div&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;                 &lt;span style="font-family: consolas;"&gt;StartHTML:00000097&lt;/span&gt;&lt;/div&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;                 &lt;span style="font-family: consolas;"&gt;EndHTML:00000672&lt;/span&gt;&lt;/div&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;                 &lt;span style="font-family: consolas;"&gt;StartFragment:00000133&lt;/span&gt;&lt;/div&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;                 &lt;span style="font-family: consolas;"&gt;EndFragment:00000636&lt;/span&gt;&lt;/div&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;                 &lt;span style="font-family: consolas;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;HTML&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;                 &lt;span style="font-family: consolas;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;BODY&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;
&lt;div&gt;                     &lt;span style="font-family: consolas;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&amp;lt;!--StartFragment--&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;                     &lt;span style="font-family: consolas;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;TABLE&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: consolas;"&gt;&lt;span style="font-family: consolas;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;...Dati...&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: consolas;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;TABLE&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span style="font-family: consolas;"&gt;&lt;span style="color: rgb(0, 128, 0); font-family: consolas;"&gt;&amp;lt;!--EndFragment--&amp;gt;&lt;br /&gt;
&lt;/span&gt;&lt;span style="font-family: consolas;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;BODY&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="MsoNormal" style="margin: 0cm 0cm 10pt; line-height: 13pt;"&gt;                     &lt;span style="font-family: consolas;"&gt;&lt;span style="line-height: 12pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;                         &amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span style="line-height: 12pt;"&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;HTML&lt;/span&gt;&lt;/span&gt;&lt;span style="line-height: 12pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:06882eda-9e32-4547-a6db-fd3b23ac7c14" style="margin: 0px; padding: 0px; float: none; display: inline;"&gt;     Tag di Technorati: &lt;a rel="tag" href="http://technorati.com/tags/WPF"&gt;WPF&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/DataGrid"&gt;DataGrid&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/99486.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/11/16/wpf-4.0-esportare-dati-dal-controllo-datagrid.aspx</guid>
            <pubDate>Tue, 16 Nov 2010 00:40:04 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/11/16/wpf-4.0-esportare-dati-dal-controllo-datagrid.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/99486.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/99486.aspx</trackback:ping>
        </item>
        <item>
            <title>[WPF] TextBox e input filtering</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/09/07/wpf-textbox-e-input-filtering.aspx</link>
            <description>&lt;p&gt;Quando si realizza un’interfaccia grafica per l’inserimento dati, è sempre buona prassi prevedere una prima "validazione" dell'input utente. Una tecnica molto semplice per raggiungere tale obiettivo potrebbe basarsi sull’idea di filtrare l’input in modo da non permettere l’inserimento di caratteri non validi. Nel caso della TextBox, in particolare, si potrebbe pensare di estendere il controllo affinché il filtraggio avvenga a fronte di un matching con un generica espressione regolare… una RegexTextBox dunque :).&lt;/p&gt;
&lt;pre style="MARGIN: auto"&gt;&lt;font face="Consolas"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;RegexTextBox&lt;/font&gt;&lt;/span&gt; : System.Windows.Controls.&lt;span&gt;&lt;font color="#2b91af"&gt;TextBox&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;{                &lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;  &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; Pattern { &lt;span&gt;&lt;font color="#0000ff"&gt;get&lt;/font&gt;&lt;/span&gt;; &lt;span&gt;&lt;font color="#0000ff"&gt;set&lt;/font&gt;&lt;/span&gt;; }&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt; &lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;  &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; RegexTextBox()&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;  {&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;     &lt;span&gt;&lt;font color="#2b91af"&gt;CommandBinding&lt;/font&gt;&lt;/span&gt; pasteCommandBinding = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;CommandBinding&lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#2b91af"&gt;ApplicationCommands&lt;/font&gt;&lt;/span&gt;.Paste);&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;     pasteCommandBinding.CanExecute += &lt;span&gt;&lt;font color="#0000ff"&gt;delegate&lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#0000ff"&gt;object&lt;/font&gt;&lt;/span&gt; sender, &lt;span&gt;&lt;font color="#2b91af"&gt;CanExecuteRoutedEventArgs&lt;/font&gt;&lt;/span&gt; e) &lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;     { &lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;       e.Handled = !IsValid(&lt;span&gt;&lt;font color="#2b91af"&gt;Clipboard&lt;/font&gt;&lt;/span&gt;.GetText()); &lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;     };&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;     &lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.CommandBindings.Add(pasteCommandBinding);&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;  }&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;        &lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;  &lt;span&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; OnPreviewTextInput(System.Windows.Input.&lt;span&gt;&lt;font color="#2b91af"&gt;TextCompositionEventArgs&lt;/font&gt;&lt;/span&gt; e)&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;  {                        &lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;     &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; newText = Text + e.Text;&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;     e.Handled = !IsValid(newText);            &lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;     &lt;span&gt;&lt;font color="#0000ff"&gt;base&lt;/font&gt;&lt;/span&gt;.OnPreviewTextInput(e);&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;  }&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt; &lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;  &lt;span&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;bool&lt;/font&gt;&lt;/span&gt; IsValid(&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; text)&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;  {&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;     &lt;span&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt; (&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;.IsNullOrEmpty(text)) &lt;span&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;true&lt;/font&gt;&lt;/span&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;     &lt;span&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;Regex&lt;/font&gt;&lt;/span&gt;(Pattern).IsMatch(text);&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;  }&lt;/font&gt;&lt;br /&gt;&lt;font face="Consolas"&gt;}&lt;/font&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;
Un esempio di utilizzo potrebbe essere il seguente (ammissione di soli numeri naturali):&lt;/p&gt;
&lt;pre style="MARGIN: auto"&gt;&lt;font face="Consolas"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#a31515"&gt;src&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;:&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#a31515"&gt;RegexTextBox&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#ff0000"&gt; Pattern&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;"^[0-9]+$"&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;&amp;gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#a31515"&gt;src&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;:&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#a31515"&gt;RegexTextBox&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;
Nel codice sopra riportato viene mostrata anche un’ accortezza che può risultare utile, ovvero il filtraggio dell’input in caso di operazioni di Cut/Copy and Paste. Tale controllo avviene agganciando la nostra RegexTextBox all’application command &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.input.applicationcommands.paste.aspx"&gt;ApplicationCommands.Paste&lt;/a&gt;, in modo da poter validare il contenuto della clipboard.&lt;/p&gt;
&lt;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:437f1953-8400-4693-98e6-b79417991a0c" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/WPF"&gt;WPF&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/TextBox"&gt;TextBox&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/99167.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/09/07/wpf-textbox-e-input-filtering.aspx</guid>
            <pubDate>Tue, 07 Sep 2010 22:13:49 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/09/07/wpf-textbox-e-input-filtering.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/99167.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/99167.aspx</trackback:ping>
        </item>
        <item>
            <title>[WPF] Evidenziare testo in una RichTextBox</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/08/24/wpf-evidenziare-testo-in-una-richtextbox.aspx</link>
            <description>&lt;p&gt;Una funzionalità fondamentale per text-editor/reader è l’evidenziazione programmatica di testo, magari utilizzando stili di formattazione diversi. In questo post vorrei mostrare una possibile implementazione di tale funzionalità utilizzando il controllo RichTextBox di WPF. Immaginando un approccio top-down, potremmo partire da un metodo &lt;em&gt;HilightText(…),&lt;/em&gt; il cui compito sia proprio quello di evidenziare del testo all’interno di una RichTextBox. &lt;/p&gt;
&lt;div style="FONT-FAMILY: courier new; FONT-SIZE: 8pt"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt; &lt;/span&gt;HilightText(&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt; &lt;/span&gt;pattern) &lt;br /&gt;
&lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;span style="mso-spacerun: yes"&gt;             &lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;&lt;font color="#000000"&gt;  &lt;/font&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;TextRange&lt;/font&gt;&lt;/span&gt;&amp;gt; ranges = GetMatchingTextRanges(pattern); &lt;br /&gt;
  &lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;foreach &lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#2b91af"&gt;TextRange&lt;/font&gt; &lt;/span&gt;textRange &lt;span&gt;&lt;font color="#0000ff"&gt;in&lt;/font&gt; &lt;/span&gt;ranges) HilightTextRange(textRange, &lt;span&gt;&lt;font color="#2b91af"&gt;Brushes&lt;/font&gt;&lt;/span&gt;.Black, &lt;span&gt;&lt;font color="#2b91af"&gt;Brushes&lt;/font&gt;&lt;/span&gt;.Yellow); &lt;span style="mso-spacerun: yes"&gt;            &lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
L’idea è quella di applicare un background giallo ed un foreground nero a tutti gli intervalli di testo (&lt;a target="_blank" href="http://msdn.microsoft.com/it-it/library/system.windows.documents.textrange.aspx"&gt;TextRange&lt;/a&gt;) che soddisfano un dato pattern-matching. &lt;br /&gt;
&lt;div style="FONT-FAMILY: courier new; FONT-SIZE: 8pt"&gt;&lt;br /&gt;
&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt; &lt;/span&gt;HilightTextRange(&lt;span&gt;&lt;font color="#2b91af"&gt;TextRange&lt;/font&gt; &lt;/span&gt;textRange, &lt;span&gt;&lt;font color="#2b91af"&gt;Brush&lt;/font&gt; &lt;/span&gt;foregroundBrush, &lt;span&gt;&lt;font color="#2b91af"&gt;Brush&lt;/font&gt; &lt;/span&gt;backgroundBrush) &lt;br /&gt;
&lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
  &lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;if &lt;/font&gt;&lt;/span&gt;(foregroundBrush != &lt;span&gt;&lt;font color="#0000ff"&gt;null&lt;/font&gt;&lt;/span&gt;) textRange.ApplyPropertyValue(&lt;span&gt;&lt;font color="#2b91af"&gt;TextElement&lt;/font&gt;&lt;/span&gt;.ForegroundProperty, foregroundBrush); &lt;br /&gt;
  &lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;if &lt;/font&gt;&lt;/span&gt;(backgroundBrush != &lt;span&gt;&lt;font color="#0000ff"&gt;null&lt;/font&gt;&lt;/span&gt;) textRange.ApplyPropertyValue(&lt;span&gt;&lt;font color="#2b91af"&gt;TextElement&lt;/font&gt;&lt;/span&gt;.BackgroundProperty, backgroundBrush); &lt;br /&gt;
&lt;/span&gt;&lt;span&gt;} &lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
Ora ci troviamo di fronte all’esigenza di determinare gli intervalli di testo coinvolti nel matching. Definiamo dunque un metodo &lt;em&gt;GetMatchingTextRanges(…)&lt;/em&gt;, il cui compito è di navigare l’intero documento della RichTextBox (un &lt;a target="_blank" href="http://msdn.microsoft.com/it-it/library/system.windows.documents.flowdocument.aspx"&gt;FlowDocument&lt;/a&gt;) analizzando esclusivamente gli elementi (inlines) di tipo &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.documents.run.aspx"&gt;Run&lt;/a&gt;, ovvero quelli che contengono testo.
&lt;div style="FONT-FAMILY: courier new; FONT-SIZE: 8pt"&gt;&lt;br /&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;TextRange&lt;/font&gt;&lt;/span&gt;&amp;gt; GetMatchingTextRanges(&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt; &lt;/span&gt;pattern) &lt;br /&gt;
&lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;&lt;font color="#000000"&gt;   &lt;/font&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;TextRange&lt;/font&gt;&lt;/span&gt;&amp;gt; ranges = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;TextRange&lt;/font&gt;&lt;/span&gt;&amp;gt;(); &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;  &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;&lt;font color="#000000"&gt;   &lt;/font&gt;TextPointer &lt;/font&gt;&lt;/span&gt;textNavigator = richTextBox.Document.ContentStart; &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;   &lt;/font&gt;while &lt;/font&gt;&lt;/span&gt;&lt;span&gt;(textNavigator.CompareTo(richTextBox.Document.ContentEnd) &amp;lt; 0) &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span&gt;&lt;span style="mso-spacerun: yes"&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;&lt;font color="#000000"&gt;      &lt;/font&gt;TextPointerContext &lt;/font&gt;&lt;/span&gt;context = textNavigator.GetPointerContext(&lt;span&gt;&lt;font color="#2b91af"&gt;LogicalDirection&lt;/font&gt;&lt;/span&gt;.Backward); &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;      &lt;/font&gt;if &lt;/font&gt;&lt;/span&gt;(context == &lt;span&gt;&lt;font color="#2b91af"&gt;TextPointerContext&lt;/font&gt;&lt;/span&gt;.ElementStart &amp;amp;&amp;amp; textNavigator.Parent &lt;span&gt;&lt;font color="#0000ff"&gt;is&lt;/font&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;Run&lt;/font&gt;&lt;/span&gt;) &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;      { &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;&lt;font color="#000000"&gt;        &lt;/font&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;TextRange&lt;/font&gt;&lt;/span&gt;&amp;gt; runRanges = GetMatchingTextRanges((&lt;span&gt;&lt;font color="#2b91af"&gt;Run&lt;/font&gt;&lt;/span&gt;)textNavigator.Parent, pattern); &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;        &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt; &lt;/span&gt;(runRanges.Count &amp;gt; 0) ranges.AddRange(runRanges); &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;      &lt;/span&gt;} &lt;br /&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;      textNavigator = textNavigator.GetNextContextPosition(&lt;span&gt;&lt;font color="#2b91af"&gt;LogicalDirection&lt;/font&gt;&lt;/span&gt;.Forward); &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span&gt;  &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span&gt;&lt;span style="mso-spacerun: yes"&gt;   &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt; &lt;/span&gt;ranges; &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span&gt;} &lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
A questo punto, per ogni Run trovato, è possibile controllare se esistono porzioni di testo in esso contenuti che soddisfano il pattern di ricerca. In caso positivo, possiamo aggiungerle alla lista dei TextRange da evidenziare. &lt;br /&gt;
&lt;div style="FONT-FAMILY: courier new; FONT-SIZE: 8pt"&gt;&lt;br /&gt;
&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;TextRange&lt;/font&gt;&lt;/span&gt;&amp;gt; GetMatchingTextRanges(&lt;span&gt;&lt;font color="#2b91af"&gt;Run&lt;/font&gt; &lt;/span&gt;run, &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt; &lt;/span&gt;pattern) &lt;/span&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;span style="mso-spacerun: yes"&gt;            &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;&lt;font color="#000000"&gt;   &lt;/font&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;TextRange&lt;/font&gt;&lt;/span&gt;&amp;gt; ranges = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;TextRange&lt;/font&gt;&lt;/span&gt;&amp;gt;(); &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;&lt;font color="#000000"&gt;   &lt;/font&gt;MatchCollection &lt;/font&gt;&lt;/span&gt;matches = &lt;span&gt;&lt;font color="#2b91af"&gt;Regex&lt;/font&gt;&lt;/span&gt;.Matches(run.Text, pattern); &lt;span style="mso-spacerun: yes"&gt;            &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;  &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;   &lt;/font&gt;foreach &lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#2b91af"&gt;Match&lt;/font&gt; &lt;/span&gt;match &lt;span&gt;&lt;font color="#0000ff"&gt;in&lt;/font&gt; &lt;/span&gt;matches) &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;   { &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;&lt;font color="#000000"&gt;     &lt;/font&gt;TextPointer &lt;/font&gt;&lt;/span&gt;startPosition = GetContentTextPointer(run.ContentStart, match.Index - 1); &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;&lt;font color="#000000"&gt;     &lt;/font&gt;TextPointer &lt;/font&gt;&lt;/span&gt;endPosition = GetContentTextPointer(run.ContentStart, match.Index + match.Length - 1); &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;     ranges.Add(&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;TextRange&lt;/font&gt;&lt;/span&gt;(startPosition, endPosition)); &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span&gt;   } &lt;br /&gt;
&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;   &lt;/font&gt;return &lt;/font&gt;&lt;/span&gt;ranges; &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span&gt;} &lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
Come si stabiliscono gli estremi dei TextRange da evidenziare all’interno di ciascun Run? Anzitutto, tramite la classe &lt;a target="_blank" href="http://msdn.microsoft.com/it-it/library/system.text.regularexpressions.regex(VS.80).aspx"&gt;Regex&lt;/a&gt; riusciamo a capire per ciascun match quali sono gli indici dei caratteri iniziali all’interno del testo del Run. Poi, ricordando che per calcolare l’offset corretto all’interno di ciascun Run non dobbiamo considerare i caratteri (un Run può contenere altri tipi di simboli) bensì i &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.documents.textpointer.aspx"&gt;TextPointer&lt;/a&gt; che sono adiacenti al testo di interesse, definiamo il seguente metodo:
&lt;div style="FONT-FAMILY: courier new; FONT-SIZE: 8pt"&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt; &lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;TextPointer&lt;/font&gt; &lt;/span&gt;GetContentTextPointer(&lt;span&gt;&lt;font color="#2b91af"&gt;TextPointer&lt;/font&gt; &lt;/span&gt;contentStart, &lt;span&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt; &lt;/span&gt;offset) &lt;br /&gt;
&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
&lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;&lt;font color="#000000"&gt;  &lt;/font&gt;TextPointer &lt;/font&gt;&lt;/span&gt;result = contentStart; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;  &lt;/font&gt;int &lt;/font&gt;&lt;/span&gt;i = 0; &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;  &lt;/font&gt;while &lt;/font&gt;&lt;/span&gt;(i &amp;lt; offset &amp;amp;&amp;amp; result != &lt;span&gt;&lt;font color="#0000ff"&gt;null&lt;/font&gt;&lt;/span&gt;) &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;  { &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;    &lt;/font&gt;if &lt;/font&gt;&lt;/span&gt;(result.GetPointerContext(&lt;span&gt;&lt;font color="#2b91af"&gt;LogicalDirection&lt;/font&gt;&lt;/span&gt;.Backward) == &lt;span&gt;&lt;font color="#2b91af"&gt;TextPointerContext&lt;/font&gt;&lt;/span&gt;.Text || &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;        result.GetPointerContext(&lt;span&gt;&lt;font color="#2b91af"&gt;LogicalDirection&lt;/font&gt;&lt;/span&gt;.Backward) == &lt;span&gt;&lt;font color="#2b91af"&gt;TextPointerContext&lt;/font&gt;&lt;/span&gt;.None) &lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;i++; &lt;br /&gt;
&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;&lt;br /&gt;
    if &lt;/font&gt;&lt;/span&gt;(result.GetPositionAtOffset(1, &lt;span&gt;&lt;font color="#2b91af"&gt;LogicalDirection&lt;/font&gt;&lt;/span&gt;.Forward) == &lt;span&gt;&lt;font color="#0000ff"&gt;null&lt;/font&gt;&lt;/span&gt;) &lt;span&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt; &lt;/span&gt;result; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;  &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt;    result = result.GetPositionAtOffset(1, &lt;span&gt;&lt;font color="#2b91af"&gt;LogicalDirection&lt;/font&gt;&lt;/span&gt;.Forward); &lt;br /&gt;
&lt;span&gt;  } &lt;br /&gt;
&lt;span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;  return&lt;/font&gt; &lt;/span&gt;result; &lt;br /&gt;
&lt;/span&gt;&lt;span style="LINE-HEIGHT: 9pt; mso-ansi-language: it; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;} &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
Finalmente il gioco è fatto. Di seguito riportiamo un esempio di output ottenuto invocando HilightText(“labor”); &lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://img839.imageshack.us/img839/6521/immaginemm.jpg" /&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;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:7056ac30-06f1-4add-9788-79850a3d44b0" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/WPF"&gt;WPF&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/RichTextBox"&gt;RichTextBox&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/99110.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/08/24/wpf-evidenziare-testo-in-una-richtextbox.aspx</guid>
            <pubDate>Tue, 24 Aug 2010 23:01:53 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/08/24/wpf-evidenziare-testo-in-una-richtextbox.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/99110.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/99110.aspx</trackback:ping>
        </item>
        <item>
            <title>[WPF] MVVM e Splash Screen</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/05/30/wpf-mvvm-e-splash-screen.aspx</link>
            <description>&lt;p&gt;Durante lo sviluppo di applicazioni WPF di una certa “pesantezza”, può essere utile ricorrere a Splash Screen aggiornabili in tempo reale che notifichino all’utente lo stato di avanzamento del caricamento dei vari moduli, ad esempio tramite elementi di testo piuttosto che barre di progresso. A volte, infatti, può non essere sufficiente una semplice immagine impostabile tramite la Build Action "SplashScreen" di Visual Studio.&lt;br /&gt;
In questo post vorrei quindi mostrare una possibile implementazione di uno Splash Screen aggiornabile in tempo reale usando il pattern MVVM.  &lt;br /&gt;
&lt;br /&gt;
Per semplificare, supponiamo di posizionare nel Main la pesantissima sequenza di caricamento della nostra applicazione:&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: blue; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;public&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Program &lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;[&lt;span style="COLOR: #2b91af"&gt;STAThread&lt;/span&gt;] &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Main(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;[] args) &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: #2b91af"&gt;App&lt;/span&gt; app = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;App&lt;/span&gt;(); &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;app.InitializeComponent();  &lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: green"&gt;// Load resources...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;            &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: #2b91af"&gt;&lt;font color="#000000"&gt;    &lt;/font&gt;MainWindow&lt;/span&gt; mainWindow = &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;; &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;SplashScreenViewModel&lt;/span&gt; splashScreenViewModel = &lt;strong&gt;&lt;span style="COLOR: #2b91af"&gt;SplashScreen&lt;/span&gt;.ShowSplashScreen()&lt;/strong&gt;) &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
      &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;splashScreenViewModel.StatusText = &lt;span style="COLOR: #a31515"&gt;"Initializing..."&lt;/span&gt;;  &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;               &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;   &lt;br /&gt;
&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: green"&gt;     // Loading application modules...&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;
&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: #2b91af"&gt;&lt;font color="#000000"&gt;      &lt;/font&gt;Thread&lt;/span&gt;.Sleep(3000); &lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: green"&gt;// Simulate delay...&lt;/span&gt;&lt;/span&gt;  &lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;      &lt;/span&gt;mainWindow = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;MainWindow&lt;/span&gt;();&lt;/span&gt;&lt;/span&gt; &lt;/p&gt;
&lt;p&gt; &lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;      &lt;/span&gt;splashScreenViewModel.StatusText = &lt;span style="COLOR: #a31515"&gt;"Initialized."&lt;/span&gt;;  &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;      &lt;/span&gt;&lt;span style="COLOR: #2b91af"&gt;Thread&lt;/span&gt;.Sleep(1000); &lt;br /&gt;
   &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;} &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;&lt;span style="mso-spacerun: yes"&gt;            &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;&lt;span style="mso-spacerun: yes"&gt;     &lt;/span&gt;app.Run(mainWindow); &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;}&lt;span style="mso-spacerun: yes"&gt;        &lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
Al fine di evitare fastidiosi effetti di freezing della GUI mentre il thread principale sta caricando i vari pezzi della nostra applicazione, la window dello Splash Screen va fatta girare necessariamente su un thread separato. Al termine della sequenza di caricamento, il thread principale deve poter chiudere lo Splash Screen utilizzando il &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.aspx"&gt;Dispatcher&lt;/a&gt; corretto. &lt;br /&gt;
Vediamo quindi il codice della view:&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: blue; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;public&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt; &lt;span style="COLOR: blue"&gt;partial&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;SplashScreen&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;Window &lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; splashScreenlockObj = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt;(); &lt;/span&gt; &lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;&lt;font color="#000000"&gt;  &lt;/font&gt;public&lt;/span&gt; SplashScreen() &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;InitializeComponent();  &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;DataContext = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;SplashScreenViewModel&lt;/span&gt;(); &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;&lt;font color="#000000"&gt;  &lt;/font&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;SplashScreenViewModel&lt;/span&gt; ShowSplashScreen() &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;lock&lt;/span&gt; (splashScreenlockObj) &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
     &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: #2b91af"&gt;SplashScreenViewModel&lt;/span&gt; splashScreenViewModel = &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;;  &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;     &lt;/span&gt;&lt;span style="COLOR: #2b91af"&gt;ManualResetEvent&lt;/span&gt; resetEvent = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;ManualResetEvent&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;false&lt;/span&gt;); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;     &lt;/span&gt;&lt;span style="COLOR: #2b91af"&gt;Thread&lt;/span&gt; splashScreenThread = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Thread&lt;/span&gt;(() =&amp;gt; &lt;br /&gt;
     &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
       &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: #2b91af"&gt;Dispatcher&lt;/span&gt;.CurrentDispatcher.BeginInvoke((&lt;span style="COLOR: #2b91af"&gt;Action&lt;/span&gt;)&lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;()  &lt;br /&gt;
       &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
         &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: #2b91af"&gt;SplashScreen&lt;/span&gt; splashScreenWindow = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;SplashScreen&lt;/span&gt;(); &lt;br /&gt;
         &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;splashScreenViewModel = (&lt;span style="COLOR: #2b91af"&gt;SplashScreenViewModel&lt;/span&gt;)splashScreenWindow.DataContext; &lt;br /&gt;
         &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;splashScreenViewModel.Dispatcher = &lt;span style="COLOR: #2b91af"&gt;Dispatcher&lt;/span&gt;.CurrentDispatcher; &lt;br /&gt;
         &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;resetEvent.Set(); &lt;br /&gt;
         &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;splashScreenWindow.Show();  &lt;br /&gt;
       &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;}); &lt;br /&gt;
       &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: #2b91af"&gt;Dispatcher&lt;/span&gt;.Run(); &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;      &lt;/span&gt;}); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;              &lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;splashScreenThread.SetApartmentState(&lt;span style="COLOR: #2b91af"&gt;ApartmentState&lt;/span&gt;.STA); &lt;br /&gt;
      &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;splashScreenThread.IsBackground = &lt;span style="COLOR: blue"&gt;true&lt;/span&gt;;  &lt;br /&gt;
      &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;splashScreenThread.Start(); &lt;/span&gt;&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;resetEvent.WaitOne(); &lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: green"&gt;// Wait for viewmodel initialization...&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
      &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;&lt;span style="COLOR: blue"&gt;return&lt;/span&gt; splashScreenViewModel; &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;} &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;} &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Il metodo statico ShowSplashScreen() visualizza lo splash screen e comunica al ViewModel quale Dispatcher utilizzare per la chiusura (&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.invokeshutdown.aspx"&gt;InvokeShutdown()&lt;/a&gt;).&lt;/p&gt;
&lt;p style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: blue; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;public&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;SplashScreenViewModel&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;ViewModelBase&lt;/span&gt;, &lt;span style="COLOR: #2b91af"&gt;IDisposable &lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; _statusText = &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;; &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; StatusText &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _statusText; } &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;set&lt;/span&gt; &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
      &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (_statusText == &lt;span style="COLOR: blue"&gt;value&lt;/span&gt;) &lt;span style="COLOR: blue"&gt;return&lt;/span&gt;;  &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;      &lt;/span&gt;_statusText = &lt;span style="COLOR: blue"&gt;value&lt;/span&gt;; &lt;br /&gt;
      &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;OnPropertyChanged(&lt;span style="COLOR: #a31515"&gt;"StatusText"&lt;/span&gt;); &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;} &lt;br /&gt;
   &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;} &lt;br /&gt;
&lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Dispatcher&lt;/span&gt; Dispatcher { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; } &lt;br /&gt;
&lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Dispose() &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (Dispatcher != &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;{ &lt;br /&gt;
      &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;Dispatcher.InvokeShutdown(); &lt;br /&gt;
      &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;Dispatcher = &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;; &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;} &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;} &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;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:3b55f672-d399-4f29-8b20-8f1e6d0a30d3" class="wlWriterEditableSmartContent"&gt;Technorati Tag: &lt;a rel="tag" href="http://technorati.com/tags/WPF"&gt;WPF&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/MVVM"&gt;MVVM&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/98688.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/05/30/wpf-mvvm-e-splash-screen.aspx</guid>
            <pubDate>Sun, 30 May 2010 22:36:57 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/05/30/wpf-mvvm-e-splash-screen.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/98688.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/98688.aspx</trackback:ping>
        </item>
        <item>
            <title>[WPF] Ereditare controlli da classi generiche</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/03/29/wpf-ereditare-controlli-da-classi-generiche.aspx</link>
            <description>&lt;!--DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"--&gt;
&lt;p&gt;In applicazioni WPF di una certa complessità è molto facile trovarsi in situazioni in cui è utile sfruttare classi base per i controlli (es. &lt;em&gt;UserControl e&lt;/em&gt; &lt;em&gt;Window)&lt;/em&gt;. In architetture MVVM, ad esempio, è possibile far ereditare i vari controlli da classi base generiche. Tuttavia, l’ implementazione dell’ereditarietà generica in WPF talvolta non è proprio immediata, soprattutto perché non sempre gli errori di build sono esplicativi.  &lt;br /&gt;
In questo semplicissimo esempio di MVVM viene mostrato come si può specificare la classe base generica di una Window direttamente nello XAML. &lt;br /&gt;
&lt;br /&gt;
Partiamo dalla Window:&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: blue; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;public&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt; &lt;span style="COLOR: blue"&gt;partial&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;CustomersWindow&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;WindowBase&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;CustomersViewModel&lt;/span&gt;&amp;gt; &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{        &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; CustomersWindow() : &lt;span style="COLOR: blue"&gt;base&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;CustomersViewModel&lt;/span&gt;()) &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{            &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;InitializeComponent();                         &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;} &lt;br /&gt;
  ... &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;}&lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;La classe base generica della Window potrebbe essere qualcosa del genere...&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: blue; FONT-SIZE: 8pt"&gt;public&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;WindowBase&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="COLOR: #2b91af"&gt;Window&lt;/span&gt; &lt;span style="COLOR: blue"&gt;where&lt;/span&gt; T : &lt;span style="COLOR: #2b91af"&gt;ViewModelBase &lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; T ViewModel { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt;; } &lt;br /&gt;
&lt;br /&gt;
  &lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; WindowBase() { }&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; WindowBase(T viewModel) &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;{ &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.ViewModel = viewModel; &lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: blue"&gt;base&lt;/span&gt;.Dat&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;aContext = viewModel; &lt;br /&gt;
  &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;} &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt"&gt;} &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Arriviamo quindi al punto. Lo XAML che permette di specificare l’ereditarietà da classi generiche diventa:&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: blue; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: #a31515; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;src&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: blue; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;:&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: #a31515; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;WindowBase&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt; &lt;br /&gt;
     &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: red"&gt;xmlns&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="&lt;a href="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&gt;http://schemas.microsoft.com/winfx/2006/xaml/presentation&lt;/a&gt;" &lt;br /&gt;
     &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: red"&gt;xmlns&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: red"&gt;x&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="&lt;a href="http://schemas.microsoft.com/winfx/2006/xaml"&gt;http://schemas.microsoft.com/winfx/2006/xaml&lt;/a&gt;"&lt;/span&gt;    &lt;br /&gt;
     &lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: red"&gt;&lt;strong&gt;xmlns&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: red"&gt;src&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="clr-namespace:MyApplication" &lt;br /&gt;
     &lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: red"&gt;x&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: red"&gt;Class&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="MyApplication.CustomersWindow"&lt;/span&gt; &lt;br /&gt;
     &lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&lt;span style="COLOR: red"&gt;x:&lt;/span&gt;&lt;span style="COLOR: red"&gt;TypeArguments&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="src:CustomersViewModel"&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: blue; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt; ...&amp;gt;&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;    &lt;br /&gt;
 &lt;/span&gt;... &lt;br /&gt;
&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: blue; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: #a31515; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;src&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: blue; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;:&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: #a31515; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;WindowBase&lt;/span&gt;&lt;span style="FONT-FAMILY: &amp;quot;Courier New&amp;quot;; COLOR: blue; FONT-SIZE: 8pt; mso-ansi-language: en-us" lang="EN-US"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Tramite &lt;em&gt;x:TypeArguments&lt;/em&gt; possiamo specificare il tipo generico della classe base.  &lt;br /&gt;
&lt;br /&gt;
ATTENZIONE: questa tecnica è applicabile &lt;strong&gt;solo per il nodo root&lt;/strong&gt; del documento XAML.&lt;br /&gt;
&lt;/p&gt;
&lt;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:ba928733-0917-4f81-83e1-504edf2bc2a6" class="wlWriterEditableSmartContent"&gt;Technorati Tag: &lt;a rel="tag" href="http://technorati.com/tags/WPF"&gt;WPF&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/Generics"&gt;Generics&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/Window"&gt;Window&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/Controls"&gt;Controls&lt;/a&gt;&lt;/div&gt;
&lt;div style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" class="wlWriterEditableSmartContent"&gt;
&lt;p&gt; &lt;/p&gt;
&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/98276.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/03/29/wpf-ereditare-controlli-da-classi-generiche.aspx</guid>
            <pubDate>Mon, 29 Mar 2010 14:48:27 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2010/03/29/wpf-ereditare-controlli-da-classi-generiche.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/98276.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/98276.aspx</trackback:ping>
        </item>
        <item>
            <title>[WPF] Un &amp;ldquo;generic&amp;rdquo; command</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2009/10/17/wpf-un-ldquogenericrdquo-command.aspx</link>
            <description>&lt;p&gt;Analizzando diverse soluzioni WPF che sfruttano l’architettura M-V-VM, mi è saltata all’occhio una strategia di implementazione dell’interfaccia &lt;a href="http://msdn.microsoft.com/it-it/library/system.windows.input.icommand.aspx" target="_blank"&gt;ICommand&lt;/a&gt; semplice e potente a mio modo di vedere. Andiamo direttamente al codice:&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;public&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;GenericCommand&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color: #2b91af"&gt;ICommand        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Predicate&lt;/span&gt;&amp;lt;T&amp;gt; CanExecuteDelegate { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;T&amp;gt; ExecuteDelegate { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;span style="mso-spacerun: yes"&gt;        &lt;br /&gt;        &lt;br /&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; CanExecute(&lt;span style="color: blue"&gt;object&lt;/span&gt; parameter)       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt; (CanExecuteDelegate != &lt;span style="color: blue"&gt;null&lt;/span&gt;) &lt;span style="color: blue"&gt;return&lt;/span&gt; CanExecuteDelegate((T)parameter);       &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;return&lt;/span&gt; &lt;span style="color: blue"&gt;true&lt;/span&gt;;       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}      &lt;br /&gt;      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;event&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EventHandler&lt;/span&gt; CanExecuteChanged       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;add&lt;/span&gt; { &lt;span style="color: #2b91af"&gt;CommandManager&lt;/span&gt;.RequerySuggested += &lt;span style="color: blue"&gt;value&lt;/span&gt;; }       &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;remove&lt;/span&gt; { &lt;span style="color: #2b91af"&gt;CommandManager&lt;/span&gt;.RequerySuggested -= &lt;span style="color: blue"&gt;value&lt;/span&gt;; }       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}      &lt;br /&gt;      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Execute(&lt;span style="color: blue"&gt;object&lt;/span&gt; parameter)       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt; (ExecuteDelegate != &lt;span style="color: blue"&gt;null&lt;/span&gt;) ExecuteDelegate((T)parameter);       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-no-proof: yes"&gt;}&lt;span style="mso-spacerun: yes"&gt;        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-no-proof: yes"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;Sostanzialmente l’obiettivo di questo &lt;em&gt;GenericCommand&lt;/em&gt; è di permettere una “tipizzazione” dichiarativa del parametro gestito dall’ interfaccia ICommand, in modo tale da poter costruire ViewModel contenenti delegati che gestiscono il pattern &lt;em&gt;CanExecute/Execute&lt;/em&gt; operando a nostro piacimento su parametri tipizzati passati magari direttamente dalla View. Ecco un esempio molto semplice di ViewModel...&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;public&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ContactsViewModel        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ObservableCollection&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; Contacts { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;GenericCommand&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; AddContact { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;GenericCommand&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt; ClearContacts { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;span style="mso-spacerun: yes"&gt;        &lt;br /&gt;        &lt;br /&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; ContactsViewModel()       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Contacts = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ObservableCollection&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;();       &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;AddContact = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;GenericCommand&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;();       &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;ClearContacts = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;GenericCommand&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;();       &lt;br /&gt;      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;AddContact.CanExecuteDelegate += &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Predicate&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;(AddContact_CanExecute);       &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;AddContact.ExecuteDelegate += &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;(AddContact_Execute);       &lt;br /&gt;      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;ClearContacts.CanExecuteDelegate += &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Predicate&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;(ClearContacts_CanExecute);       &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;ClearContacts.ExecuteDelegate += &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;(ClearContacts_Execute);       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}  &lt;br /&gt;      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;bool&lt;/span&gt; AddContact_CanExecute(&lt;span style="color: blue"&gt;string&lt;/span&gt; contactName) { &lt;span style="color: blue"&gt;return&lt;/span&gt; (!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(contactName)); }  &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;void&lt;/span&gt; AddContact_Execute(&lt;span style="color: blue"&gt;string&lt;/span&gt; contactName) { Contacts.Add(contactName); }  &lt;br /&gt;      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;bool&lt;/span&gt; ClearContacts_CanExecute(&lt;span style="color: blue"&gt;object&lt;/span&gt; parameter) { &lt;span style="color: blue"&gt;return&lt;/span&gt; (Contacts.Count &amp;gt; 0); }  &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;void&lt;/span&gt; ClearContacts_Execute(&lt;span style="color: blue"&gt;object&lt;/span&gt; parameter) { Contacts.Clear(); }&lt;span style="mso-spacerun: yes"&gt;       &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-no-proof: yes"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;...e per chiudere il cerchio riporto anche lo XAML saliente di una View di esempio.  &lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;TextBox&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Name&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="txtContactName"&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; ...&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; /&amp;gt;      &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Button&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: red"&gt;Command&lt;/span&gt;&lt;span style="color: blue"&gt;="{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: red"&gt; AddContact&lt;/span&gt;&lt;span style="color: blue"&gt;}"&lt;/span&gt;&lt;span style="color: red"&gt; CommandParameter&lt;/span&gt;&lt;span style="color: blue"&gt;="{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: red"&gt; ElementName&lt;/span&gt;&lt;span style="color: blue"&gt;=txtContactName,&lt;/span&gt;&lt;span style="color: red"&gt; Path&lt;/span&gt;&lt;span style="color: blue"&gt;=Text}" ...&amp;gt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Add Contact&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Button&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;ListBox&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;ItemsSource&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="{&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Binding&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Contacts&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}" ... /&amp;gt;      &lt;br /&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Button&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Command&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="{&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Binding&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; ClearContacts&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}" ...&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Clear Contacts&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Button&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-ansi-language: en-us" lang="EN-US"&gt; &lt;/span&gt;    &lt;/p&gt;&lt;p /&gt;   &lt;p /&gt;  &lt;p&gt;   &lt;br /&gt;Cosa ne pensate?&lt;/p&gt;  &lt;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:b710a5df-d461-4331-beff-0d69370a4c09" class="wlWriterEditableSmartContent"&gt;Technorati Tag: &lt;a href="http://technorati.com/tags/WPF" rel="tag"&gt;WPF&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ICommand" rel="tag"&gt;ICommand&lt;/a&gt;,&lt;a href="http://technorati.com/tags/M-V-VM" rel="tag"&gt;M-V-VM&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/97272.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2009/10/17/wpf-un-ldquogenericrdquo-command.aspx</guid>
            <pubDate>Sat, 17 Oct 2009 12:41:24 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2009/10/17/wpf-un-ldquogenericrdquo-command.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/97272.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/97272.aspx</trackback:ping>
        </item>
        <item>
            <title>[WPF] Window non rettangolari</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2009/09/26/wpf-window-non-rettangolari.aspx</link>
            <description>&lt;p&gt;La possibilità di creare Window di forma irregolare costituisce a mio modo di vedere uno dei più divertenti nonché semplici vantaggi di WPF.    &lt;br /&gt;In genere, ogni tecnica di realizzazione di Window dalla forma completamente personalizzata si basa sulla valorizzazione preliminare di tre proprietà:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/it-it/library/system.windows.window.allowstransparency.aspx" target="_blank"&gt;Window.AllowsTransparency&lt;/a&gt; = True &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/it-it/library/system.windows.window.windowstyle.aspx" target="_blank"&gt;Window.WindowStyle&lt;/a&gt; = None &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/it-it/library/system.windows.controls.control.background.aspx" target="_blank"&gt;Window.Background&lt;/a&gt; = Transparent &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In questo modo siamo subito svincolati sia dalla forma rettangolare standard della nostra Window, che dalla barra standard del titolo. Si aprono quindi diverse possibilità di sviluppo. E’ possibile ad esempio sfruttare immagini semitrasparenti come background della Window (scelta semplice e di veloce realizzazione, ma non consigliabile in WPF dal momento che la Window subirebbe un rendering con più pixel in sistemi con maggiori DPIs). Una soluzione sicuramente più potente sfrutta invece il programming model che WPF ci mette a disposizione relativamente alla grafica vettoriale: in altre parole, per creare una Window dai bordi arrotondati basta partire dall’elemento &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.border.aspx" target="_blank"&gt;Border&lt;/a&gt;.     &lt;br /&gt;Vorrei riportare un esempio che mi è rimasto impresso dopo aver letto il libro “&lt;a href="http://www.amazon.com/Pro-WPF-2008-Presentation-Professionals/dp/1590599551" target="_blank"&gt;Pro WPF in C# 2008&lt;/a&gt;” : creare una Window dalla forma irregolare, con bordi arrotondati.    &lt;br /&gt;N.B.: tralascio volutamente ogni questione di carattere architetturale ( es. realizzazione di custom control template per le nostre Window ).     &lt;br /&gt;    &lt;br /&gt;&lt;img src="http://img17.imageshack.us/img17/8228/windowjm.jpg" /&gt;     &lt;br /&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Codice XAML:      &lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Window&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; x&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;:&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Class&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="WPF_Demo.ShapedWindow"&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: red"&gt;        xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;="http://schemas.microsoft.com/winfx/2006/xaml"        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: red"&gt;        ...&lt;/span&gt; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;   &lt;/span&gt;&lt;span style="color: red"&gt;&lt;span style="mso-spacerun: yes"&gt;  &lt;br /&gt;        &lt;/span&gt;AllowsTransparency&lt;/span&gt;&lt;span style="color: blue"&gt;="True"&lt;/span&gt;&lt;span style="color: red"&gt; WindowStyle&lt;/span&gt;&lt;span style="color: blue"&gt;="None"&lt;/span&gt;&lt;span style="color: red"&gt; Background&lt;/span&gt;&lt;span style="color: blue"&gt;="Transparent"&lt;/span&gt;&lt;span style="color: red"&gt; ResizeMode&lt;/span&gt;&lt;span style="color: blue"&gt;="CanResizeWithGrip"&amp;gt;        &lt;br /&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Border&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; ...&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; CornerRadius&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="0,20,30,20"&amp;gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;       &lt;br /&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Grid&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;          &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;             &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;RowDefinition&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Height&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="Auto"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;RowDefinition&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;             &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;RowDefinition&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;RowDefinition&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;             &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;RowDefinition&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Height&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="Auto"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;RowDefinition&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;          &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;     &lt;br /&gt;         &lt;br /&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;TextBlock&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Text&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="Title"&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; ...&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; MouseLeftButtonDown&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="WindowDragMove"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;TextBlock&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;      &lt;br /&gt;        &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Button&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; ...&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Command&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="Close"&amp;gt;      &lt;br /&gt;           &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Button.Content&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;              &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Image&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Source&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="..."&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Stretch&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="Fill"&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Image&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;           &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Button.Content&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;        &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Button&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;      &lt;br /&gt;        &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Grid&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Grid.Row&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="1"&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Background&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="White"&amp;gt;      &lt;br /&gt;            &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Rectangle&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Grid.RowSpan&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="3"&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Width&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="5"&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; VerticalAlignment&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="Stretch"&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; HorizontalAlignment&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="Right"      &lt;br /&gt;                       &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: red"&gt;Cursor&lt;/span&gt;&lt;span style="color: blue"&gt;="SizeWE"&lt;/span&gt;&lt;span style="color: red"&gt; Fill&lt;/span&gt;&lt;span style="color: blue"&gt;="Transparent"        &lt;br /&gt;                       &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: red"&gt;MouseLeftButtonDown&lt;/span&gt;&lt;span style="color: blue"&gt;="BeginWindowResize"        &lt;br /&gt;                       &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: red"&gt;MouseLeftButtonUp&lt;/span&gt;&lt;span style="color: blue"&gt;="EndWindowResize"        &lt;br /&gt;                       &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: red"&gt;MouseMove&lt;/span&gt;&lt;span style="color: blue"&gt;="WindowResize"&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="mso-spacerun: yes"&gt;                    &lt;br /&gt;             &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Rectangle&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;             &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;TextBlock&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; VerticalAlignment&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="Center"&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; HorizontalAlignment&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="Center"&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;...&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Body&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;TextBlock&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;        &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;Grid&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;        &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;TextBlock&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Grid.Row&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="2"&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; Text&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;="Footer"&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: red; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; ...&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;TextBlock&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&amp;gt;      &lt;br /&gt;      &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-no-proof: yes"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-no-proof: yes"&gt;Grid&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-no-proof: yes"&gt;&amp;gt;      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-no-proof: yes"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-no-proof: yes"&gt;Border&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-no-proof: yes"&gt;&amp;gt;      &lt;br /&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-no-proof: yes"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: #a31515; font-size: 8pt; mso-no-proof: yes"&gt;Window&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-no-proof: yes"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Code-behind (interaction logic):      &lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;public&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; &lt;span style="color: blue"&gt;partial&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ShapedWindow&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;Window        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; _isResizing = &lt;span style="color: blue"&gt;false&lt;/span&gt;;       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; ShapedWindow()       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;InitializeComponent();      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: #2b91af"&gt;CommandBinding&lt;/span&gt; binding = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CommandBinding&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ApplicationCommands&lt;/span&gt;.Close);       &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;binding.Executed += CloseWindow;      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.CommandBindings.Add(binding);       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}      &lt;br /&gt;      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; CloseWindow(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;RoutedEventArgs&lt;/span&gt; e) { &lt;span style="color: blue"&gt;this&lt;/span&gt;.Close(); }       &lt;br /&gt;      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; BeginWindowResize(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;MouseButtonEventArgs&lt;/span&gt; e) { _isResizing = &lt;span style="color: blue"&gt;true&lt;/span&gt;; }       &lt;br /&gt;      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; EndWindowResize(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;MouseButtonEventArgs&lt;/span&gt; e)       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;_isResizing = &lt;span style="color: blue"&gt;false&lt;/span&gt;;       &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: #2b91af"&gt;Rectangle&lt;/span&gt; rectangle = (&lt;span style="color: #2b91af"&gt;Rectangle&lt;/span&gt;)sender;       &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;rectangle.ReleaseMouseCapture();      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}&lt;span style="mso-spacerun: yes"&gt;        &lt;br /&gt;        &lt;br /&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; WindowResize(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;MouseEventArgs&lt;/span&gt; e)       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: #2b91af"&gt;Rectangle&lt;/span&gt; rectangle = (&lt;span style="color: #2b91af"&gt;Rectangle&lt;/span&gt;)sender;       &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt; (_isResizing)       &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;      &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;rectangle.CaptureMouse();      &lt;br /&gt;      &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;double&lt;/span&gt; newWidth = e.GetPosition(&lt;span style="color: blue"&gt;this&lt;/span&gt;).X + 5;       &lt;br /&gt;      &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt; (newWidth &amp;gt; 0) &lt;span style="color: blue"&gt;this&lt;/span&gt;.Width = newWidth;       &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}      &lt;br /&gt;   &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}      &lt;br /&gt;      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; WindowDragMove(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;MouseButtonEventArgs&lt;/span&gt; e)       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{&lt;span style="mso-spacerun: yes"&gt;            &lt;br /&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt; (e.ClickCount == 2) &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;this&lt;/span&gt;.WindowState = (&lt;span style="color: blue"&gt;this&lt;/span&gt;.WindowState == &lt;span style="color: #2b91af"&gt;WindowState&lt;/span&gt;.Maximized) ? &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: #2b91af; font-size: 8pt; mso-no-proof: yes"&gt;WindowState&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-no-proof: yes"&gt;.Normal : &lt;span style="color: #2b91af"&gt;WindowState&lt;/span&gt;.Maximized; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-no-proof: yes"&gt;     &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-no-proof: yes"&gt;&lt;span style="color: blue"&gt;else&lt;/span&gt; &lt;span style="color: blue"&gt;this&lt;/span&gt;.DragMove();&lt;span style="mso-spacerun: yes"&gt;    &lt;br /&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-no-proof: yes"&gt;}&lt;span style="mso-spacerun: yes"&gt;       &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-no-proof: yes"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;Si nota subito che in una soluzione di questo tipo (non poteva essere altrimenti) è compito dello sviluppatore gestire sia il &lt;em&gt;resize&lt;/em&gt; che il &lt;em&gt;move&lt;/em&gt; della Window, dal momento che è assente la barra del titolo standard che l’utente usa comunemente per interagire con la finestra stessa.     &lt;br /&gt;Differentemente dal mondo Windows Forms, in WPF è possibile gestire la modalità di dragging della Window semplicemente invocando il metodo &lt;a href="http://msdn.microsoft.com/it-it/library/system.windows.window.dragmove.aspx" target="_blank"&gt;Window.DragMove()&lt;/a&gt; , che in questo caso specifico viene usato in corrispondenza dell’evento &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.mouseleftbuttondown.aspx" target="_blank"&gt;MouseLeftButtonDown&lt;/a&gt; scatenato sul TextBlock che funge da barra del titolo ( due click consecutivi invece “massimizzano” o “normalizzano” la finestra ;) ).     &lt;br /&gt;Per quanto riguarda invece il resize, la questione diventa un po’ più “complessa”. Anzitutto, impostare la proprietà &lt;a href="http://msdn.microsoft.com/it-it/library/system.windows.window.resizemode.aspx" target="_blank"&gt;Window.ResizeMode&lt;/a&gt; a &lt;em&gt;CanResizeWithGrip&lt;/em&gt; significa far apparire il sizing grip nell’angolo in basso a destra assumendo che la window sia comunque rettangolare. Questo significa quindi che esso può apparire o troppo distante o addirittura sopra l’effettivo bordo della Window.  &lt;br /&gt;Se non si vuole scegliere questo tipo di approccio, bensì si desidera poter ridimensionare manualmente la finestra interagendo con i suoi bordi effettivi, esistono due strade: o si utilizzano P/Invoke che inviano messaggi Win32 per ridimensionare la window, oppure più semplicemente (come in questo caso) si gestisce la posizione e l’azione scatenata dal mouse in ogni bordo che si vuole utilizzare per ridimensionare la finestra, andando poi a gestire di conseguenza la proprietà &lt;em&gt;Width&lt;/em&gt;.     &lt;br /&gt;Nell’esempio, si è scelto di posizionare un &lt;a href="http://msdn.microsoft.com/it-it/library/system.windows.shapes.rectangle(VS.95).aspx" target="_blank"&gt;Rectangle&lt;/a&gt; trasparente di larghezza 5 in corrsipondenza del lato destro della finestra. In questo modo gli opportuni event handler (&lt;em&gt;MouseLeftButtonDown&lt;/em&gt;, &lt;em&gt;MouseLeftButtonUp&lt;/em&gt;, &lt;em&gt;MouseMove&lt;/em&gt;) ci permettono di gestire il resize manuale della window ogni volta che il mouse interagisce con il bordo destro della stessa. &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;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:bdf6db91-9774-42c7-9c1d-544351d7abd2" class="wlWriterEditableSmartContent"&gt;Technorati Tag: &lt;a href="http://technorati.com/tags/WPF" rel="tag"&gt;WPF&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/97116.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2009/09/26/wpf-window-non-rettangolari.aspx</guid>
            <pubDate>Sat, 26 Sep 2009 14:23:09 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2009/09/26/wpf-window-non-rettangolari.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/97116.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/97116.aspx</trackback:ping>
        </item>
        <item>
            <title>Screenshots di Forms, Windows e schermo</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2009/09/09/screenshots-di-forms-windows-e-schermo.aspx</link>
            <description>&lt;p&gt;Spesso in ambiente desktop può essere utile salvare degli screenshot relativi alla UI della nostra applicazione: in alcuni scenari ad esempio, oltre ai soliti log e trace, è molto comodo avere automaticamente lo screenshot dell’UI al momento dell’errore, magari come allegato di una email di report.    &lt;br /&gt;Una comune soluzione in Windows Forms è quella che sfrutta GDI+ tramite il metodo &lt;a href="http://msdn.microsoft.com/it-it/library/system.drawing.graphics.copyfromscreen.aspx" target="_blank"&gt;Graphics.CopyFromScreen(…)&lt;/a&gt; . In questo post vorrei mostrare come anche in WPF è possibile approfittare della stessa tecnica con il minimo sforzo: in particolare, nell’ helper class che segue sono presenti degli overload del metodo &lt;em&gt;SaveScreenShot(…)&lt;/em&gt; per salvare su file system gli screenshot sia di singole Window (WPF) / Form (Windows Forms) che dell’intero schermo.     &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: blue; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;public&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ScreenshotHelper        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;  &lt;span style="font-family: 'Courier New'; color: green; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-fareast-language: en-us; mso-bidi-language: ar-sa" lang="EN-US"&gt;// Per Windows Forms&lt;/span&gt;...       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; SaveScreenShot(&lt;span style="color: #2b91af"&gt;Form&lt;/span&gt; form, &lt;span style="color: blue"&gt;string&lt;/span&gt; fileName, &lt;span style="color: #2b91af"&gt;ImageFormat&lt;/span&gt; imageFormat)       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;SaveScreenShot(form.Location, form.Size, fileName, imageFormat);      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}      &lt;br /&gt;      &lt;br /&gt;&lt;span style="font-family: 'Courier New'; color: green; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-fareast-language: en-us; mso-bidi-language: ar-sa" lang="EN-US"&gt;  // Per WPF...&lt;/span&gt;  &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; SaveScreenShot(&lt;span style="color: #2b91af"&gt;Window&lt;/span&gt; window, &lt;span style="color: blue"&gt;string&lt;/span&gt; fileName, &lt;span style="color: #2b91af"&gt;ImageFormat&lt;/span&gt; imageFormat)       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;SaveScreenShot(&lt;span style="color: blue"&gt;new&lt;/span&gt; System.Drawing.&lt;span style="color: #2b91af"&gt;Point&lt;/span&gt;((&lt;span style="color: blue"&gt;int&lt;/span&gt;)window.Left, (&lt;span style="color: blue"&gt;int&lt;/span&gt;)window.Top),       &lt;br /&gt;                   &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;new&lt;/span&gt; System.Drawing.&lt;span style="color: #2b91af"&gt;Size&lt;/span&gt;((&lt;span style="color: blue"&gt;int&lt;/span&gt;)window.Width, (&lt;span style="color: blue"&gt;int&lt;/span&gt;)window.Height),       &lt;br /&gt;                   &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;fileName, imageFormat);      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}      &lt;br /&gt;      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; SaveScreenShot(System.Drawing.&lt;span style="color: #2b91af"&gt;Point&lt;/span&gt; windowLocation, System.Drawing.&lt;span style="color: #2b91af"&gt;Size&lt;/span&gt; windowSize,       &lt;br /&gt;                                     &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;string&lt;/span&gt; fileName, &lt;span style="color: #2b91af"&gt;ImageFormat&lt;/span&gt; imageFormat)       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{&lt;span style="mso-spacerun: yes"&gt;                       &lt;br /&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Bitmap&lt;/span&gt; bitmap = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Bitmap&lt;/span&gt;(windowSize.Width, windowSize.Height))       &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;      &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Graphics&lt;/span&gt; graphics = &lt;span style="color: #2b91af"&gt;Graphics&lt;/span&gt;.FromImage(bitmap))       &lt;br /&gt;      &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;        &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;graphics.CopyFromScreen(windowLocation, &lt;span style="color: blue"&gt;new&lt;/span&gt; System.Drawing.&lt;span style="color: #2b91af"&gt;Point&lt;/span&gt;(0, 0), windowSize);       &lt;br /&gt;      &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}      &lt;br /&gt;      &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;bitmap.Save(fileName, imageFormat);      &lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;}  &lt;br /&gt;      &lt;br /&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; color: green; font-size: 8pt; mso-no-proof: yes"&gt;  // Schermo intero...&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; SaveScreenShot(&lt;span style="color: blue"&gt;string&lt;/span&gt; fileName, &lt;span style="color: #2b91af"&gt;ImageFormat&lt;/span&gt; imageFormat)       &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;     &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: #2b91af"&gt;Rectangle&lt;/span&gt; bounds = &lt;span style="color: #2b91af"&gt;Screen&lt;/span&gt;.GetBounds(System.Drawing.&lt;span style="color: #2b91af"&gt;Point&lt;/span&gt;.Empty);       &lt;br /&gt;     &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Bitmap&lt;/span&gt; bitmap = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Bitmap&lt;/span&gt;(bounds.Width, bounds.Height))       &lt;br /&gt;     &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;       &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Graphics&lt;/span&gt; graphics = &lt;span style="color: #2b91af"&gt;Graphics&lt;/span&gt;.FromImage(bitmap))       &lt;br /&gt;       &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;{      &lt;br /&gt;         &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-ansi-language: en-us; mso-no-proof: yes" lang="EN-US"&gt;graphics.CopyFromScreen(System.Drawing.&lt;span style="color: #2b91af"&gt;Point&lt;/span&gt;.Empty, System.Drawing.&lt;span style="color: #2b91af"&gt;Point&lt;/span&gt;.Empty, bounds.Size);       &lt;br /&gt;       &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-no-proof: yes"&gt;}      &lt;br /&gt;       &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-no-proof: yes"&gt;bitmap.Save(fileName, imageFormat);      &lt;br /&gt;     &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-no-proof: yes"&gt;}      &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-no-proof: yes"&gt;}      &lt;br /&gt;&lt;/span&gt;&lt;span style="line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;; font-size: 8pt; mso-no-proof: yes"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;&lt;em&gt;Nota&lt;/em&gt;&lt;/strong&gt;: Questo metodo non riesce a catturare controlli trasparenti. Per gestirli occorre utilizzare altri metodi, nativi di GDI+, come mostrato in &lt;a href="http://blog.developers.ba/post/2009/09/03/Screenshot-your-WPF-application.aspx" target="_blank"&gt;questo post&lt;/a&gt;.     &lt;br /&gt;&lt;/p&gt;  &lt;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:68d14aa8-6fe4-48f9-8aad-aa6613343f47" class="wlWriterEditableSmartContent"&gt;Technorati Tag: &lt;a href="http://technorati.com/tags/WPF" rel="tag"&gt;WPF&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Windows+Forms" rel="tag"&gt;Windows Forms&lt;/a&gt;,&lt;a href="http://technorati.com/tags/GDI%2b" rel="tag"&gt;GDI+&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/97020.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2009/09/09/screenshots-di-forms-windows-e-schermo.aspx</guid>
            <pubDate>Wed, 09 Sep 2009 00:29:44 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2009/09/09/screenshots-di-forms-windows-e-schermo.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/97020.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/97020.aspx</trackback:ping>
        </item>
    </channel>
</rss>