<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:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>MVVM</title>
        <link>http://geekswithblogs.net/lbugnion/category/10201.aspx</link>
        <description>Model-View-ViewModel "light" toolkit and other MVVM related posts</description>
        <language>en-US</language>
        <copyright>Laurent Bugnion</copyright>
        <managingEditor>laurent@galasoft.ch</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
        <item>
            <title>Bug correction in Messenger and new feature in EventToCommand (MVVM Light Toolkit V3 alpha)</title>
            <link>http://geekswithblogs.net/lbugnion/archive/2009/11/13/bug-correction-in-messenger-and-new-feature-in-eventtocommand-mvvm.aspx</link>
            <description>&lt;div class="frame"&gt;&lt;strong&gt;Update (11/14/2009):&lt;/strong&gt; The sample application is available &lt;a href="http://galasoft.ch/mvvm/resources/Samples/EventToCommand.zip" target="_blank"&gt;as a zip file&lt;/a&gt;, and I also published the Silverlight version to be &lt;a href="http://galasoft.ch/mvvm/resources/Samples/EventToCommandDemo/TestPage.html"&gt;executed directly in your browser&lt;/a&gt;.&lt;/div&gt;  &lt;p&gt;&lt;a title="MVVM_Black by lbugnionblog, on Flickr" href="http://www.flickr.com/photos/36917929@N06/4084199726/"&gt;&lt;img style="margin: 0px 10px 0px 0px; display: inline" alt="MVVM_Black" align="left" src="http://farm3.static.flickr.com/2617/4084199726_d1cc8527aa_o.png" width="240" height="206" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The advantage of pushing very early software to the advanced users is that bugs are detected before too many people suffer from them, and features requests can be placed and implemented without pain. This is exactly what happened with the MVVM Light Toolkit V3 alpha 2.&lt;/p&gt;  &lt;h2&gt;Bug correction&lt;/h2&gt;  &lt;p&gt;This applies to the new “send with token” feature of the Messenger. When a recipient registers for a type of message, it can provide a token (any object). Then, when a sender sends a message, it can also provide the same token. The Messenger will only send the messages to those recipients who provided the same token when registering. This enables creating separate optimized communication channels between objects. The token can be any object, for example a string, a GUID, etc…&lt;/p&gt;  &lt;p&gt;A silly mistake I made in the Messenger preventer simple values (such as an Integer) to be used as a token when sending a message. Simple values can be very valuable for this scenario, since a common reference is not needed to the token: It is simply a kind of contract that the sender and the receiver agree upon in advance. This is as decoupled as it gets, and yet enables a private channel of communication between two objects. Anyway, this mistake is corrected, and available in &lt;a href="http://mvvmlight.codeplex.com/SourceControl/ListDownloadableCommits.aspx"&gt;changeset 34855 on Codeplex&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;New feature&lt;/h2&gt;  &lt;p&gt;A &lt;a href="http://mvvmlight.codeplex.com/Thread/View.aspx?ThreadId=74835"&gt;user on Codeplex&lt;/a&gt; required an additional feature in the EventToCommand behavior: Adding a way to get the EventArgs from the fired event to the invoked command. I tried to find a good way to implement that, and decided to make this an opt-in feature. The scenario is:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;if you set the new property &lt;strong&gt;PassEventArgsToCommand&lt;/strong&gt; to true in the EventToCommand &lt;/li&gt;    &lt;li&gt;and you do NOT set the CommandParameter, nor the CommandParameterValue &lt;/li&gt;    &lt;li&gt;and you use a RelayCommand&amp;lt;EventArgs&amp;gt; as the data bound command &lt;/li&gt;    &lt;li&gt;then the parameter passed to the RelayCommand will be the EventArgs. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I believe that passing the EventArgs straight to the ViewModel is a bit overstepping the separation of concerns between the View and the ViewModel. However I do also acknowledge that there are cases where this can be useful, and so now it is possible. This feature is also implemented in &lt;a href="http://mvvmlight.codeplex.com/SourceControl/ListDownloadableCommits.aspx"&gt;changeset 34855 on Codeplex&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I also updated the sample application &lt;a href="http://galasoft.ch/mvvm/resources/Samples/EventToCommand.zip" target="_blank"&gt;which can be downloaded here&lt;/a&gt;, or from Codeplex (see below). The Silverlight version of the sample application &lt;a href="http://galasoft.ch/mvvm/resources/Samples/EventToCommandDemo/TestPage.html" target="_blank"&gt;can also be run here&lt;/a&gt;.&lt;/p&gt; &lt;a title="EventToCommand demo" href="http://www.flickr.com/photos/36917929@N06/4102403273"&gt;&lt;img src="http://farm3.static.flickr.com/2715/4102403273_28c14af3fa.jpg" width="500" height="494" /&gt;&lt;/a&gt;   &lt;h2&gt;Sample applications on Codeplex&lt;/h2&gt;  &lt;p&gt;I took the occasion to &lt;a href="http://mvvmlight.codeplex.com/sourcecontrol/changeset/view/34873?projectName=mvvmlight"&gt;upload some sample applications&lt;/a&gt; on Codeplex too.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;EventToCommand: This application demoes the feature of the same name, and is &lt;a href="http://blog.galasoft.ch/archive/2009/11/05/mvvm-light-toolkit-v3-alpha-2-eventtocommand-behavior.aspx"&gt;detailed in this blog post&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;CleanShutdown: This application shows a practical use for the Messenger, and a way to implement a clean shutdown that can easily be extended with additional components. &lt;a href="http://blog.galasoft.ch/archive/2009/10/18/clean-shutdown-in-silverlight-and-wpf-applications.aspx"&gt;More about this application here&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;RaiseCanExecuteChanged: This app shows how to use RelayCommands and more info about this sample is &lt;a href="http://blog.galasoft.ch/archive/2009/09/26/using-relaycommands-in-silverlight-and-wpf.aspx"&gt;found in this blog post&lt;/a&gt;. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Happy coding!!&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;div style="margin-bottom: -1em"&gt;   &lt;div style="vertical-align: middle"&gt;&lt;a href="http://www.galasoft.ch/"&gt;&lt;img title="GalaSoft Laurent Bugnion" alt="GalaSoft Laurent Bugnion" src="http://www.galasoft.ch/logo/Current/logo_120x30.png" /&gt;&lt;/a&gt; &lt;/div&gt;    &lt;div style="position: relative; top: -36px; left: 130px"&gt;&lt;strong&gt;&lt;a href="http://www.galasoft.ch/contact_en.html"&gt;Laurent Bugnion (GalaSoft)&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;&lt;a href="http://feeds.feedburner.com/galasoft"&gt;Subscribe&lt;/a&gt; | &lt;a href="http://twitter.com/lbugnion"&gt;Twitter&lt;/a&gt; | &lt;a href="http://www.facebook.com/lbugnion"&gt;Facebook&lt;/a&gt; | &lt;a href="http://www.flickr.com/photos/lbugnion"&gt;Flickr&lt;/a&gt; | &lt;a href="http://www.linkedin.com/in/lbugnion"&gt;LinkedIn&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=136296"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=136296" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/lbugnion/aggbug/136296.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Laurent Bugnion</dc:creator>
            <guid>http://geekswithblogs.net/lbugnion/archive/2009/11/13/bug-correction-in-messenger-and-new-feature-in-eventtocommand-mvvm.aspx</guid>
            <pubDate>Fri, 13 Nov 2009 23:55:39 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/lbugnion/comments/136296.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/lbugnion/archive/2009/11/13/bug-correction-in-messenger-and-new-feature-in-eventtocommand-mvvm.aspx#feedback</comments>
            <slash:comments>8</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/lbugnion/comments/commentRss/136296.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/lbugnion/services/trackbacks/136296.aspx</trackback:ping>
        </item>
        <item>
            <title>MVVM Light Toolkit Logo by P. Schutz</title>
            <link>http://geekswithblogs.net/lbugnion/archive/2009/11/07/mvvm-light-toolkit-logo-by-p.-schutz.aspx</link>
            <description>&lt;p&gt;I met &lt;a href="http://info.philippe-schutz.com"&gt;Philippe Schutz&lt;/a&gt; at the TechDays in Geneva early this year, and have been following him on Facebook since then. He does amazing work with logos and icons, and it is only natural that I have thought of him when I decided to get a new logo and icons for the MVVM Light Toolkit.&lt;/p&gt;  &lt;p&gt;A brand identity is quite important to me even in private projects. This is why I created the site GalaSoft (&lt;a href="http://www.galasoft.ch"&gt;www.galasoft.ch&lt;/a&gt;) years ago, and started using this “brand” consistently as well as the cat logo (more about that on a &lt;a href="http://blog.galasoft.ch/archive/2008/10/19/redesigning-my-website-with-the-help-of-expression-blend.aspx"&gt;post I wrote last year&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;With the MVVM Light Toolkit starting to gain quite some popularity in the community, I have received a few suggestions to open a Facebook page for it, and to promote it on some other platforms. To do this, I needed a logo, something to display proudly and conveying the image, the message of MVVM Light.&lt;/p&gt;  &lt;p&gt;So I present to you proudly the new MVVM Light Toolkit logos designed by &lt;a href="http://info.philippe-schutz.com"&gt;Philippe Schutz&lt;/a&gt;:&lt;/p&gt; &lt;a title="MVVM_Black by lbugnionblog, on Flickr" href="http://www.flickr.com/photos/36917929@N06/4084199726/"&gt;&lt;img alt="MVVM_Black" src="http://farm3.static.flickr.com/2617/4084199726_d1cc8527aa_o.png" width="349" height="300" /&gt;&lt;/a&gt;   &lt;p&gt; &lt;/p&gt; &lt;a title="MVVM_White by lbugnionblog, on Flickr" href="http://www.flickr.com/photos/36917929@N06/4084208308/"&gt;&lt;img alt="MVVM_White" src="http://farm3.static.flickr.com/2706/4084208308_f541fd0597_o.png" width="356" height="300" /&gt;&lt;/a&gt;   &lt;p&gt;Yeah I know, they are beautiful.&lt;/p&gt;  &lt;p&gt;The design is meant to remind from the Windows 7 aesthetics, and of the Silverlight / .NET logos. I think it is a total success. Of course, the feather suggests the idea of lightness, as opposed to more complex frameworks that are very powerful, but also quite hard to understand and start with.&lt;/p&gt;  &lt;p&gt;I will work hard to include this new identity in the MVVM Light Toolkit and all the material related (websites, etc…). I am also preparing a Facebook page for “the fans” ;) So as usual, stay tuned!&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;div style="margin-bottom: -1em"&gt;   &lt;div style="vertical-align: middle"&gt;&lt;a href="http://www.galasoft.ch/"&gt;&lt;img title="GalaSoft Laurent Bugnion" alt="GalaSoft Laurent Bugnion" src="http://www.galasoft.ch/logo/Current/logo_120x30.png" /&gt;&lt;/a&gt; &lt;/div&gt;    &lt;div style="position: relative; top: -36px; left: 130px"&gt;&lt;strong&gt;&lt;a href="http://www.galasoft.ch/contact_en.html"&gt;Laurent Bugnion (GalaSoft)&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;&lt;a href="http://feeds.feedburner.com/galasoft"&gt;Subscribe&lt;/a&gt; | &lt;a href="http://twitter.com/lbugnion"&gt;Twitter&lt;/a&gt; | &lt;a href="http://www.facebook.com/lbugnion"&gt;Facebook&lt;/a&gt; | &lt;a href="http://www.flickr.com/photos/lbugnion"&gt;Flickr&lt;/a&gt; | &lt;a href="http://www.linkedin.com/in/lbugnion"&gt;LinkedIn&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=136123"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=136123" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/lbugnion/aggbug/136123.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Laurent Bugnion</dc:creator>
            <guid>http://geekswithblogs.net/lbugnion/archive/2009/11/07/mvvm-light-toolkit-logo-by-p.-schutz.aspx</guid>
            <pubDate>Sat, 07 Nov 2009 22:03:54 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/lbugnion/comments/136123.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/lbugnion/archive/2009/11/07/mvvm-light-toolkit-logo-by-p.-schutz.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/lbugnion/comments/commentRss/136123.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/lbugnion/services/trackbacks/136123.aspx</trackback:ping>
        </item>
        <item>
            <title>MVVM Light Toolkit V3 Alpha 2: EventToCommand behavior</title>
            <link>http://geekswithblogs.net/lbugnion/archive/2009/11/05/mvvm-light-toolkit-v3-alpha-2-eventtocommand-behavior.aspx</link>
            <description>&lt;div class="frame"&gt;&lt;strong&gt;Update (11/14/2009):&lt;/strong&gt; I updated EventToCommand with a new feature: You can now pass the EventArgs of the fired event to the invoked command. &lt;a href="http://blog.galasoft.ch/archive/2009/11/13/bug-correction-in-messenger-and-new-feature-in-eventtocommand-mvvm.aspx"&gt;See this post for more explanations&lt;/a&gt;.&lt;/div&gt;  &lt;p&gt;Here is another early release of the MVVM Light Toolkit V3 (Alpha 2). I decided to release gradually and early as soon as a new part of this new version is ready, to allow advanced users to install, test and give feedback about the new features. If you haven’t seen it yet, the features available in &lt;a href="http://blog.galasoft.ch/archive/2009/10/27/mvvm-light-toolkit-v3-alpha-1.aspx"&gt;V3 Alpha 1 are described in a previous article&lt;/a&gt;. There will be a few more alphas before I make a V3 release, which means more good things are a-coming ;)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Usual disclaimer:&lt;/strong&gt; Alpha releases are not feature complete (meaning that APIs may change) and it is very possible that there are bugs in the code. Use with care and &lt;a href="http://www.galasoft.ch/contact"&gt;give feedback&lt;/a&gt; if something is not working, thanks!!&lt;/p&gt;  &lt;h2&gt;EventToCommand behavior&lt;/h2&gt;  &lt;p&gt;The new feature available in V3 Alpha2 is called &lt;strong&gt;EventToCommand&lt;/strong&gt; and is a &lt;a href="http://blogs.msdn.com/expression/archive/2009/03/23/an-introduction-to-behaviors-triggers-and-actions.aspx"&gt;Blend behavior&lt;/a&gt;. These pieces of code are optimized for Expression Blend, but can also be added directly in XAML, as we will see in this article.&lt;/p&gt;  &lt;p&gt;EventToCommand is used to &lt;strong&gt;bind an event to an ICommand directly in XAML&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Even though Expression Blend facilitates the usage of EventToCommand, it is not a prerequisite. EventToCommand can be used even if Expression Blend is not installed on your system, or on your users’ system.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h2&gt;Credits, History&lt;/h2&gt;  &lt;p&gt;This behavior reuses much code from the Expression Blend sample behavior named &lt;a href="http://expressionblend.codeplex.com/"&gt;InvokeDataCommand&lt;/a&gt;. I want to give props to the Expression team for creating and publishing these great samples. This would not have been possible without the work put into these samples. I want to especially thank &lt;strong&gt;Pete Blois&lt;/strong&gt; and &lt;strong&gt;Jeff Kelly&lt;/strong&gt; of the Expression team for their help.&lt;/p&gt;  &lt;p&gt;I also want to thank &lt;strong&gt;Rishi&lt;/strong&gt;, the creator of the &lt;a href="http://nroute.codeplex.com/"&gt;nRoute toolkit&lt;/a&gt;, for the interesting discussions and a couple of ideas that I implemented in EventToCommand. &lt;/p&gt;  &lt;p&gt;If you are already using InvokeDataCommand, the new EventToCommand behavior brings the following additional features:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;WPF / Silverlight compatibility&lt;/strong&gt;: The WPF version of the Expression Blend sample behavior InvokeDataCommand &lt;a href="http://expressionblend.codeplex.com/WorkItem/View.aspx?WorkItemId=5335"&gt;has a bug&lt;/a&gt; that prevents it to work (the Silverlight version runs fine though). The bug is corrected in EventToCommand, and both versions run well. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;CommandParameter is bindable&lt;/strong&gt;. You can bind this property, for example, to the value of a slider, the content of a TextBox, or any other property that is accessible to a data binding. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Disabling the attached control:&lt;/strong&gt; If the IsEnabled property is available for the attached element, you can opt-in to automatically disable the element if the Command’s CanExecute method returns false. This is dynamic, i.e. if the value of CanExecute changes, the element will be disabled/enabled.       &lt;ul&gt;       &lt;li&gt;In Silverlight, this is valid for all Controls. &lt;/li&gt;        &lt;li&gt;In WPF, this is valid for all FrameworkElements (Panels, Shapes, Controls, etc…). &lt;/li&gt;        &lt;li&gt;Note: By default, the element will &lt;strong&gt;not&lt;/strong&gt; be disabled/enabled automatically. Since one element can have multiple EventToCommand behaviors added to link multiple events to commands, you probably want only one or two of these to affect the IsEnabled property. This can be turned on by using the &lt;strong&gt;MustToggleIsEnabled&lt;/strong&gt; property, which can be either set in XAML (see below) or databound to a boolean value (checkbox, etc…). &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h2&gt;Source code, Binaries&lt;/h2&gt;  &lt;p&gt;The source code is &lt;a href="http://www.galasoft.ch/mvvm/resources/V3/GalaSoft.MvvmLight_Source_V3Alpha2.zip"&gt;available for download&lt;/a&gt; from my website. If you prefer, you can go &lt;a href="http://mvvmlight.codeplex.com/SourceControl/ListDownloadableCommits.aspx"&gt;to the Codeplex page&lt;/a&gt; where the source code has also been updated.&lt;/p&gt;  &lt;p&gt;The &lt;a href="http://www.galasoft.ch/mvvm/resources/V3/GalaSoft.MvvmLight_Binaries_V3Alpha2.zip"&gt;binaries can be found here&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;Features, Usage&lt;/h2&gt;  &lt;p&gt;&lt;strong&gt;EventToCommand&lt;/strong&gt; is a behavior that can be added to any FrameworkElement. This can be a Rectangle, an Ellipse (in fact, any shape), an Image, any Control (Button, Slider, CheckBox, RadioButton, and many many others) etc. In short: If you can add an element to your UI, you can probably add EventToCommand to it.&lt;/p&gt;  &lt;p&gt;For more information about ICommand (and their MVVM Light implementation, RelayCommand), &lt;a href="http://blog.galasoft.ch/archive/2009/09/26/using-relaycommands-in-silverlight-and-wpf.aspx"&gt;read this article&lt;/a&gt;. You can bind any event to any command. Typically, you will use this to link an element’s event to a command defined in a ViewModel class. For more information about the ViewModel pattern in WPF and Silverlight, &lt;a href="http://www.galasoft.ch/mvvm/getstarted"&gt;this page will help you&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;In Expression Blend:&lt;/h3&gt;  &lt;p&gt;Adding an EventToCommand to any element in Expression Blend is super easy thanks to the visual support.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Right click on the References folder and select “Add Reference”. &lt;/li&gt; &lt;/ul&gt; &lt;a title="Adding references" href="http://www.flickr.com/photos/36917929@N06/4076890743"&gt;&lt;img src="http://farm3.static.flickr.com/2658/4076890743_d398cda55c.jpg" width="359" height="187" /&gt;&lt;/a&gt;   &lt;ul&gt;   &lt;li&gt;Add a reference to the MVVM Light DLLs. You need two: &lt;strong&gt;GalaSoft.MvvmLight.dll&lt;/strong&gt; and &lt;strong&gt;GalaSoft.MvvmLight.Extras.dll&lt;/strong&gt;. In addition, you need the &lt;strong&gt;System.Windows.Interactivity.dll&lt;/strong&gt; which contains the base code for all behaviors.       &lt;br /&gt;&lt;em&gt;&lt;a href="http://www.galasoft.ch/mvvm/resources/V3/GalaSoft.MvvmLight_Binaries_V3Alpha2.zip"&gt;You can download the DLLs needed here&lt;/a&gt;.&lt;/em&gt;  &lt;/li&gt;    &lt;li&gt;Open your project in Expression Blend, and build it to make sure that everything is working fine. &lt;/li&gt;    &lt;li&gt;Locate the element on which you want to add a command in the Objects and Timeline panel. &lt;/li&gt;    &lt;li&gt;Open the Assets panel and find the Behaviors category.      &lt;br /&gt;&lt;em&gt;You can also find behaviors in the Asset library, which is the last button on the bottom of the toolbar.&lt;/em&gt; &lt;/li&gt; &lt;/ul&gt; &lt;a title="Finding EventToCommand" href="http://www.flickr.com/photos/36917929@N06/4077646092/"&gt;&lt;img alt="FliCA4" src="http://farm3.static.flickr.com/2475/4077646092_063122b6ae_o.png" width="672" height="225" /&gt;&lt;/a&gt;   &lt;ul&gt;   &lt;li&gt;Drag the EventToCommand behavior on the element you selected before in the Objects and Timeline panel. &lt;/li&gt; &lt;/ul&gt; &lt;a title="Drag and drop EventToCommand" href="http://www.flickr.com/photos/36917929@N06/4076892115"&gt;&lt;img src="http://farm4.static.flickr.com/3492/4076892115_3e696ab73a.jpg" width="364" height="209" /&gt;&lt;/a&gt;   &lt;ul&gt;   &lt;li&gt;With the EventToCommand selected, select the Properties panel. &lt;/li&gt;    &lt;li&gt;Select the event you want to handle. &lt;/li&gt; &lt;/ul&gt; &lt;a title="Selecting the event" href="http://www.flickr.com/photos/36917929@N06/4077647408"&gt;&lt;img src="http://farm3.static.flickr.com/2770/4077647408_b12c68f015.jpg" width="344" height="385" /&gt;&lt;/a&gt;   &lt;ul&gt;   &lt;li&gt;In the Miscellaneous section, bind the EventToCommand to the ICommand you want to execute when the event is fired.      &lt;br /&gt;&lt;em&gt;If you use &lt;a href="http://www.galasoft.ch/mvvm/getstarted"&gt;the MVVM pattern&lt;/a&gt;, you probably want to use an ICommand (&lt;a href="http://blog.galasoft.ch/archive/2009/09/26/using-relaycommands-in-silverlight-and-wpf.aspx"&gt;for example a RelayCommand&lt;/a&gt;) located in the ViewModel that is set as the DataContext for your window/page.         &lt;br /&gt;In WPF, you can also enter a value, for example ApplicationCommands.Save. In that case, you must &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.commandbinding.aspx"&gt;set a CommandBinding&lt;/a&gt;.&lt;/em&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a title="Advanced properties button" href="http://www.flickr.com/photos/36917929@N06/4076893421"&gt;&lt;img src="http://farm4.static.flickr.com/3487/4076893421_9bb2e9fc09.jpg" width="313" height="75" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a title="Data binding" href="http://www.flickr.com/photos/36917929@N06/4077648672"&gt;&lt;img src="http://farm3.static.flickr.com/2749/4077648672_5f276f2ef1.jpg" width="311" height="272" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a title="Data binding editor" href="http://www.flickr.com/photos/36917929@N06/4077649032/"&gt;&lt;img alt="Fli249C" src="http://farm3.static.flickr.com/2740/4077649032_e2d741480e_o.png" width="619" height="179" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;If you want to pass a parameter to the ICommand, you can set the CommandParameter property. You can data bind CommandParameter to something (for example the Text property of a TextBox, etc…). If you want to set a hard coded value ) for example “Hello world”, you need to set CommandParameterValue in the XAML editor (see the “Caveat” section below). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a title="Advanced properties button" href="http://www.flickr.com/photos/36917929@N06/4076894807"&gt;&lt;img src="http://farm3.static.flickr.com/2792/4076894807_c22d0604fe.jpg" width="321" height="62" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a title="Data binding editor" href="http://www.flickr.com/photos/36917929@N06/4077649906/"&gt;&lt;img alt="FliD557" src="http://farm3.static.flickr.com/2688/4077649906_b89ee62060_o.png" width="621" height="288" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Finally, if you want the attached element to be disabled depending on the ICommand.CanExecute method, set the MustToggleIsEnabledValue property to True. You can also use MustToggleIsEnabled to data bind this property to something else (for example a CheckBox’s IsChecked property) (see the “Caveat” section below).      &lt;ul&gt;       &lt;li&gt;In Silverlight, this will only work on Controls. Use the VisualStateManager to modify the appearance of the disabled control. &lt;/li&gt;        &lt;li&gt;In WPF, any FrameworkElement can be disabled. Use the Triggers panel to modify the appearance of the FrameworkElement when it is disabled. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt; &lt;a title="Setting MustToggleIsEnabled" href="http://www.flickr.com/photos/36917929@N06/4076897585"&gt;&lt;img src="http://farm4.static.flickr.com/3517/4076897585_dc1f5ae7da.jpg" width="305" height="58" /&gt;&lt;/a&gt;   &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;In XAML&lt;/h3&gt;  &lt;p&gt;Using the XAML editor, follow the steps to add an EventToCommand to an element.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Add a reference to the MVVM Light DLLs. You need two: &lt;strong&gt;GalaSoft.MvvmLight.dll&lt;/strong&gt; and &lt;strong&gt;GalaSoft.MvvmLight.Extras.dll&lt;/strong&gt;. In addition, you need the &lt;strong&gt;System.Windows.Interactivity.dll&lt;/strong&gt; which contains the base code for all behaviors.       &lt;br /&gt;&lt;em&gt;&lt;a href="http://www.galasoft.ch/mvvm/resources/V3/GalaSoft.MvvmLight_Binaries_V3Alpha2.zip"&gt;You can download the DLLs needed here&lt;/a&gt;.&lt;/em&gt;  &lt;/li&gt;    &lt;li&gt;Add an xmlns for the following namespaces: &lt;/li&gt; &lt;/ul&gt;  &lt;pre class="xml" name="code"&gt;xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras"&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Add the EventToCommand to the desired element (in this example, a Rectangle) with the following XAML code: 
      &lt;br /&gt;&lt;em&gt;This presupposes that the DataContext of your page/window is set to a ViewModel containing the TestCommand command, as is usual in the MVVM pattern.&lt;/em&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="xml" name="code"&gt;&amp;lt;Rectangle Fill="White"
           Stroke="Black"
           Width="200"
           Height="100"&amp;gt;
    &amp;lt;i:Interaction.Triggers&amp;gt;
        &amp;lt;i:EventTrigger EventName="MouseEnter"&amp;gt;
            &amp;lt;cmd:EventToCommand Command="{Binding TestCommand,
                                          Mode=OneWay}"
               CommandParameter="{Binding Text,
                                  ElementName=MyTextBox,
                                  Mode=OneWay}"
               MustToggleIsEnabledValue="True" /&amp;gt;
        &amp;lt;/i:EventTrigger&amp;gt;
    &amp;lt;/i:Interaction.Triggers&amp;gt;
&amp;lt;/Rectangle&amp;gt;&lt;/pre&gt;

&lt;h3&gt;Listening to events on other elements&lt;/h3&gt;

&lt;p&gt;Because EventToCommand derives from System.Windows.Interactivity.TriggerAction&amp;lt;T&amp;gt;, it has a property named SourceName. With this property, you can attach EventToCommand to an element, but listen to events on another element. I didn’t explicitly forbid this in the code, but I would recommend against it. I think that it creates confusing code that can easily be broken. The best is probably to always listen to events on the attached element itself, and leave SourceName empty.&lt;/p&gt;

&lt;h2&gt;Small caveat&lt;/h2&gt;

&lt;p&gt;Because of limitations in the Silverlight framework (specifically, the fact that data bindings can only be applied to a FrameworkElement), I had to resort to a small trick to make CommandParameter and MustToggleIsEnabled bindable. You will see in the code that there are four properties:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;CommandParameter&lt;/strong&gt;: 

    &lt;ul&gt;
      &lt;li&gt;In Silverlight, used to data bind CommandParameter. &lt;/li&gt;

      &lt;li&gt;In WPF, used either for data binding or for hard coded values. &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;CommandParameterValue:&lt;/strong&gt; 

    &lt;ul&gt;
      &lt;li&gt;In Silverlight and in WPF, used for hard coded values only. &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;MustToggleIsEnabled:&lt;/strong&gt; 

    &lt;ul&gt;
      &lt;li&gt;In Silverlight, used to data bind MustToggleIsEnabled. &lt;/li&gt;

      &lt;li&gt;In WPF, used either for data binding or for hard coded values. &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;MustToggleIsEnabledValue:&lt;/strong&gt; 

    &lt;ul&gt;
      &lt;li&gt;In Silverlight and in WPF, used for hard coded values only. &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, if you don’t care about Silverlight compatibility for your XAML code, you can always use CommandParameter or MustToggleIsEnabled in WPF, either for data binding or for hard coded values. If you want to share your XAML between a Silverlight and a WPF application, then you should respect the rules above, or else you will get exceptions in Silverlight when the XAML is being parsed.&lt;/p&gt;

&lt;h2&gt;Demo application&lt;/h2&gt;

&lt;p&gt;The demo application shows multiple usages of the EventToCommand behavior. The application runs in Silverlight and in WPF. &lt;a href="http://galasoft.ch/mvvm/resources/Samples/EventToCommand.zip"&gt;Feel free to download the code&lt;/a&gt; and play with it to learn how to use EventToCommand! The Silverlight version of the sample application &lt;a href="http://galasoft.ch/mvvm/resources/Samples/EventToCommandDemo/TestPage.html" target="_blank"&gt;can also be executed&lt;/a&gt; directly in your web browser.&lt;/p&gt;
&lt;a title="EventToCommand demo" href="http://www.flickr.com/photos/36917929@N06/4102403273"&gt;&lt;img src="http://farm3.static.flickr.com/2715/4102403273_28c14af3fa.jpg" width="500" height="494" /&gt;&lt;/a&gt; 

&lt;ul&gt;
  &lt;li&gt;Binding a Button’s Click event and a Rectangle’s MouseEnter event to a simple RelayCommand. &lt;/li&gt;

  &lt;li&gt;Binding a Button’s Click event and a Rectangle’s MouseEnter event to a RelayCommand with a data bound parameter. &lt;/li&gt;

  &lt;li&gt;Binding a Button’s Click event and a Rectangle’s MouseEnter event to a RelayCommand with a hard coded parameter. &lt;/li&gt;

  &lt;li&gt;Binding a Button’s Click event and a Rectangle’s MouseEnter event to a RelayCommand and disabling them depending on the parameter’s value. 
    &lt;br /&gt;&lt;em&gt;Note: In Silverlight, Rectangles cannot be disabled.&lt;/em&gt; &lt;/li&gt;

  &lt;li&gt;Passing the EventArgs of a fired event to the invoked command.
    &lt;br /&gt;&lt;em&gt;Note: This feature was added after V3 alpha 2 was released. &lt;a href="http://blog.galasoft.ch/archive/2009/11/13/bug-correction-in-messenger-and-new-feature-in-eventtocommand-mvvm.aspx"&gt;See this post&lt;/a&gt; for more information.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;License&lt;/h2&gt;

&lt;p&gt;MVVM Light Toolkit is distributed under the MIT License. This license grants you the right to do pretty much anything you want with the code, but don’t come crying if you break something (&lt;a href="http://www.galasoft.ch/license_MIT.txt"&gt;the exact wording is found here&lt;/a&gt;). Some parts of the GalaSoft.MvvmLight.Extras DLL are licensed under the MS-PL license.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="margin-bottom: -1em"&gt;
  &lt;div style="vertical-align: middle"&gt;&lt;a href="http://www.galasoft.ch/"&gt;&lt;img title="GalaSoft Laurent Bugnion" alt="GalaSoft Laurent Bugnion" src="http://www.galasoft.ch/logo/Current/logo_120x30.png" /&gt;&lt;/a&gt; &lt;/div&gt;

  &lt;div style="position: relative; top: -36px; left: 130px"&gt;&lt;strong&gt;&lt;a href="http://www.galasoft.ch/contact_en.html"&gt;Laurent Bugnion (GalaSoft)&lt;/a&gt;&lt;/strong&gt; 

    &lt;br /&gt;&lt;a href="http://feeds.feedburner.com/galasoft"&gt;Subscribe&lt;/a&gt; | &lt;a href="http://twitter.com/lbugnion"&gt;Twitter&lt;/a&gt; | &lt;a href="http://www.facebook.com/lbugnion"&gt;Facebook&lt;/a&gt; | &lt;a href="http://www.flickr.com/photos/lbugnion"&gt;Flickr&lt;/a&gt; | &lt;a href="http://www.linkedin.com/in/lbugnion"&gt;LinkedIn&lt;/a&gt; &lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=136016"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=136016" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/lbugnion/aggbug/136016.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Laurent Bugnion</dc:creator>
            <guid>http://geekswithblogs.net/lbugnion/archive/2009/11/05/mvvm-light-toolkit-v3-alpha-2-eventtocommand-behavior.aspx</guid>
            <pubDate>Thu, 05 Nov 2009 14:57:43 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/lbugnion/comments/136016.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/lbugnion/archive/2009/11/05/mvvm-light-toolkit-v3-alpha-2-eventtocommand-behavior.aspx#feedback</comments>
            <slash:comments>9</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/lbugnion/comments/commentRss/136016.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/lbugnion/services/trackbacks/136016.aspx</trackback:ping>
        </item>
        <item>
            <title>MVVM Light Toolkit V3 Alpha 1</title>
            <link>http://geekswithblogs.net/lbugnion/archive/2009/10/27/mvvm-light-toolkit-v3-alpha-1.aspx</link>
            <description>&lt;p&gt;This is a super early release of the next version of the &lt;a href="http://www.galasoft.ch/mvvm/getstarted"&gt;MVVM Light Toolkit&lt;/a&gt;. Please enjoy with care, be aware that this version is &lt;strong&gt;not fully tested&lt;/strong&gt; and &lt;strong&gt;not feature complete&lt;/strong&gt; by a long shot.&lt;/p&gt;  &lt;p&gt;The &lt;a href="http://galasoft.ch/mvvm/resources/V3/GalaSoft.MvvmLight_Binaries_V3Alpha1.zip"&gt;binaries are available for download&lt;/a&gt;, as well &lt;a href="http://galasoft.ch/mvvm/resources/V3/GalaSoft.MvvmLight_Source_V3Alpha1.zip"&gt;as the source code&lt;/a&gt;. In addition, the source code for V3 alpha1 is &lt;a href="http://mvvmlight.codeplex.com/SourceControl/ListDownloadableCommits.aspx"&gt;up to date in Codeplex&lt;/a&gt;, so you can also get the code from there.&lt;/p&gt;  &lt;h2&gt;What’s new in the Messenger?&lt;/h2&gt;  &lt;p&gt;So far the changes are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Bug correction: A “collection was modified” error could occur if a recipient was registering for a message type in the same method it used to receive another message. A similar error had been fixed in V2, but unfortunately this one remained. A unit test was added to isolate this case, and a fix has been implemented. &lt;/li&gt;    &lt;li&gt;New built-in message types: &lt;strong&gt;NotificationMessageAction and NotificationMessageAction&amp;lt;TCallbackParameter&amp;gt;&lt;/strong&gt;. These types can be used to send a message through the Messenger, and get a callback. A next post will give more information about this scenario. &lt;/li&gt;    &lt;li&gt;Renamed message types: To avoid some confusion, I renamed CommandMessage to &lt;strong&gt;NotificationMessage&lt;/strong&gt;. These messages are used to convey a notification (of type string) from a sender to a recipient. The term “command” was too confusing because it is a loaded term in the MVVM pattern (ICommand, RoutedCommand, RelayCommand, etc…). The term NotificationMessage is clearer. The old types are still available but have been marked Obsolete and will be removed in a future version of the toolkit. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;At this point it is good to remember that the Messenger class (from V2) can be used to send &lt;strong&gt;any kind of message&lt;/strong&gt;, from simple values to complex objects. The built-in message types are merely a convenience for specific scenarios, but nothing forces you to use them!&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;To make testing and mocking easier, it is now possible to &lt;strong&gt;override the Messenger.Default&lt;/strong&gt; property and provide another implementation. In addition, all the public methods of the Messenger class have now been marked virtual, which means that they can be overriden. A next post will give more information about this scenario. &lt;/li&gt;    &lt;li&gt;In V2, you could send a message to a given type of recipients only by using the method overload Send&amp;lt;TMessage, TRecipient&amp;gt;. In V3, &lt;strong&gt;TRecipient&lt;/strong&gt; &lt;strong&gt;can now be an interface&lt;/strong&gt;. This enables the Messenger to send messages to all the objects implementing a given interface. Note that the Messenger can send &lt;strong&gt;to any type of recipient&lt;/strong&gt;, and no special requirement is needed to receive a message. But if some of your objects happen to implement an interface (for example IViewModel), you can make sure that your messages reach only these recipients (of course, the recipients still need to register for a type of messages). &lt;/li&gt;    &lt;li&gt;When a recipient registers for a type of message, it can &lt;strong&gt;provide a token&lt;/strong&gt; (any object). Then, when a sender sends a message, it can also provide the same token. The Messenger will only send the messages to those recipients who provided the same token when registering. This enables creating separate optimized communication channels between objects. The token can be any object, for example a string, a GUID, etc… &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;What’s new in ViewModelBase?&lt;/h2&gt;  &lt;p&gt;In V3 alpha 1, a small change has been made to ViewModelBase: The constructor ViewModelBase(Messenger) has been replaced by &lt;strong&gt;ViewModelBase(IMessenger)&lt;/strong&gt;. This makes it easier to test and mock ViewModels that use their own implementation of the IMessenger interface.&lt;/p&gt;  &lt;p&gt;More changes will be implemented in V3 final.&lt;/p&gt;  &lt;h2&gt;Installation&lt;/h2&gt;  &lt;p&gt;if you have MVVM Light Toolkit V2 installed, you can easily deploy the V3 alpha1 DLLs manually by following the steps:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;In Windows, choose the Start menu then All Programs, MVVM Light Toolkit, Binaries (Assemblies). This starts the Windows Explorer in the Binaries folder. &lt;/li&gt;    &lt;li&gt;(optional but recommended) Rename GalaSoft.MvvmLight.dll (and the Silverlight version too) to GalaSoft.MvvmLight.bak. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://galasoft.ch/mvvm/resources/V3/GalaSoft.MvvmLight_Binaries_V3Alpha1.zip"&gt;Download the V3 alpha1 binaries&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;Extract this file to a local folder. &lt;/li&gt;    &lt;li&gt;Copy the WPF version of the assembly in Binaries, and then copy the Silverlight version to Binaries\Silverlight. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;After these few steps, you are all set to use the new features described here. Again, remember that this is a super early release, so use with care and revert to V2 if you are encountering issues. Also, please give me feedback and suggestions!&lt;/p&gt;  &lt;h2&gt;What else?&lt;/h2&gt;  &lt;p&gt;I will publish in the next few days a few blog posts about these new features, and also continue to work on new features. As soon as some features are ready, I will push an alpha2 and blog about it. Thanks a lot for the support!!&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;div style="margin-bottom: -1em"&gt;   &lt;div style="vertical-align: middle"&gt;&lt;a href="http://www.galasoft.ch/"&gt;&lt;img title="GalaSoft Laurent Bugnion" alt="GalaSoft Laurent Bugnion" src="http://www.galasoft.ch/logo/Current/logo_120x30.png" /&gt;&lt;/a&gt; &lt;/div&gt;    &lt;div style="position: relative; top: -36px; left: 130px"&gt;&lt;strong&gt;&lt;a href="http://www.galasoft.ch/contact_en.html"&gt;Laurent Bugnion (GalaSoft)&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;&lt;a href="http://feeds.feedburner.com/galasoft"&gt;Subscribe&lt;/a&gt; | &lt;a href="http://twitter.com/lbugnion"&gt;Twitter&lt;/a&gt; | &lt;a href="http://www.facebook.com/lbugnion"&gt;Facebook&lt;/a&gt;| &lt;a href="http://www.flickr.com/photos/lbugnion"&gt;Flickr&lt;/a&gt; | &lt;a href="http://www.linkedin.com/in/lbugnion"&gt;LinkedIn&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135753"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135753" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/lbugnion/aggbug/135753.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Laurent Bugnion</dc:creator>
            <guid>http://geekswithblogs.net/lbugnion/archive/2009/10/27/mvvm-light-toolkit-v3-alpha-1.aspx</guid>
            <pubDate>Tue, 27 Oct 2009 20:05:02 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/lbugnion/comments/135753.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/lbugnion/archive/2009/10/27/mvvm-light-toolkit-v3-alpha-1.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/lbugnion/comments/commentRss/135753.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/lbugnion/services/trackbacks/135753.aspx</trackback:ping>
        </item>
        <item>
            <title>Clean shutdown in Silverlight and WPF applications</title>
            <link>http://geekswithblogs.net/lbugnion/archive/2009/10/18/clean-shutdown-in-silverlight-and-wpf-applications.aspx</link>
            <description>&lt;div class="frame"&gt;&lt;strong&gt;Update:&lt;/strong&gt; There was a small error in the Silverlight version of the application. The code used to navigate to a different webpage was wrong (in ApplicationExtensions.cs). I wrote this article in the Austrian mountains and did not have the web to check the code, sorry about that ;) I &lt;a href="http://galasoft.ch/mvvm/resources/Samples/CleanShutdown.zip"&gt;updated the source code&lt;/a&gt;. If you downloaded the source code before the 19th of October, 8AM GMT, you want to load the correct version. Apologies!! &lt;/div&gt;  &lt;p&gt;It is often difficult for large applications with multiple, loosely coupled components to cleanly shut down. Once a clean shutdown procedure is established, adding new components can disrupt the whole sequence, and things get ugly fast.&lt;/p&gt;  &lt;p&gt;In this article, we will show a way to use a Messenger to create a loosely coupled shutdown sequence, making it easy to add new components if needed. For the sake of the demonstration, we will use the &lt;a href="http://www.galasoft.ch/mvvm/getstarted"&gt;MVVM Light Toolkit Messenger&lt;/a&gt;, but of course this can also be realized with other messaging systems.&lt;/p&gt;  &lt;p&gt;As a bonus, &lt;a href="http://galasoft.ch/mvvm/resources/Samples/CleanShutdown.zip"&gt;the sample application&lt;/a&gt; will also show how to use the same Messenger class to enable communication between two ViewModels that don’t know each other, making it very easy to refactor the application or to modify the client application (for example by adding new screens, etc…).&lt;/p&gt; &lt;object width="400" height="300"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=7116270&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=7116270&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"&gt;&lt;/embed&gt;&lt;/object&gt;  &lt;p&gt;&lt;a href="http://vimeo.com/7116270"&gt;CleanShutdown demo&lt;/a&gt; from &lt;a href="http://vimeo.com/user2473028"&gt;Laurent Bugnion&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;What is a clean shutdown sequence?&lt;/h2&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Easy to request shutdown&lt;/h3&gt;  &lt;p&gt;To cleanly shut down a system, we need a central point from which the shutdown sequence can be started. This central point (we’ll call it the ShutdownService) should be reachable from any place in the application in an easy way. This way, if we add new components, they can request shut down without the ShutdownService needing any modification.&lt;/p&gt;  &lt;h3&gt;Possibility to interrupt shutdown&lt;/h3&gt;  &lt;p&gt;Some components might need a little more time to process important information, to display a “shutdown animation”, to log some information to a web service, etc. Some of these operations might be asynchronous, meaning that the shutdown sequence should be interrupted temporarily. This should be implemented in a way that allows adding new components without the ShutdownService or other components being changed.&lt;/p&gt;  &lt;h3&gt;Being notified upon shutdown&lt;/h3&gt;  &lt;p&gt;Some components might need to be notified when shutdown is happening, for example to save important information to the disk. Here too, we need to be able to add new components without changing anything else.&lt;/p&gt;  &lt;h2&gt;Requesting shutdown&lt;/h2&gt;  &lt;p&gt;This is quite easy: we simply provide a static method in the ShutdownService class. This method called RequestShutdown can be called by any object in the application. A more sophisticated implementation could include a reason for shutdown, letting the ShutdownService decide if the complete shutdown sequence must be executed, of if it should be ignored (for example, in case of a critical application error, a “catastrophic shutdown”, it could be dangerous or impossible to attempt a clean shutdown. Similarly, we could avoid to use a static method, and instead store an instance of the ShutdownService in an IoC container.&lt;/p&gt;  &lt;h2&gt;Giving everyone a possibility to interrupt shutdown&lt;/h2&gt;  &lt;p&gt;The ShutdownService provides a possibility for any object in the application to interrupt shutdown. We use the MVVM Light Toolkit’s Messenger class so that objects can register to be notified when a shutdown sequence starts, and to interrupt it if needed. We will use a &lt;strong&gt;NotificationMessageAction&amp;lt;bool&amp;gt;&lt;/strong&gt;. This message type contains:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A string specifying which operation needs to be initiated. In the case of the shutdown sequence, we will send a string meaning &lt;strong&gt;ConfirmShutdown&lt;/strong&gt;. The recipient of the message can take the opportunity to confirm that shutdown is OK, or to request shutdown to be stopped. &lt;/li&gt;    &lt;li&gt;A callback method (of type Action&amp;lt;bool&amp;gt;) that the recipient can call to prevent shutdown from happening. If the recipient calls the callback with &lt;strong&gt;true&lt;/strong&gt;, the shutdown sequence will be interrupted. If it calls the callback with &lt;strong&gt;false&lt;/strong&gt;, (or if it doesn’t call it at all), the shutdown sequence will continue. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Note that the recipient that interrupts shutdown is responsible for requesting shutdown again, after the asynchronous operation has completed. A more elaborate implementation could use a timeout to force shutdown if the asynchronous operation still did not complete after a certain time.&lt;/p&gt;  &lt;h2&gt;Notifying of imminent shutdown&lt;/h2&gt;  &lt;p&gt;When shutdown is really happening, a last message will be sent to notify recipients that this time, it’s for real. this gives a unique opportunity to recipients to take last minute measures, such as saving their state to a file, etc. In the sample application, we use a &lt;strong&gt;CommandMessage&lt;/strong&gt; with a string meaning &lt;strong&gt;NotifyShutdown&lt;/strong&gt;. Recipients who subscribed to this message can do what needs to be done.&lt;/p&gt;  &lt;h2&gt;Let’s see some code&lt;/h2&gt;  &lt;p&gt;So time to see some code. The source code can be downloaded here. The application can be run in WPF or in Silverlight, and looks like this:&lt;/p&gt; &lt;a title="2009101701 by lbugnionblog, on Flickr" href="http://www.flickr.com/photos/36917929@N06/4019732973/"&gt;&lt;img alt="2009101701" src="http://farm3.static.flickr.com/2481/4019732973_58db213863_o.png" width="420" height="565" /&gt;&lt;/a&gt;   &lt;ul&gt;   &lt;li&gt;The 3 sliders are used to change the color of the application’s background. &lt;/li&gt;    &lt;li&gt;The big X is used to close the application. &lt;/li&gt;    &lt;li&gt;On closing, the values of the 3 sliders are saved to a file. &lt;/li&gt;    &lt;li&gt;When the application starts, the saved values are read from the file and set. &lt;/li&gt;    &lt;li&gt;An animation is played when the application is closed (rotation, scale animation and fade out). &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;ShutdownService&lt;/h3&gt;  &lt;p&gt;This class exposes one static method used by other objects to request shutdown. The class is instantiated on startup by the Application object (in App.xaml.cs).&lt;/p&gt;  &lt;pre class="csharp" name="code"&gt;public static void RequestShutdown()
{
    var shouldAbortShutdown = false;

    Messenger.Default.Send(new NotificationMessageAction&amp;lt;bool&amp;gt;(
        Notifications.ConfirmShutdown,
        shouldAbort =&amp;gt; shouldAbortShutdown |= shouldAbort));

    if (!shouldAbortShutdown)
    {
        // This time it is for real
        Messenger.Default.Send(new CommandMessage(Notifications.NotifyShutdown));

        Application.Current.Shutdown();
    }
}&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;We start by setting a local variable to false. &lt;/li&gt;

  &lt;li&gt;Then we send a message that interested objects can register for. This provides them with a callback that they can call to interrupt shutdown. The callback is implemented as a lambda expression. If at least one recipient replies &lt;em&gt;true&lt;/em&gt;, the variable &lt;em&gt;shouldAbortShutdown&lt;/em&gt; is set to true. &lt;/li&gt;

  &lt;li&gt;Finally, if &lt;em&gt;shouldAbortShutdown&lt;/em&gt; is false (meaning that noone wants to interrupt), we send another message, this time announcing &lt;em&gt;NotifyShutdown&lt;/em&gt;). If anyone registers for this message, they will know that the shutdown is imminent. &lt;/li&gt;

  &lt;li&gt;The last line shuts down the application. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;h3&gt;Playing an animation on shutdown&lt;/h3&gt;

&lt;p&gt;In our sample application, we want to play an animation when the application is shut down. Animations are asynchronous, so we need to temporarily interrupt the shutdown sequence. To do this, we register for the message type NotificationMessageAction&amp;lt;bool&amp;gt;.&lt;/p&gt;

&lt;p&gt;To make it easier to share this code between Silverlight and WPF, we place this code in a class called ShutdownAnimationService. This class is instantiated in the MainWindow (for WPF) or in the Page (for Silverlight).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Some like to see MVVM applications without any code in the code-behind of a View. However, playing animations, showing popups and other functionalities are really the responsibility of the View. &lt;strong&gt;There is nothing wrong in placing code in the View, as long as it is View-specific&lt;/strong&gt;!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre class="csharp" name="code"&gt;Messenger.Default.Register&amp;lt;NotificationMessageAction&amp;lt;bool&amp;gt;&amp;gt;(this, message =&amp;gt;
{
    if (message.Command == Notifications.ConfirmShutdown)
    {
        if (!_shutdownAnimationHasRun)
        {
            var sbd = this.Resources["ShutdownStoryboard"] as Storyboard;
            if (sbd != null)
            {
                message.Execute(true); // true == abort shutdown

                sbd.Completed += ShutdownStoryboardCompleted;
                sbd.Begin();
            }
        }

        // If the animation ran already, no need to reply
        // to the message, allow shutdown.
    }
});&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;When a message of type NotificationMessageAction&amp;lt;bool&amp;gt; is sent (which is what the ShutdownService does), the lambda expression is executed. &lt;/li&gt;

  &lt;li&gt;First we check a global variable that tells us if the animation ran already. &lt;/li&gt;

  &lt;li&gt;If it didn’t run yet, we check if there is a Storyboard named ShutdownStoryboard in the resources. If we don’t find it, we let the shutdown happen (this is just a failsafe in case something went wrong with the Storyboard). &lt;/li&gt;

  &lt;li&gt;If we do find the storyboard, we execute the callback with &lt;strong&gt;true&lt;/strong&gt; meaning that we interrupt the shutdown sequence. &lt;/li&gt;

  &lt;li&gt;Finally, we assign a “completed” event to the Storyboard and we start it. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember that it is now the responsibility of this object to restart the shutdown sequence! It is done in the completed event of the Storyboard:&lt;/p&gt;

&lt;pre class="csharp" name="code"&gt;void ShutdownStoryboardCompleted(object sender, System.EventArgs e)
{
    _shutdownAnimationHasRun = true;

    // Now that our pre-shutdown task is done
    // we can request shutdown again.
    ShutdownService.RequestShutdown();
}&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Note: The animation is defined in the Page.xaml (for Silverlight) and in MainWindow.xaml (for WPF) and not in MainSkin.xaml. While storing the animation in the external resource dictionary would work in WPF, it fails in Silverlight.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;Saving settings to a file&lt;/h3&gt;

&lt;p&gt;The class SettingsViewModel defines three properties (Red, Green and Blue) that are databound to the 3 sliders. In fact, the SettingsViewModel is the D&lt;em&gt;ataContext &lt;/em&gt;of the half-white panel on the left of the X button.&lt;/p&gt;

&lt;pre class="csharp" name="code"&gt;public SettingsViewModel()
{
    if (!IsInDesignMode)
    {
        Messenger.Default.Register&amp;lt;CommandMessage&amp;gt;(this, m =&amp;gt;
        {
            if (m.Command == Notifications.NotifyShutdown)
            {
                SaveSettings();
            }
        });
        
        _settingsFile = new SettingsFileHandler();

        var savedSettings = _settingsFile.LoadSettings();
        Messenger.Default.Send&amp;lt;Brush, MainViewModel&amp;gt;(
            savedSettings.ApplicationBackgroundBrush);

        _isLoading = true;

        var solidBrush
            = savedSettings.ApplicationBackgroundBrush as SolidColorBrush;
        if (solidBrush != null)
        {
            Red = solidBrush.Color.R;
            Green = solidBrush.Color.G;
            Blue = solidBrush.Color.B;
        }

        _isLoading = false;
    }
}&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;SettingsViewModel registers to receive messages of type CommandMessage. If the CommandMessage’s content is NotifyShutdown, it means the application is closing, and the object saves its state in a file. &lt;/li&gt;

  &lt;li&gt;The rest of the constructor is used to load existing settings, and send an initial message to the MainViewModel to set the saved brush as the application background (see the section below titled “Sending messages from a ViewModel to another” for more details). &lt;/li&gt;

  &lt;li&gt;Finally, we set the sliders to values corresponding to the saved ones. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The saving itself happens in SettingsFileHandler, which is also responsible for loading the settings when the application starts.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;In WPF, saving the settings and reading them back is made with the XamlWriter, resp XamlReader. These two classes are very useful to save any CLR object to a XAML file, and to restore it. In this sample, we save to the Temp folder, but a normal implementation would save to the AppData folder. &lt;/li&gt;

  &lt;li&gt;In Silverlight, we don’t have XamlWriter, so we save to a plain text file in the IsolatedStorage instead, as explained in the section titled “Specific implementation details for Silverlight”. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;h3&gt;Requesting shutdown when the button is pressed&lt;/h3&gt;

&lt;p&gt;The MainViewModel is set as the DataContext of the application’s window (in Silverlight, of the Page), with the exception of the half-white area with the 3 sliders (which is bound to the SettingsViewModel). Clicking the X button executes a RelayCommand defined in the MainViewModel. This command is very simple: It just calls the RequestShutdown method.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;ShutdownCommand = new RelayCommand(ShutdownService.RequestShutdown);&lt;/pre&gt;

&lt;h3&gt;Sending messages from a ViewModel to another&lt;/h3&gt;

&lt;p&gt;Another thing the MainViewModel does it define a bindable property called BackgroundBrush. This property, when updated, automatically sets the background of the application (through databinding). However, how do we know when the user changes the Brush?&lt;/p&gt;

&lt;p&gt;In this simple application, we don’t really need two ViewModels. However, it makes sense to have them: If we decided to move the 3 sliders to a popup, for example, or to another window, it would be very easy to do, thanks to the separation of concerns: MainViewModel takes care of the MainWindow, SettingsViewModel takes care of the settings.&lt;/p&gt;

&lt;p&gt;This poses a problem however: Since both ViewModels are separated, how can they communicate without being tightly coupled, which we really want to avoid. Well this is another usage for the Messenger: The MainViewModel registers for any message of type Brush:&lt;/p&gt;

&lt;pre class="csharp" name="code"&gt;public MainViewModel()
{
    if (IsInDesignMode)
    {
        BackgroundBrush = new SolidColorBrush(Colors.Orange);
    }
    else
    {
        Messenger.Default.Register&amp;lt;Brush&amp;gt;(
            this, 
            true, 
            m =&amp;gt; BackgroundBrush = m);

        ShutdownCommand
            = new RelayCommand(ShutdownService.RequestShutdown);
    }
}&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Whenever a message of type Brush is received, we just set the BackgroundBrush to it. 
      &lt;br /&gt;&lt;em&gt;The Messenger class can be used to send any message type, from simple values to complex objects!&lt;/em&gt;&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;Note that we use an overload of the Register application: The second parameter is set to true, indicating that we want to receive all messages of type Brush, and derived types too (SolidColorBrush, LinearGradientBrush, etc…).&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;If we are in design mode (running in Expression Blend for example), we set the brush to Orange, so that we have something to see (otherwise the window would be transparent).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, we need someone to send updates! This is the SettingsViewModel’s task: When the user moves the sliders, we send a message of type SolidColorBrush, corresponding to the value of the 3 sliders. We do, however, send this message only to MainViewModel, thus avoiding too much unnecessary communication.&lt;/p&gt;

&lt;pre class="csharp" name="code"&gt;private void SendBrushUpdate()
{
    if (_isLoading)
    {
        return;
    }

    Messenger.Default.Send&amp;lt;Brush, MainViewModel&amp;gt;(
      GetCurrentBrush());
}

private Brush GetCurrentBrush()
{
    return new SolidColorBrush(
      Color.FromArgb(255, Red, Green, Blue));
}&lt;/pre&gt;

&lt;h3&gt;Specific implementation details for Silverlight&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Most objects in this application are shared between WPF and Silverlight. 
    &lt;br /&gt;&lt;em&gt;Reminder: To share objects, you can right click on a folder, select “Add, Existing Item” from the context menu. Browse to the item you want to share, then instead of clicking on the “Add” button, click on the small arrow within this button, and choose “Add as a Link” from the menu that opens.&lt;/em&gt; &lt;/li&gt;

  &lt;li&gt;Instead of saving the settings to the file system (which is not allowed in Silverlight), we save to the IsolatedStorage. The class SettingsFileHandler is not the same in Silverlight than in WPF, and takes care of this implementation detail. &lt;/li&gt;

  &lt;li&gt;Similarly, we do not have a XAML Writer in Silverlight, unfortunately. Instead of saving the settings to XAML (which is very easy and convenient), we use an extension of the partial class Settings (available only in the Silverlight version of the application) to serialize to a text format, and to deserialize from it. &lt;/li&gt;

  &lt;li&gt;Finally, we cannot shut down the application in Silverlight. We can, however, navigate to a different web page. Since the Shutdown() method doesn’t exist in the Application class in Silverlight, we provide an extension method (in the class ApplicationExtensions) with the same name. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These few techniques (partial class with specific Silverlight extensions, extension methods, adding items as link) help to “bridge the gap” between WPF and Silverlight and to write less code while providing similar functionality.&lt;/p&gt;

&lt;h2&gt;About NotificationMessageAction&lt;/h2&gt;

&lt;p&gt;This useful message type (allowing to send a notification and providing a callback to the recipient) is not yet part of the MVVM Light Toolkit V2, but will be included in future versions. An implementation is provided as part of the sample application, but is not final yet. Comments or feedback is welcomed!&lt;/p&gt;

&lt;h2&gt;Source code&lt;/h2&gt;

&lt;p&gt;The &lt;a href="http://galasoft.ch/mvvm/resources/Samples/CleanShutdown.zip"&gt;sample application’s source code&lt;/a&gt; can be downloaded from my site.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This sample application shows two usages of the Messenger class:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Enable communication between decoupled ViewModels. &lt;/li&gt;

  &lt;li&gt;Create a clean shutdown sequence that can easily be extended with new objects if necessary. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are of course many other situations where a Messenger can be useful in an application. I hope to have awaken your interest for this very powerful yet simple to use component. For more information about the Messenger, RelayCommands or other parts of the MVVM Light Toolkit, please refer &lt;a href="http://www.galasoft.ch/mvvm/getstarted"&gt;to the Get Started page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="margin-bottom: -1em"&gt;
  &lt;div style="vertical-align: middle"&gt;&lt;a href="http://www.galasoft.ch/"&gt;&lt;img title="GalaSoft Laurent Bugnion" alt="GalaSoft Laurent Bugnion" src="http://www.galasoft.ch/logo/Current/logo_120x30.png" /&gt;&lt;/a&gt; &lt;/div&gt;

  &lt;div style="position: relative; top: -36px; left: 130px"&gt;&lt;strong&gt;&lt;a href="http://www.galasoft.ch/contact_en.html"&gt;Laurent Bugnion (GalaSoft)&lt;/a&gt;&lt;/strong&gt; 

    &lt;br /&gt;&lt;a href="http://feeds.feedburner.com/galasoft"&gt;Subscribe&lt;/a&gt; | &lt;a href="http://twitter.com/lbugnion"&gt;Twitter&lt;/a&gt; | &lt;a href="http://www.facebook.com/lbugnion"&gt;Facebook&lt;/a&gt;| &lt;a href="http://www.flickr.com/photos/lbugnion"&gt;Flickr&lt;/a&gt; | &lt;a href="http://www.linkedin.com/in/lbugnion"&gt;LinkedIn&lt;/a&gt; &lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135531"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135531" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/lbugnion/aggbug/135531.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Laurent Bugnion</dc:creator>
            <guid>http://geekswithblogs.net/lbugnion/archive/2009/10/18/clean-shutdown-in-silverlight-and-wpf-applications.aspx</guid>
            <pubDate>Sun, 18 Oct 2009 19:25:56 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/lbugnion/comments/135531.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/lbugnion/archive/2009/10/18/clean-shutdown-in-silverlight-and-wpf-applications.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/lbugnion/comments/commentRss/135531.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/lbugnion/services/trackbacks/135531.aspx</trackback:ping>
        </item>
        <item>
            <title>MVVM Light Toolkit on Codeplex</title>
            <link>http://geekswithblogs.net/lbugnion/archive/2009/10/18/mvvm-light-toolkit-on-codeplex.aspx</link>
            <description>&lt;p&gt;Responding to a few requests from MVVM Light Toolkit users, I opened a project on Codeplex and published the installer as well as the source code there.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://mvvmlight.codeplex.com/"&gt;http://mvvmlight.codeplex.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Formally, nothing much changes, &lt;a href="http://www.galasoft.ch/mvvm/getstarted"&gt;my site&lt;/a&gt; and &lt;a href="http://blog.galasoft.ch/lbugnion/category/10201.aspx"&gt;my blog&lt;/a&gt; remain the main location to find information on the toolkit. Being on Codeplex gives the project more visibility, and provides a convenient place for discussions too.&lt;/p&gt;  &lt;p&gt;Happy coding!&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;div style="margin-bottom: -1em;"&gt;   &lt;div style="vertical-align: middle"&gt;&lt;a href="http://www.galasoft.ch/"&gt;&lt;img title="GalaSoft Laurent Bugnion" alt="GalaSoft Laurent Bugnion" src="http://www.galasoft.ch/logo/Current/logo_120x30.png" /&gt;&lt;/a&gt; &lt;/div&gt;    &lt;div style="position: relative; top: -36px; left: 130px"&gt;&lt;strong&gt;&lt;a href="http://www.galasoft.ch/contact_en.html"&gt;Laurent Bugnion (GalaSoft)&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;&lt;a href="http://feeds.feedburner.com/galasoft"&gt;Subscribe&lt;/a&gt; | &lt;a href="http://twitter.com/lbugnion"&gt;Twitter&lt;/a&gt; | &lt;a href="http://www.facebook.com/lbugnion"&gt;Facebook&lt;/a&gt;| &lt;a href="http://www.flickr.com/photos/lbugnion"&gt;Flickr&lt;/a&gt; | &lt;a href="http://www.linkedin.com/in/lbugnion"&gt;LinkedIn&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135527"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135527" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/lbugnion/aggbug/135527.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Laurent Bugnion</dc:creator>
            <guid>http://geekswithblogs.net/lbugnion/archive/2009/10/18/mvvm-light-toolkit-on-codeplex.aspx</guid>
            <pubDate>Sun, 18 Oct 2009 12:42:31 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/lbugnion/comments/135527.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/lbugnion/archive/2009/10/18/mvvm-light-toolkit-on-codeplex.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/lbugnion/comments/commentRss/135527.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/lbugnion/services/trackbacks/135527.aspx</trackback:ping>
        </item>
        <item>
            <title>MVVM Light Toolkit V2: What&amp;rsquo;s new?</title>
            <link>http://geekswithblogs.net/lbugnion/archive/2009/10/03/mvvm-light-toolkit-v2-whatrsquos-new.aspx</link>
            <description>&lt;p&gt;I am happy and proud to announce that the &lt;a href="http://www.galasoft.ch/mvvm/getstarted"&gt;MVVM Light Toolkit V2 has been published&lt;/a&gt;! &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Shortcut: &lt;a href="http://www.galasoft.ch/mvvm/installing/"&gt;Jump directly to the installation instructions&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Excerpt from the &lt;a href="http://www.galasoft.ch/mvvm/getstarted"&gt;Get Started page&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;The main purpose of the toolkit is to accelerate the creation and development of MVVM applications in WPF and Silverlight.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Like other MVVM implementations, the toolkit helps you to &lt;strong&gt;separate your View from your Model&lt;/strong&gt; which creates applications that are &lt;strong&gt;cleaner and easier to maintain and extend&lt;/strong&gt;. It also creates &lt;strong&gt;testable applications&lt;/strong&gt; and allows you to have a much thinner user interface layer (which is more difficult to test automatically).&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;This toolkit puts a special emphasis on the &lt;strong&gt;"blendability"&lt;/strong&gt; of the created application (i.e. the ability to open and &lt;strong&gt;edit the user interface into Expression Blend)&lt;/strong&gt;, including the creation of design-time data to enable the Blend users to "see something" when they work with data controls.&lt;/em&gt;&lt;/p&gt;  &lt;h2&gt;What’s new?&lt;/h2&gt;  &lt;p&gt;So what is new in V2? Here is a list that should help you adapt your existing applications to the new version.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;New Messenger API&lt;/h3&gt;  &lt;p&gt;The major change in this release is the &lt;strong&gt;new and improved Messenger class&lt;/strong&gt;. The API has been reworked and simplified to make sending and registering for messages a one-liner each. Any type of message can now be sent, from simple values (int, double, string etc…) to complex messages.&lt;/p&gt;  &lt;p&gt;The old methods are still available, however they have been marked Obsolete, which will cause warnings to appear in the Output window of Visual Studio when you build an existing application. I encourage you to upgrade to the new API, which should be quite harmless and rewarding.&lt;/p&gt;  &lt;p&gt;There is also an IMessenger interface that the Messenger implements, which makes mocking and testing easier.&lt;/p&gt;  &lt;p&gt;The new methods are &lt;a href="http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx"&gt;described in an existing blog post&lt;/a&gt;, and additional blog posts around this component will follow.&lt;/p&gt;  &lt;h3&gt;Expression Blend templates&lt;/h3&gt;  &lt;p&gt;The MVVM Light templates (project templates and item templates) are &lt;strong&gt;now installed for Expression Blend 3 too&lt;/strong&gt;. You can create and run new MVVM Light applications in this fantastic tool. With the help of the Blend source code editor, you can even consider writing simple MVVM applications without using Visual Studio at all (though for more complex applications, this might prove difficult).&lt;/p&gt;  &lt;p&gt;More information about creating new applications in Expression Blend can be found &lt;a href="http://www.galasoft.ch/mvvm/creatingblend/"&gt;in a related article&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Never miss a new version!&lt;/h3&gt;  &lt;p&gt;I wanted to make a small application to help you check really fast if a new version of the MVVM Light Toolkit is available for download. Simply choose Start / MVVM Light Toolkit / Check Version On Server, et voila. It’s simple and fast (of course, an Internet connection is required ;)) More information &lt;a href="http://www.galasoft.ch/mvvm/installing/#newversion"&gt;about this application is available here&lt;/a&gt;. Oh, by the way, this is, of course, an MVVM Light application.&lt;/p&gt;  &lt;h3&gt;Easier to find in the Start menu&lt;/h3&gt;  &lt;p&gt;The shortcuts for V1.1 were installed in Start / All Programs / Laurent Bugnion (GalaSoft) / MVVM Light Toolkit. This was not very convenient, and made them more difficult to find than it should be. I changed this, and the shortcuts are now under Start / All Programs / MVVM Light Toolkit.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Note: The V2 installer attempts to delete the shortcut folder “Laurent Bugnion (GalaSoft)”, since it is not needed anymore. Depending on your system’s configuration, this step might be unsuccessful, and you might have to delete this shortcut folder manually.&lt;/em&gt;&lt;/p&gt;  &lt;h3&gt;Minor changes&lt;/h3&gt;  &lt;p&gt;A few minor changes have been made, that shouldn’t affect the way that the Toolkit works, but make things a bit cleaner:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The method RelayCommand.RaiseCanExecuteChanged(bool) has been marked Obsolete and replaced by RelayCommand.RaiseCanExecuteChanged(). The parameter was not really necessary and has been removed. &lt;/li&gt;    &lt;li&gt;In the “Add new project” dialog in Visual Studio, the WPF project template has been moved from “MVVM” to “Windows / MVVM”. It makes more sense to put all the WPF content under the Windows category. &lt;/li&gt;    &lt;li&gt;In the project template for WPF, I moved the resource dictionary "Skin.xaml” to a folder named “Skins” and I renamed the file “MainSkin.xaml”. &lt;/li&gt;    &lt;li&gt;For consistency, in Silverlight, I also added a “Skins” folder in the project template, and moved all the resources from App.xaml to MainSkin.xaml. Note that this features will not work in Silverlight 2 applications (but hey it’s time to move on, right?). &lt;/li&gt;    &lt;li&gt;Cosmetic changes: Quite a few small improvements (“polish”) have been made to make the experience (installing and using the toolkit) more consistent and clean. &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Bugs corrections&lt;/h3&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;p&gt;There were a few issues with V1.1 that have been corrected in V2:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A scenario I had not envisioned was causing issues: When a recipient would receive a message, and in the method handling that message would register another recipient for the same message type, an Exception occurred. This bug has been corrected and unit tests added to verify this behavior.      &lt;br /&gt;&lt;em&gt;Thanks to &lt;a href="http://www.techheadbrothers.com/Auteurs.aspx/laurent-kempe" target="_blank"&gt;Laurent Kempé&lt;/a&gt; for finding this one and helping me solve it, &lt;a href="http://www.innoveo.com" target="_blank"&gt;and to Innoveo&lt;/a&gt; for giving him some time to do this.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;The property ViewModelBase.IsInDesignMode was returning false all the time when the assembly was compiled in Release mode. The value is now correct in Debug and Release modes. &lt;/li&gt;    &lt;li&gt;(Silverlight only) When a RelayCommand was bound to a control, the control was not disabled properly if the command’s CanExecute method was returning false before it was bound.      &lt;br /&gt;&lt;em&gt;Props go to &lt;a href="http://blogs.ugidotnet.org/corrado/Default.aspx" target="_blank"&gt;Corrado Cavalli&lt;/a&gt; for finding this bug.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;The manual step that was required when creating a new Silverlight MVVM Light application is not required anymore. I modified the project template to take care of this. &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Conclusion&lt;/h2&gt;  &lt;p&gt;With these changes, the MVVM Light Toolkit should be easier to use, which is my main goal and the motivation that drives me.&lt;/p&gt;  &lt;p&gt;In next releases, new components will be added to make MVVM application development more fun and enjoyable. I am very careful when I add a new component to the toolkit to keep it “light”. The MVVM Light Toolkit is not a “solution to all the problems”, and never will be. It does, however, make it quite easy to start creating clean applications in Silverlight and Windows Presentation Foundation. Its stated goals (improving the blendability of applications, making them easier to test, separation of concerns, avoiding “component overload”) are, I hope, respected. I encourage you to give me feedback (many already did, and I am grateful for that) and new ideas.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;div style="margin-bottom: -1em"&gt;   &lt;div style="vertical-align: middle"&gt;&lt;a href="http://www.galasoft.ch/"&gt;&lt;img title="GalaSoft Laurent Bugnion" alt="GalaSoft Laurent Bugnion" src="http://www.galasoft.ch/logo/Current/logo_120x30.png" /&gt;&lt;/a&gt; &lt;/div&gt;    &lt;div style="position: relative; top: -36px; left: 130px"&gt;&lt;strong&gt;&lt;a href="http://www.galasoft.ch/contact_en.html"&gt;Laurent Bugnion (GalaSoft)&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;&lt;a href="http://feeds.feedburner.com/galasoft"&gt;Subscribe&lt;/a&gt; | &lt;a href="http://twitter.com/lbugnion"&gt;Twitter&lt;/a&gt; | &lt;a href="http://www.facebook.com/lbugnion"&gt;Facebook&lt;/a&gt;| &lt;a href="http://www.flickr.com/photos/lbugnion"&gt;Flickr&lt;/a&gt; | &lt;a href="http://www.linkedin.com/in/lbugnion"&gt;LinkedIn&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135287"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135287" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/lbugnion/aggbug/135287.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Laurent Bugnion</dc:creator>
            <guid>http://geekswithblogs.net/lbugnion/archive/2009/10/03/mvvm-light-toolkit-v2-whatrsquos-new.aspx</guid>
            <pubDate>Sun, 04 Oct 2009 11:06:30 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/lbugnion/comments/135287.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/lbugnion/archive/2009/10/03/mvvm-light-toolkit-v2-whatrsquos-new.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/lbugnion/comments/commentRss/135287.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/lbugnion/services/trackbacks/135287.aspx</trackback:ping>
        </item>
        <item>
            <title>MVVM Light Toolkit Messenger V2 beta</title>
            <link>http://geekswithblogs.net/lbugnion/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx</link>
            <description>&lt;div class="frame"&gt;&lt;strong&gt;Update&lt;/strong&gt;: &lt;a href="http://www.galasoft.ch/mvvm/getstarted"&gt;MVVM Light Toolkit V2 has been released&lt;/a&gt;. Please use the new installer to upgrade your installation.&lt;/div&gt;  &lt;p&gt;Ever since I released V1.1 of the &lt;a href="http://www.galasoft.ch/mvvm/getstarted"&gt;MVVM Light Toolkit&lt;/a&gt;, I have received wonderful and constructive feedback from users. Most of it is flowing into V2, which is almost ready (I am still fighting a little with MSI installers and project/item templates for one feature I am particularly happy about, which is making project templates and item templates available in Expression Blend. That’s right, with V2 you can start Blend, and choose “File / New Project / MVVM Light”, then press F5 to have an application running.&lt;/p&gt;  &lt;p&gt;IMHO the most interesting and innovative change in the toolkit is the new &lt;strong&gt;Messenger&lt;/strong&gt;. In V1.1, quite a lot of plumbing as involved to register for messages, and to send messages. You had to implement IMessageRecipient to get messages, and all messages had to inherit the MessageBase class. Let’s face it, this was a bad idea. Thankfully, Glenn Block (of MEF and Prism fame) called me on that, and suggested a much, much cleaner implementation: Get rid of IMessageRecipient and use Actions instead to register for messages. Get rid of MessageBase and allow me to send anything through the Messenger.&lt;/p&gt;  &lt;h2&gt;The new API&lt;/h2&gt;  &lt;p&gt;This immediately appealed to me (and to some of my users whom I talked to) and I propose to you the Messenger V2. It implements the&lt;strong&gt; IMessenger&lt;/strong&gt; interface, which should make mocking and testing easier. The interface looks like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="csharp" name="code"&gt;/// &amp;lt;summary&amp;gt;
/// Registers a recipient for a type of message TMessage. The &amp;lt;see cref="action" /&amp;gt;
/// parameter will be executed when a corresponding message is sent.
/// &amp;lt;para&amp;gt;Registering a recipient does not create a hard reference to it,
/// so if this recipient is deleted, no memory leak is caused.&amp;lt;/para&amp;gt;
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name="TMessage"&amp;gt;The type of message that the recipient registers
/// for.&amp;lt;/typeparam&amp;gt;
/// &amp;lt;param name="recipient"&amp;gt;The recipient that will receive the messages.&amp;lt;/param&amp;gt;
/// &amp;lt;param name="action"&amp;gt;The action that will be executed when a message
/// of type TMessage is sent.&amp;lt;/param&amp;gt;
void Register&amp;lt;TMessage&amp;gt;(object recipient, Action&amp;lt;TMessage&amp;gt; action);

/// &amp;lt;summary&amp;gt;
/// Registers a recipient for a type of message TMessage.
/// The &amp;lt;see cref="action" /&amp;gt; parameter will be executed when a corresponding 
/// message is sent. See the &amp;lt;see cref="receiveDerivedMessagesToo" /&amp;gt; parameter
/// for details on how messages deriving from TMessage (or, if TMessage is an interface,
/// messages implementing TMessage) can be received too.
/// &amp;lt;para&amp;gt;Registering a recipient does not create a hard reference to it,
/// so if this recipient is deleted, no memory leak is caused.&amp;lt;/para&amp;gt;
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name="TMessage"&amp;gt;The type of message that the recipient registers
/// for.&amp;lt;/typeparam&amp;gt;
/// &amp;lt;param name="recipient"&amp;gt;The recipient that will receive the messages.&amp;lt;/param&amp;gt;
/// &amp;lt;param name="receiveDerivedMessagesToo"&amp;gt;If true, message types deriving from
/// TMessage will also be transmitted to the recipient. For example, if a SendOrderMessage
/// and an ExecuteOrderMessage derive from OrderMessage, registering for OrderMessage
/// and setting receiveDerivedMessagesToo to true will send SendOrderMessage
/// and ExecuteOrderMessage to the recipient that registered.
/// &amp;lt;para&amp;gt;Also, if TMessage is an interface, message types implementing TMessage will also be
/// transmitted to the recipient. For example, if a SendOrderMessage
/// and an ExecuteOrderMessage implement IOrderMessage, registering for IOrderMessage
/// and setting receiveDerivedMessagesToo to true will send SendOrderMessage
/// and ExecuteOrderMessage to the recipient that registered.&amp;lt;/para&amp;gt;
/// &amp;lt;/param&amp;gt;
/// &amp;lt;param name="action"&amp;gt;The action that will be executed when a message
/// of type TMessage is sent.&amp;lt;/param&amp;gt;
void Register&amp;lt;TMessage&amp;gt;(object recipient, bool receiveDerivedMessagesToo, Action&amp;lt;TMessage&amp;gt; action);

/// &amp;lt;summary&amp;gt;
/// Sends a message to registered recipients. The message will
/// reach all recipients that registered for this message type
/// using one of the Register methods.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name="TMessage"&amp;gt;The type of message that will be sent.&amp;lt;/typeparam&amp;gt;
/// &amp;lt;param name="message"&amp;gt;The message to send to registered recipients.&amp;lt;/param&amp;gt;
void Send&amp;lt;TMessage&amp;gt;(TMessage message);

/// &amp;lt;summary&amp;gt;
/// Sends a message to registered recipients. The message will
/// reach only recipients that registered for this message type
/// using one of the Register methods, and that are
/// of the targetType.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name="TMessage"&amp;gt;The type of message that will be sent.&amp;lt;/typeparam&amp;gt;
/// &amp;lt;typeparam name="TTarget"&amp;gt;The type of recipients that will receive
/// the message. The message won't be sent to recipients of another type.&amp;lt;/typeparam&amp;gt;
/// &amp;lt;param name="message"&amp;gt;The message to send to registered recipients.&amp;lt;/param&amp;gt;
void Send&amp;lt;TMessage, TTarget&amp;gt;(TMessage message);

/// &amp;lt;summary&amp;gt;
/// Unregisters a messager recipient completely. After this method
/// is executed, the recipient will not receive any messages anymore.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name="recipient"&amp;gt;The recipient that must be unregistered.&amp;lt;/param&amp;gt;
void Unregister(object recipient);

/// &amp;lt;summary&amp;gt;
/// Unregisters a message recipient for a given type of messages only. 
/// After this method is executed, the recipient will not receive messages
/// of type TMessage anymore, but will still receive other message types (if it
/// registered for them previously).
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name="TMessage"&amp;gt;The type of messages that the recipient wants
/// to unregister from.&amp;lt;/typeparam&amp;gt;
/// &amp;lt;param name="recipient"&amp;gt;The recipient that must be unregistered.&amp;lt;/param&amp;gt;
void Unregister&amp;lt;TMessage&amp;gt;(object recipient);

/// &amp;lt;summary&amp;gt;
/// Unregisters a message recipient for a given type of messages and for
/// a given action. Other message types will still be transmitted to the
/// recipient (if it registered for them previously). Other actions that have
/// been registered for the message type TMessage and for the given recipient (if
/// available) will also remain available.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name="TMessage"&amp;gt;The type of messages that the recipient wants
/// to unregister from.&amp;lt;/typeparam&amp;gt;
/// &amp;lt;param name="recipient"&amp;gt;The recipient that must be unregistered.&amp;lt;/param&amp;gt;
/// &amp;lt;param name="action"&amp;gt;The action that must be unregistered for
/// the recipient and for the message type TMessage.&amp;lt;/param&amp;gt;
void Unregister&amp;lt;TMessage&amp;gt;(object recipient, Action&amp;lt;TMessage&amp;gt; action);&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;h2&gt;No Memory Leaks&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;One neat thing with the Messenger (already in V1 and of course also in V2) is that the objects are referenced using &lt;a href="http://msdn.microsoft.com/en-us/library/system.weakreference.aspx"&gt;WeakReferences&lt;/a&gt;. Even though &lt;strong&gt;I recommend to unregister explicitly&lt;/strong&gt; when you want to delete the message recipient, if you omit to do so, you won’t cause a memory leak, because the Messenger does not keep a hard reference to the recipient.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Backwards compatibility&lt;/h2&gt;

&lt;p&gt;All V1 methods are still available, but marked as Obsolete. This allows a smooth evolution of existing projects to the new syntax. When you build existing projects with the new toolkit, you will get warnings with a suggestion to move to the new syntax.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;MessageBase&lt;/strong&gt; class and the deriving message types (GenericMessage, CommandMessage, CommandMessageGeneric, DialogMessage, PropertyChangedMessage) are still available as suggestions for the payload (i.e. you can use them if you like, but you can also build your own messages, or send anything you want (objects, simple value types, etc…). It is perfectly legal to do:&lt;/p&gt;

&lt;pre class="csharp" name="code"&gt;// Somewhere
Messenger.Default.Register&amp;lt;string&amp;gt;(this, DoSomething);

// Further
private void DoSomething(string message)
{
    // ...
}

// Somewhere else
Messenger.Default.Send(“Hello world”);&lt;/pre&gt;

&lt;h2&gt;Default Messenger, mocking, testing, IoC&lt;/h2&gt;

&lt;p&gt;Note that like in V1, you can either use the default Messenger (Messenger.Default) or create your own messengers, for example to create specialized channels of communication. Since the IMessenger interface is now available, you can easily mock, test, use IoC containers, etc…&lt;/p&gt;

&lt;p&gt;The Messenger V2 as well as the rest of the toolkit will be available in a few days, and I will also prepare sample applications to demonstrate the use more in-depth.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="margin-bottom: -1em"&gt;
  &lt;div style="vertical-align: middle"&gt;&lt;a href="http://www.galasoft.ch/"&gt;&lt;img title="GalaSoft Laurent Bugnion" alt="GalaSoft Laurent Bugnion" src="http://www.galasoft.ch/logo/Current/logo_120x30.png" /&gt;&lt;/a&gt; &lt;/div&gt;

  &lt;div style="position: relative; top: -36px; left: 130px"&gt;&lt;strong&gt;&lt;a href="http://www.galasoft.ch/contact_en.html"&gt;Laurent Bugnion (GalaSoft)&lt;/a&gt;&lt;/strong&gt; 

    &lt;br /&gt;&lt;a href="http://feeds.feedburner.com/galasoft"&gt;Subscribe&lt;/a&gt; | &lt;a href="http://twitter.com/lbugnion"&gt;Twitter&lt;/a&gt; | &lt;a href="http://www.facebook.com/lbugnion"&gt;Facebook&lt;/a&gt;| &lt;a href="http://www.flickr.com/photos/lbugnion"&gt;Flickr&lt;/a&gt; | &lt;a href="http://www.linkedin.com/in/lbugnion"&gt;LinkedIn&lt;/a&gt; &lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135121"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135121" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/lbugnion/aggbug/135121.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Laurent Bugnion</dc:creator>
            <guid>http://geekswithblogs.net/lbugnion/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx</guid>
            <pubDate>Sun, 27 Sep 2009 13:16:05 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/lbugnion/comments/135121.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/lbugnion/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/lbugnion/comments/commentRss/135121.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/lbugnion/services/trackbacks/135121.aspx</trackback:ping>
        </item>
        <item>
            <title>Using RelayCommands in Silverlight and WPF</title>
            <link>http://geekswithblogs.net/lbugnion/archive/2009/09/26/using-relaycommands-in-silverlight-and-wpf.aspx</link>
            <description>&lt;p&gt;Like most of us have found out the hard way, Silverlight 3 and Windows Presentation Foundation 3.5 are two quite similar beasts, but not totally the same. Silverlight is often presented as a subset of WPF (in fact, some features are available in Silverlight but not yet in WPF; generally speaking, though, it is true that Silverlight has less features than its big sister WPF) (yeah WPF is a girl, don’t tell me you didn’t know ;))&lt;/p&gt;  &lt;h2&gt;No Commands in Silverlight&lt;/h2&gt;  &lt;p&gt;One of the missing parts is &lt;a href="http://msdn.microsoft.com/en-us/library/ms752308.aspx" target="_blank"&gt;Commanding&lt;/a&gt;. Commands in WPF are used as a kind of “weak events”, i.e. they can be used to execute an action when a control is actuated (just like an event), but without the tight coupling that an event brings with it. You can specify a Command on an object, and &lt;em&gt;bind&lt;/em&gt; this command to a control in a completely different part of your application. You can have one person write the Command (typically a developer), and a completely other person (typically a designer) use the Command in the user interface. More interestingly, the designer can change the look and feel, for example replacing a series of Buttons by a Menu and MenuItems, and the developer doesn’t need to change anything to the code.&lt;/p&gt;  &lt;p&gt;In Silverlight, parts of the “plumbing” are available already (the &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.aspx" target="_blank"&gt;ICommand&lt;/a&gt;&lt;/strong&gt; interface) but most of it is missing. This led some very clever people to implement Commands in Silverlight, to replace the missing pieces by a custom implementation. In &lt;a href="http://compositewpf.codeplex.com/" target="_blank"&gt;Prism&lt;/a&gt;, the command implementation is called &lt;strong&gt;DelegateCommand&lt;/strong&gt;. In my &lt;a href="http://www.galasoft.ch/mvvm/getstarted"&gt;MVVM Light Toolkit&lt;/a&gt;, I use a command that my good friend, colleague at IdentityMine and fellow WPF Disciple &lt;a href="http://joshsmithonwpf.wordpress.com/" target="_blank"&gt;Josh Smith&lt;/a&gt; created, called the &lt;strong&gt;RelayCommand&lt;/strong&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Now, the beautiful part is that RelayCommands (and DelegateCommands too) work wonders in Silverlight, but also in WPF. RelayCommands are making your life much easier in WPF too. No need to implement complicated code to bind the control to your method, just use a RelayCommand to do that. And since the implementation is (almost) the same in Silverlight too, you can share code between Silverlight and WPF.&lt;/p&gt;  &lt;h2&gt;The Execute Method&lt;/h2&gt;  &lt;p&gt;When the control to which a Command is bound is actuated by the user, the &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.execute.aspx" target="_blank"&gt;Execute&lt;/a&gt;&lt;/strong&gt; method is called. This method is specified by the ICommand interface, and every ICommand implementation must offer it (and of course RelayCommand does).&lt;/p&gt;  &lt;p&gt;The Execute method is passed to the RelayCommand’s constructor in form of an &lt;a href="http://msdn.microsoft.com/en-us/library/system.action.aspx" target="_blank"&gt;Action&lt;/a&gt; (or &lt;a href="http://msdn.microsoft.com/en-us/library/018hxwa8.aspx" target="_blank"&gt;Action&amp;lt;T&amp;gt;&lt;/a&gt; if the command has a parameter, in which case you must use the RelayCommand&amp;lt;T&amp;gt; class).&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Note: An Action is a method  (returning void) that can be passed to another object, for example as a parameter. It is something like a method pointer. If the method that the Action represents has a parameter, you must use Action&amp;lt;T&amp;gt; where T is the parameter’s type. There are also additional Action implementations with more than one parameters, but RelayCommand can only have 0 or 1 parameter. &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;The code to create a RelayCommand is:&lt;/p&gt;  &lt;pre class="csharp" name="code"&gt;public RelayCommand MyCommand
{
    get;
    private set;
}

public MainViewModel()
{
    MyCommand = new RelayCommand(
        () =&amp;gt; DoSomething());
}&lt;/pre&gt;

&lt;h6&gt;&lt;/h6&gt;

&lt;p&gt;&lt;em&gt;Note: The syntax () =&amp;gt; DoSomething() is called a &lt;a href="http://msdn.microsoft.com/en-us/library/bb397687.aspx" target="_blank"&gt;lambda expression&lt;/a&gt;, and is the shortest way to define and pass an Action to an object. In the sample here, the method DoSomething will be called without any parameter when the Command is executed.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;CanExecute and CanExecuteChanged&lt;/h2&gt;

&lt;p&gt;Apart from the Execute method that the ICommand interface specifies, there is an additional method and an event that every ICommand (including, of course, RelayCommand) must offer.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.canexecute.aspx" target="_blank"&gt;CanExecute&lt;/a&gt;&lt;/strong&gt;: This method should return true if the command can be executed. When the Command is used on a control, the control will be disabled automatically when CanExecute returns false. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.canexecutechanged.aspx" target="_blank"&gt;CanExecuteChanged&lt;/a&gt;&lt;/strong&gt;: This event should be raised when the CanExecute method must be “requeried” (when the value of CanExecute might have changed, and should be re-evaluated). &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The CanExecute method can be passed to the RelayCommand constructor as a &lt;a href="http://msdn.microsoft.com/en-us/library/bb534960.aspx" target="_blank"&gt;Func&amp;lt;bool&amp;gt;&lt;/a&gt; (or a &lt;a href="http://msdn.microsoft.com/en-us/library/bb549151.aspx" target="_blank"&gt;Func&amp;lt;T, bool&amp;gt;&lt;/a&gt; if the command has a parameter).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: A Func is exactly like an Action, except that it has a return type. In the case of RelayCommands, the return type is bool: True if the command can be executed, false otherwise.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To create a command with an Execute and a CanExecute methods, you can do:&lt;/p&gt;

&lt;pre class="csharp" name="code"&gt;public RelayCommand MyCommand
{
    get;
    private set;
}

public MainViewModel()
{
    MyCommand = new RelayCommand(
        () =&amp;gt; DoSomething(),
        () =&amp;gt; return MyValue);
}&lt;/pre&gt;

&lt;p&gt;In the code above, if MyValue is true, the command can be executed; if it is false, the command cannot be executed (and controls using that command are disabled). This can depend on multiple parameters such as the state of the application, the time of the day, the weather outside, etc.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: When using lambda expressions, if the expression is just “return something”, the “return” keyword can be omitted. So the code becomes:&lt;/em&gt;&lt;/p&gt;

&lt;pre class="csharp" name="code"&gt;public RelayCommand MyCommand
{
    get;
    private set;
}

public MainViewModel()
{
    MyCommand = new RelayCommand(
        () =&amp;gt; DoSomething(),
        () =&amp;gt; MyValue);
}&lt;/pre&gt;

&lt;h2&gt;The CommandManager&lt;/h2&gt;

&lt;p&gt;RelayCommands are available for WPF and Silverlight. However, one piece is missing in Silverlight: Windows Presentation Foundation has a class that is watching your UI, and that polls the commands’ state when something happens (for example when the user clicks a button, checks a checkbox, open a menu, etc…). This class is called the &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.commandmanager.aspx" target="_blank"&gt;CommandManager&lt;/a&gt;&lt;/strong&gt; and it doesn’t exist in Silverlight. Not at all. Nada.&lt;/p&gt;

&lt;p&gt;So when a user actions the UI in WPF, this triggers the CommandManager to &lt;em&gt;requery&lt;/em&gt; all the commands. In Silverlight you have to do the work yourself. This is why the RelayCommand class has a method called &lt;strong&gt;RaiseCanExecuteChanged&lt;/strong&gt;. This method forces the control that uses the command to check again if the command may be executed or not. And if the command may not be executed, the control is disabled.&lt;/p&gt;

&lt;h2&gt;In WPF&lt;/h2&gt;

&lt;p&gt;Strictly speaking, in WPF, and if your command is bound to a control that is watched by the CommandManager, you shouldn’t have to raise the CanExecuteChanged event yourself. You can let the CommandManager handle the situation. That said, external events might also change the state of the UI. Let’s imagine that the UI should be enabled from 9AM to 5PM, and then disabled for the night. The user is not triggering the UI, so the code should request (politely) that the CommandManager requeries the state of the commands. This is done by calling the method &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.commandmanager.invalidaterequerysuggested.aspx" target="_blank"&gt;InvalidateRequerySuggested&lt;/a&gt;&lt;/strong&gt; on the CommandManager. And as you guessed, the method RaiseCanExecuteChanged of the RelayCommand class does just that.&lt;/p&gt;

&lt;h2&gt;And in Silverlight&lt;/h2&gt;

&lt;p&gt;However, since Silverlight doesn’t have the CommandManager, a little more manual work is involved. When the state of your object changes in a way that affects the UI, you must RaiseCanExecuteChanged on the corresponding commands. In Silverlight, this will raise the CanExecuteChanged event, thus forcing the bound controls to call CanExecute. In WPF,  like we just saw, this will call InvalidateRequerySuggested on the CommandManager.&lt;/p&gt;

&lt;h2&gt;Show me the code&lt;/h2&gt;

&lt;p&gt;I created a small demo to illustrate this in Silverlight and in WPF, using the &lt;a href="http://www.galasoft.ch/mvvm/getstarted"&gt;MVVM Light Toolkit&lt;/a&gt;. Most of the code is shared between WPF and Silverlight. &lt;a href="http://galasoft.ch/mvvm/resources/Samples/RaiseCanExecuteChanged.zip"&gt;The source code for the application is available as usual&lt;/a&gt; (WPF 3.5 SP1 and Silverlight 3).&lt;/p&gt;

&lt;p&gt;The demo exposes one command, created in the MainViewModel class:&lt;/p&gt;

&lt;pre class="csharp" name="code"&gt;public RelayCommand IncreaseCounterCommand
{
    get;
    private set;
}

public MainViewModel()
{
    IncreaseCounterCommand = new RelayCommand(
        () =&amp;gt; Counter++,
        () =&amp;gt; CanIncrement);
}&lt;/pre&gt;

&lt;p&gt;The &lt;em&gt;Counter&lt;/em&gt; and &lt;em&gt;CanIncrement&lt;/em&gt; properties are raising the &lt;em&gt;PropertyChanged &lt;/em&gt;event when they are modified, thus data bindings that refer to these two properties will be updated whenever the properties are modified. What the code above means is: When the IncreaseCounterCommand is executed, check the CanIncrement property. If it is true, increment the Counter property.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
&lt;a title="2009092601 by lbugnionblog, on Flickr" href="http://www.flickr.com/photos/36917929@N06/3955642039/"&gt;&lt;img alt="2009092601" src="http://farm3.static.flickr.com/2427/3955642039_c37f9ac59d_o.png" width="640" height="238" /&gt;&lt;/a&gt; 

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Figure 1: WPF demo application, Enabled and Disabled&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;Disabling the button&lt;/h2&gt;

&lt;p&gt;We have a manual way to enable/disable the “increment” button: If you click on the “Enabled” text, it will turn into “Disabled”. This text (it’s a ToggleButton) is bound to the CanIncrement property directly. So in fact, when the text is “Disabled”, the CanIncrement property is set to false.&lt;/p&gt;

&lt;p&gt;Of course, we want the controls using this command to be automatically disabled/enabled when the CanIncrement property changed. In WPF, nothing needs to be done, because the CommandManager will automatically requery the state of the commands when the user clicks on the UI. In fact the state of the commands is requeried very, very often during the course of the application. Even just moving the mouse on the UI causes the CommandManager to requery the state of commands bound to visible UI element.&lt;/p&gt;

&lt;p&gt;In Silverlight however, no CommandManager, so we need to raise the CanExecuteChanged event on the command manually. Note that raising the CanExecuteChanged event can be useful in WPF too if you change the CanIncrement property in the code, for example through a timer. So, in fact, we will just call IncreaseCounterCommand.RaiseCanExecuteChanged() in Silverlight and in WPF too when CanIncrement changes:&lt;/p&gt;

&lt;pre class="csharp" name="code"&gt;public bool CanIncrement
{
    get
    {
        return _canIncrement;
    }

    set
    {
        if (_canIncrement == value)
        {
            return;
        }

        _canIncrement = value;

        // Update bindings, no broadcast
        RaisePropertyChanged(CanIncrementPropertyName);

        IncreaseCounterCommand.RaiseCanExecuteChanged();
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Just a warning: In V1 of the MVVM Light Toolkit, the method RaiseCanExecuteChanged was taking a boolean parameter. This boolean was actually not very useful, and has been removed in V2. Calling the old method still works in V2, but the parameter has no effect, and the method has been marked Obsolete. It will be removed in a future version of the toolkit.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This sample uses V2 beta of the MVVM Light Toolkit.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Silverlight/WPF Compatibility&lt;/h2&gt;

&lt;p&gt;Much of the code is shared between Silverlight and WPF in this small demo.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The ViewModel code is completely shared. The source code files are physically into the WPF project, and added as links into the Silverlight project. Implement once, compile twice. 
    &lt;br /&gt;&lt;em&gt;To add a source code file as a link, choose “Add existing item” in Visual Studio. Then, select a file. Instead of clicking on Add, click on the arrow on the right of the Add button, and select “Add as a link”.&lt;/em&gt; &lt;/li&gt;

  &lt;li&gt;The resources defining the look&amp;amp;feel of the application are placed into the file Skins\MainSkin.xaml. The code n this file is 100% the same in WPF and in Silverlight. To reuse the Silverlight control templates in WPF too, I use the &lt;a href="http://www.codeplex.com/wpf" target="_blank"&gt;WPF Toolkit’s&lt;/a&gt; implementation of the &lt;a href="http://windowsclient.net/wpf/wpf35/wpf-35sp1-toolkit-visual-state-manager-overview.aspx" target="_blank"&gt;Visual State Manager&lt;/a&gt;. &lt;/li&gt;

  &lt;li&gt;Finally, the XAML code in the main UI element (MainWindow.xaml in WPF, and Page.xaml in Silverlight) is almost the same, except for one little difference: Since Silverlight doesn’t support commands out of the box, we rely on an &lt;em&gt;attached behaviour&lt;/em&gt; to bind the RelayCommand to the Button: &lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="xml" name="code"&gt;&amp;lt;Button cmd:ButtonBaseExtensions.Command="{Binding IncreaseCounterCommand}"
        Grid.Row="2"
        Style="{StaticResource IncrementButtonStyle}"
        Content="Increment" /&amp;gt;&lt;/pre&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Commands in WPF are quite a complex topic, and I must admit that I didn’t completely understand them before I discovered the RelayCommand class. I totally fell in love with this fantastic helper. Josh Smith has been fantastic in allowing me to re-use his code in the MVVM Light Toolkit. I hope that this article will help you understand the power and convenience of RelayCommands. Happy coding!&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="margin-bottom: -1em"&gt;
  &lt;div style="vertical-align: middle"&gt;&lt;a href="http://www.galasoft.ch/"&gt;&lt;img title="GalaSoft Laurent Bugnion" alt="GalaSoft Laurent Bugnion" src="http://www.galasoft.ch/logo/Current/logo_120x30.png" /&gt;&lt;/a&gt; &lt;/div&gt;

  &lt;div style="position: relative; top: -36px; left: 130px"&gt;&lt;strong&gt;&lt;a href="http://www.galasoft.ch/contact_en.html"&gt;Laurent Bugnion (GalaSoft)&lt;/a&gt;&lt;/strong&gt; 

    &lt;br /&gt;&lt;a href="http://feeds.feedburner.com/galasoft"&gt;Subscribe&lt;/a&gt; | &lt;a href="http://twitter.com/lbugnion"&gt;Twitter&lt;/a&gt; | &lt;a href="http://www.facebook.com/lbugnion"&gt;Facebook&lt;/a&gt;| &lt;a href="http://www.flickr.com/photos/lbugnion"&gt;Flickr&lt;/a&gt; | &lt;a href="http://www.linkedin.com/in/lbugnion"&gt;LinkedIn&lt;/a&gt; &lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135111"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=135111" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/lbugnion/aggbug/135111.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Laurent Bugnion</dc:creator>
            <guid>http://geekswithblogs.net/lbugnion/archive/2009/09/26/using-relaycommands-in-silverlight-and-wpf.aspx</guid>
            <pubDate>Sat, 26 Sep 2009 19:15:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/lbugnion/comments/135111.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/lbugnion/archive/2009/09/26/using-relaycommands-in-silverlight-and-wpf.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/lbugnion/comments/commentRss/135111.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/lbugnion/services/trackbacks/135111.aspx</trackback:ping>
        </item>
        <item>
            <title>New articles about the MVVM Light Toolkit V1.1.1</title>
            <link>http://geekswithblogs.net/lbugnion/archive/2009/09/09/new-articles-about-the-mvvm-light-toolkit-v1.1.1.aspx</link>
            <description>&lt;p&gt;To help you get started with the MVVM Light Toolkit V1.1.1, I published two new articles:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.galasoft.ch/mvvm/creating/"&gt;Creating a new MVVM Light application in Visual Studio&lt;/a&gt;      &lt;br /&gt;This article will show you how to use Visual Studio to create a brand new MVVM Light application in Windows Presentation Foundation and in Silverlight.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.galasoft.ch/mvvm/sample1/"&gt;Understanding the MVVM Light application sample&lt;/a&gt;      &lt;br /&gt;When you create a new MVVM Light application, the application can be run and serves as a sample. This post helps you to understand the various components and layers in the MVVM Light application, and how they interact together.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Of course, before you read these two articles, you should probably check the &lt;a href="http://www.galasoft.ch/mvvm/getstarted"&gt;Get Started page&lt;/a&gt; and &lt;a href="http://www.galasoft.ch/mvvm/installing"&gt;the Installation instructions&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Happy coding!&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=134589"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=134589" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/lbugnion/aggbug/134589.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Laurent Bugnion</dc:creator>
            <guid>http://geekswithblogs.net/lbugnion/archive/2009/09/09/new-articles-about-the-mvvm-light-toolkit-v1.1.1.aspx</guid>
            <pubDate>Wed, 09 Sep 2009 21:38:18 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/lbugnion/comments/134589.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/lbugnion/archive/2009/09/09/new-articles-about-the-mvvm-light-toolkit-v1.1.1.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/lbugnion/comments/commentRss/134589.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/lbugnion/services/trackbacks/134589.aspx</trackback:ping>
        </item>
    </channel>
</rss>