<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>.NET &amp; Funky Fresh : Caliburn, WP7</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/WP7/default.aspx</link><description>Tags: Caliburn, WP7</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Durandal 1.2.0 and Caliburn.Micro 1.5.0 Released!</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2013/03/18/durandal-1-2-0-and-caliburn-micro-1-5-0-released.aspx</link><pubDate>Tue, 19 Mar 2013 00:10:59 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:102953</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=102953</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2013/03/18/durandal-1-2-0-and-caliburn-micro-1-5-0-released.aspx#comments</comments><description>&lt;p&gt;Two awesome releases in the last week! Much thanks to the great community surrounding both projects! Here’s what’s new:&lt;/p&gt;  &lt;h3&gt;Durandal 1.2.0&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;Tons of bug fixes.&lt;/li&gt;    &lt;li&gt;Lots of improvements to the router.&lt;/li&gt;    &lt;li&gt;Better support for integrating with Q, KendoUI and Dojo.&lt;/li&gt;    &lt;li&gt;More docs.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="https://github.com/BlueSpire/Durandal/blob/master/Changes.txt" target="_blank"&gt;Check out the full set of changes.&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Caliburn.Micro. 1.5.0&lt;/h3&gt;  &lt;p&gt;Nigel Sampson and Thomas Ibel are going to town these days! Some really cool stuff happening in this release. Here’s a few things:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Task and Async support (on all platforms except SL4 and WP71)&lt;/li&gt;    &lt;li&gt;Task/Coroutine integration.&lt;/li&gt;    &lt;li&gt;Actions can return tasks.&lt;/li&gt;    &lt;li&gt;More async stuff in general.&lt;/li&gt;    &lt;li&gt;Support for the WinRT Share Charm&lt;/li&gt;    &lt;li&gt;Support for the WinRT Settings Charm&lt;/li&gt;    &lt;li&gt;Various bug fixes and minor improvements throughout.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You can get the latest versions of both of these frameworks on Nuget.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=102953" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NuGet/default.aspx">NuGet</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Durandal/default.aspx">Durandal</category></item><item><title>Caliburn.Micro v1.4.1 Released</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2013/01/20/caliburn-micro-v1-4-1-released.aspx</link><pubDate>Sun, 20 Jan 2013 19:43:06 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:71424</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>20</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=71424</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2013/01/20/caliburn-micro-v1-4-1-released.aspx#comments</comments><description>&lt;p&gt;I’m labeling this the&amp;#160; Thomas Ibel/Nigel Sampson release. Why? Because these two hardworking gentlemen have put great effort into bringing you the most mature version of Caliburn.Micro yet. In the two months since our 1.4 release they’ve dealt with almost every outstanding issue on our list. Great work guys! In addition to bug fixes, there’s been some minor enhancements, we’ve synced up the latest WUI library and added official support for WPF 4.5. You can get it on Nuget now. Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=71424" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category></item><item><title>Bring on the AWESOME!!! Caliburn.Micro v1.4 Released</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2012/11/15/bring-on-the-awesome-caliburn-micro-v1-4-released.aspx</link><pubDate>Fri, 16 Nov 2012 03:28:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:70470</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>16</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=70470</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2012/11/15/bring-on-the-awesome-caliburn-micro-v1-4-released.aspx#comments</comments><description>&lt;p&gt;Today I&amp;rsquo;m happy to announce the official release of Caliburn.Micro v1.4. This release brings a ton of bug fixes across all platforms, nuget fixes&amp;hellip;and best of all&amp;hellip;full support for WinRT and WP8. That means that Caliburn.Micro now supports WPF, SL4, SL5, WP7, WP8 and WinRT. AWESOME!!! You can get it on &lt;a href="http://www.nuget.org/packages/Caliburn.Micro" target="_blank"&gt;nuget.org&lt;/a&gt; or download the binaries directly from &lt;a href="http://caliburnmicro.codeplex.com/releases/view/97813" target="_blank"&gt;codeplex&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;How did this happen you say? Well, not without generous help from the community who believed in this project and put in the hours to make it happen. Here&amp;rsquo;s a few people I&amp;rsquo;d like to mention:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.nuget.org/packages?q=%20Marco%20Amendola"&gt;Marco Amendola&lt;/a&gt; &amp;ndash; A Caliburn veteran. Always working hard on bugs, features and community support.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.nuget.org/packages?q=%20Chin%20Bae"&gt;Chin Bae&lt;/a&gt; &amp;ndash; Master of our view location strategy. &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.nuget.org/packages?q=%20Nigel%20Sampson"&gt;Nigel Sampson&lt;/a&gt; &amp;ndash; Monster WinRT port guru. He practically ported the entire thing himself. REALLY.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.nuget.org/packages?q=%20Thomas%20Ibel"&gt;Thomas Ibel&lt;/a&gt; &amp;ndash; Tons and tons of bug fixes and stability improvements.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.nuget.org/packages?q=%20Matt%20Hidinger"&gt;Matt Hidinger&lt;/a&gt; &amp;ndash; Did all the grunt work to get official WP8 support into this release.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;rsquo;d also like to thank all the community members who tested out this version, submitted feedback..and of course&amp;hellip;thanks to everyone who submitted pull requests. It was a tremendous help!&lt;/p&gt;
&lt;p&gt;Finally, I&amp;rsquo;d like to extend a special thank you to Scott Hanselman, Scott Hunter and the whole .NET team for supporting open source software and providing the necessary licenses I needed to actually build and release this version. It would not have been possible without their kindness and generosity.&lt;/p&gt;
&lt;p&gt;For reference, here&amp;rsquo;s the &lt;a href="http://www.nuget.org/profiles/eisenbergeffect" target="_blank"&gt;full list of nuget packages&lt;/a&gt; and their descriptions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Caliburn.Micro &amp;ndash; The full framework compiled into an assembly.&lt;/li&gt;
&lt;li&gt;Caliburn.Micro.Start - Includes Caliburn.Micro plus a starting bootstrapper, view model and view.&lt;/li&gt;
&lt;li&gt;Caliburn.Micro.Container &amp;ndash; The Caliburn.Micro inversion of control container (IoC); source code drop-in.&lt;/li&gt;
&lt;li&gt;Caliburn.Micro.EventAggregator &amp;ndash; The Caliburn.Micro event aggregator; source code drop-in.&lt;/li&gt;
&lt;li&gt;Caliburn.Micro.INPC &amp;ndash; The Caliburn.Micro INPC infrastructure: PropertyChangedBase, BindableCollection, Execute.OnUIThread and InDesignMode checking; source code drop-in.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; We have removed the starting bootstrapper, view and view model template code from the core package and added a new package, Caliburn.Micro.Start, which now has the core plus the startup files.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Go forth and build Xaml awesomeness! And stay tuned for an update on &lt;a href="https://github.com/EisenbergEffect/Durandal" target="_blank"&gt;Durandal&lt;/a&gt; in the next few weeks too ;)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;span&gt;This community project is sponsored by&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.xceedsoft.com/redirect/ad/index.aspx?adtype=143"&gt;Xceed&lt;/a&gt;&lt;span&gt;, makers of&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.xceedsoft.com/redirect/ad/index.aspx?adtype=141"&gt;Xceed DataGrid for WPF&lt;/a&gt;&lt;span&gt;, the enterprise datagrid that provides a rich, fluid, and high performance user experience. 50% off any Xceed product with coupon code G00B8T. Xceed also offers&amp;nbsp;&lt;/span&gt;&lt;a href="http://extendedsilverlight.codeplex.com/"&gt;Extended Silverlight Toolkit&lt;/a&gt;&lt;span&gt;&amp;nbsp;and&amp;nbsp;&lt;/span&gt;&lt;a href="http://wpftoolkit.codeplex.com/"&gt;Extended WPF Toolkit&lt;/a&gt;&lt;span&gt;&amp;nbsp;here on Codeplex.&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=70470" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NuGet/default.aspx">NuGet</category></item><item><title>Today….All Your Wildest Dreams Come True</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2012/08/02/today-all-your-wildest-dreams-come-true.aspx</link><pubDate>Thu, 02 Aug 2012 20:07:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:70251</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>20</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=70251</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2012/08/02/today-all-your-wildest-dreams-come-true.aspx#comments</comments><description>&lt;p&gt;If you fit into any one (or more) of these three categories&amp;hellip;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You like tabletop RPGs&lt;/li&gt;
&lt;li&gt;You build Xaml applications&lt;/li&gt;
&lt;li&gt;You build Html/JS applications&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;1. RPGWithMe&lt;/h2&gt;
&lt;p&gt;For some time I&amp;rsquo;ve been cranking away building my company&amp;rsquo;s first real product. I&amp;rsquo;m very excited to officially announce to you today that &lt;a target="_blank" href="http://www.rpgwithme.com/"&gt;RPGWithMe&lt;/a&gt; is live!&amp;nbsp; &lt;a target="_blank" href="http://www.rpgwithme.com/"&gt;RPGWithMe&lt;/a&gt; is a web-based platform centered around tabletop RPGs. If you play these games&amp;hellip;you are going to like this a lot. RPGWithMe provides four main feature areas in its initial launch:&lt;/p&gt;
&lt;h3&gt;Character Sheets&lt;/h3&gt;
&lt;p&gt;The industry&amp;rsquo;s most beautiful character sheets, fully interactive and free: Use them at the gametable on your tablet or laptop. They&amp;rsquo;re also fully integrated into our play-by-post and virtual tabletop experience. It&amp;#39;s as simple as uploading DDI or Hero Lab &lt;sup&gt;&amp;reg;&lt;/sup&gt; files. Custom character creation is coming soon&amp;hellip;&lt;/p&gt;
&lt;h3&gt;Campaign Management&lt;/h3&gt;
&lt;p&gt;We provide gorgeous home pages for your campaigns. Use our live-previewing editor to write wiki articles and pin them to your home page. Chronicle your adventure and automatically have your content indexed for later. Plus, access our enormous, high quality art library for use in your wiki or upload your own art.&lt;/p&gt;
&lt;h3&gt;Play-by-Post&lt;/h3&gt;
&lt;p&gt;We&amp;rsquo;ve built our system from the ground up to support PbP. It fully integrates your player&amp;rsquo;s character sheets and your campaign wiki. It snapshots roll, magic, power and feat data and provides multiple views over your campaign&amp;rsquo;s activity feed with the ability to bookmark and integrate your character&amp;rsquo;s journals too.&lt;/p&gt;
&lt;h3&gt;Virtual Tabletop&lt;/h3&gt;
&lt;p&gt;Build maps, play out combat and track NPC stats. Our virtual table can be used to enhance PbP beyond anything you&amp;rsquo;ve seen. Of course, you can always use it as a realtime virtual table on it&amp;#39;s own and feel the power of integrated character sheets, rich activity feeds and campaign management.&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:cab0da76-f4b8-44a2-a32b-bb0f199d7ae0" style="padding-bottom:0px;margin:0px auto;padding-left:0px;width:448px;padding-right:0px;display:block;float:none;padding-top:15px;"&gt;
&lt;div&gt;&lt;a target="_new" href="http://www.youtube.com/watch?v=ikKPz-zqe5U&amp;amp;feature=plcp"&gt;&lt;img style="border-style:none;" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/videoe28113b8579a_5F00_5DA2CAC7.jpg" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="width:448px;clear:both;font-size:.8em;"&gt;RPGWithMe Teaser&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;2. Caliburn.Micro WinRT&lt;/h2&gt;
&lt;p&gt;Thanks to the fantastic work of &lt;a target="_blank" href="http://compiledexperience.com/"&gt;Nigel Sampson&lt;/a&gt; and &lt;a target="_blank" href="http://www.markermetro.com/2012/08/technical/caliburn-micro-for-winrt-mvvm-magic-pixie-dust-for-everyone/"&gt;Keith Patton&lt;/a&gt; we now have support for &lt;a target="_blank" href="http://caliburnmicro.codeplex.com/SourceControl/list/changesets"&gt;the full Caliburn.Micro feature set on WinRT&lt;/a&gt;. This is he initial port&amp;hellip;and its not an official release yet, so there&amp;rsquo;s bound to be bugs. But if you want to use CM to build your WinRT app, please start using this code and help us iron out the kinks&amp;hellip;.and naturally start enjoying the CM way of building apps on WinRT.&lt;/p&gt;
&lt;h2&gt;3. Durandal&lt;/h2&gt;
&lt;p&gt;Durandal is the essence of Caliburn.Micro re-imagined for HTML and Javascript. A very early version of the code is now &lt;a target="_blank" href="https://github.com/EisenbergEffect/Durandal"&gt;available on github&lt;/a&gt;. It is a very small amount of code built on top of three existing and established Javascript libraries: &lt;a target="_blank" href="http://jquery.com/"&gt;jQuery&lt;/a&gt;, &lt;a target="_blank" href="http://knockoutjs.com/"&gt;Knockout&lt;/a&gt; and &lt;a target="_blank" href="http://requirejs.org/"&gt;Require&lt;/a&gt;. Features include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fully modularize your html and js the same way you would when building Caliburn.Micro applications. ie. Shell.js automatically locates Shell.html, binds and gets composed into the dom. Naturally you can change the conventions&amp;hellip;&lt;/li&gt;
&lt;li&gt;Leverage promises everywhere as the API uses no callbacks, but has CommonJS promises plumbed throughout&lt;/li&gt;
&lt;li&gt;Experience the first html/js framework where &lt;strong&gt;Composition&lt;/strong&gt; is embraced at the very core. The view/view-model composition features of Durandal are even more powerful than Caliburn.Micro.&lt;/li&gt;
&lt;li&gt;A simple app model provides you with an app start lifecycle, modal dialogs, message boxes and an event aggregator.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a pre-pre-pre-alpha version. There are no docs and just one sample at the moment. But, I wanted to get it out there so you could dig into the code, start playing with it and give me feedback. Of course I&amp;rsquo;ll add docs, more samples, tests, etc. Just in case you are wondering though, Durandal is already being used in production as the framework for RPGWithMe&amp;rsquo;s virtual tabletop. Various versions/pieces of it are being used by some of my clients&amp;hellip;details not available right now, but I hope to share more later.&lt;/p&gt;
&lt;p&gt;Things I would like to do with Durandal in the future:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Remove the Knockout dependency. I don&amp;rsquo;t like how knockout bindings work in html and I don&amp;rsquo;t like how observables invade your model code. Both are ugly, tedious and obscure the readability of the code.&amp;nbsp; I have a plan to fix both of these, but it&amp;rsquo;s non-trivial. I chose to put together this initial version based on knockout since it was already in heavy use and it was quick and easy. In the future I hope we can improve on that.&lt;/li&gt;
&lt;li&gt;Remove the jQuery dependency. Durandal only uses a few features of jQuery. So, eventually, I&amp;rsquo;d like to have an alternate solution without an external dependency. You can always use jQuery if you want to, but in the long term, I don&amp;rsquo;t want to force it on developers.&lt;/li&gt;
&lt;li&gt;Create a component model for building reusable controls. This should work similar to Xaml in that controls should have a distinct view written in html which can be replaced globally or on a per use basis. Controls should also support templated parts with the same characteristics.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ok. That&amp;rsquo;s enough news for today. Enjoy. Now&amp;hellip;I&amp;rsquo;m going to rest for a bit.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=70251" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/game+development/default.aspx">game development</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Control+Templates/default.aspx">Control Templates</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category></item><item><title>The Manifold Blunders of Xaml–Part 1: Version and Platform Hell</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2012/04/18/the-manifold-blunders-of-xaml-part-1-version-and-platform-hell.aspx</link><pubDate>Wed, 18 Apr 2012 15:43:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:69682</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>27</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=69682</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2012/04/18/the-manifold-blunders-of-xaml-part-1-version-and-platform-hell.aspx#comments</comments><description>&lt;p&gt;I started work with &amp;ldquo;Xaml-based&amp;rdquo; platforms in the pre-Beta days of WPF, so I&amp;rsquo;ve been working with this technology longer than most. Back then I was utterly awed and inspired by it&amp;rsquo;s capabilities. Today I&amp;rsquo;m frustrated and sometimes outraged. As I&amp;rsquo;ve traveled to various conferences, worked with various companies and interacted with the many &lt;a href="http://caliburnmicro.codeplex.com/discussions" target="_blank"&gt;Caliburn.Micro&lt;/a&gt; users, I&amp;rsquo;ve discovered that I&amp;rsquo;m not the only one who feels this way. This blog series attempts to catalog a number of the issues, some of which have been there from the very beginning; others creeping in over time. This is an aggregate of my own observations and those of the community.&lt;/p&gt;
&lt;h2&gt;Versions &lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s take a brief stroll through the platform timeline:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2006 &amp;ndash; WPF 3.0 &lt;/li&gt;
&lt;li&gt;2007 &amp;ndash; Silverlight 1 &lt;/li&gt;
&lt;li&gt;2007&amp;ndash; WPF 3.5 &lt;/li&gt;
&lt;li&gt;2008 &amp;ndash; Silverlight 2 &lt;/li&gt;
&lt;li&gt;2008 &amp;ndash; WPF3.5 sp1 &lt;/li&gt;
&lt;li&gt;2009 &amp;ndash; Silverlight 3 &lt;/li&gt;
&lt;li&gt;2010 - Silverlight 4 &lt;/li&gt;
&lt;li&gt;2010 &amp;ndash; WP7 &lt;/li&gt;
&lt;li&gt;2010 &amp;ndash; WPF4.0 &lt;/li&gt;
&lt;li&gt;2011 &amp;ndash; Silverlight 5 &lt;/li&gt;
&lt;li&gt;2011 &amp;ndash; WP7 Mango &lt;/li&gt;
&lt;li&gt;2011 &amp;ndash; Lakeshore&lt;sup&gt;1&lt;/sup&gt; &lt;/li&gt;
&lt;li&gt;2012 &amp;ndash; WinRT/Metro&lt;sup&gt;2&lt;/sup&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If we focus on the platforms and ignore their various versions, we have something like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2006 &amp;ndash; WPF &lt;/li&gt;
&lt;li&gt;2007 Silverlight 1.0 (no CLR) &lt;/li&gt;
&lt;li&gt;2008 &amp;ndash; Silverlight 2.0 (CLR) &lt;/li&gt;
&lt;li&gt;2010 &amp;ndash; WP7 &lt;/li&gt;
&lt;li&gt;2011 &amp;ndash; Lakeshore &lt;/li&gt;
&lt;li&gt;2012 &amp;ndash; WinRT/Metro &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, it appears that Microsoft has released a new UI platform at least every two years! Let&amp;rsquo;s contrast that to the timeline for pre-Xaml UI technologies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1985?&amp;ndash; Win16 &lt;/li&gt;
&lt;li&gt;1995 &amp;ndash; Win32 &lt;/li&gt;
&lt;li&gt;2001 &amp;ndash; WinForms &lt;/li&gt;
&lt;li&gt;2006 &amp;ndash; WPF &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Interesting. We have at least 5 &amp;ndash; 6 years between platforms prior to Xaml, but it&amp;rsquo;s actually about 10yrs due to the fact that WinForms is just making Win32 available to managed languages. It&amp;rsquo;s just a wrapper around existing APIs. Each of the Xaml platforms is actually a different runtime altogether. So as far as platforms go, we&amp;rsquo;ve gone from one every 10yrs to one every 2 years. But that&amp;rsquo;s not all, let&amp;rsquo;s look at Xaml itself:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2006 &amp;ndash; Xaml 2006 Spec &lt;/li&gt;
&lt;li&gt;2008 &amp;ndash; Silverlight 1 Xaml &lt;/li&gt;
&lt;li&gt;2009 &amp;ndash; Xaml 2009 Spec &lt;/li&gt;
&lt;li&gt;2011 &amp;ndash; Silverlight 5 Xaml &lt;/li&gt;
&lt;li&gt;2012 &amp;ndash; WinRT/Metro Xaml &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Aside from the actual platforms released, we have a parallel divergence in Xaml markup capabilities. In 2006 the first version of Xaml was released. It was &lt;a href="http://msdn.microsoft.com/en-us/library/dd361852(v=prot.10).aspx" target="_blank"&gt;formally defined and released as a spec&lt;/a&gt; shortly after. When Silverlight came along, Microsoft failed to create a Xaml language compatible with their own specification. In fact, even Silverlight 5 doesn&amp;rsquo;t comply with the Xaml 2006 spec. In 2009 Microsoft released a new version of Xaml that fixed several important shortcomings with the 2006 spec&amp;hellip;.but not a single platform implemented it. WP7 is still playing catch-up with Silverlight and WPF. WinRT/Metro Xaml has less Xaml features than any platform. Furthermore, it significantly changes some aspects of Xaml altogether, making it compatible with almost nothing. Furthermore, some of the changes they are making will prevent it from ever becoming compatible in the future.&lt;/p&gt;
&lt;p&gt;When I step back and try to look at this information objectively, the most natural conclusion I can come to is that Microsoft UI technologies are, and have been for the last five years, in a state of complete &lt;em&gt;&lt;strong&gt;instability&lt;/strong&gt;&lt;/em&gt;&amp;hellip;and it doesn&amp;rsquo;t show any signs of change (esp. with the rumors that WP8 will not use Silverlight, but some &lt;em&gt;variant&lt;/em&gt; of WinRT). You can&amp;rsquo;t count on anything. If we forget about app developers for a moment, and think about the ecosystem, imagine the effect this has on third party products, control vendors, open source frameworks and tooling. Every time MS spits out a new platform or Xaml flavor, the entire ecosystem has to start over. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;My own Experience&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I first wrote Caliburn for WPF when there was no word on anything like Silverlight existing. When Silverlight was first announced, it was branded WPF/e so I thought my framework would port. Unfortunately, when SL2 was made available, there were so many differences that I had no choice but to completely re-write Caliburn. Then, when WP7 was announced, I started porting Caliburn to that, only to discover that it was &lt;em&gt;not possible&lt;/em&gt;. So, I did another complete re-write resulting in Caliburn.Micro. Now we have WinRT/Metro. I &lt;em&gt;think&lt;/em&gt; I can port it, albeit, with a ton of conditional code. But, I&amp;rsquo;m not 100% sure yet. If it looks like another re-write&amp;hellip;I&amp;rsquo;m done with this game.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maintenance and Innovation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There are lots of negative side-effects to this sort of instability. The one that hits me most is that it creates a battle between maintenance and innovation. Again, speaking of my own project, I have plenty of ideas about how to improve Caliburn.Micro. I think some of them are minor niceties, but others are more along the innovative lines. But, you will never see any of them come to fruition. Why? Because the instability of the underlying platform, the constant release of new platforms&amp;hellip;has put my project into a state of &lt;em&gt;&lt;strong&gt;perpetual maintenance&lt;/strong&gt;&lt;/em&gt;. I can&amp;rsquo;t innovate because I&amp;rsquo;m still trying to deal with the differences in WP7.5 and I&amp;rsquo;ve got developers (who can blame them?) banging down my door wanting to know when WinRT/Metro version will be available. It&amp;rsquo;s been discussed much in recent years as to why innovation seams to happen in non-Microsoft open source and on other platforms like Mac&amp;hellip;while very little happens in Windows software. Could it be because we are spending our time re-writing everything every two years? and don&amp;rsquo;t have time to develop anything forward thinking?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Careless and Arbitrary&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Sadly, many of the API and Xaml differences were completely avoidable. I remember one particular bug I had in Caliburn. It resulted from the fact that List&amp;lt;T&amp;gt;.Remove was implemented differently between WPF and Silverlight. In a particular scenario it would work fine on one platform and crash your app on another. There are hundreds, probably thousands of such issues, from the BCL all the way up through the UI stack.&amp;nbsp; We aren&amp;rsquo;t talking about missing features here. We are talking about the same features which exhibit different behavior or have altered APIs.&amp;nbsp; Sure, Microsoft worked hard to improve this with successive releases of Silverlight. But then came WP7, which stepped us back in time. Now look at WinRT. There are a number of changes that are completely arbitrary. They serve no technical purpose and don&amp;rsquo;t improve the API. They just make more work for developers who want to port code. If you want another fine example, just try to write a cross-framework design mode check.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A Lack of Understanding&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Sigh. This one perfectly ironic issue really troubles me sometimes. Through all of this, I&amp;rsquo;ve realized that Microsoft doesn&amp;rsquo;t understand their own platform. I&amp;rsquo;ve got more to say on this later, but let&amp;rsquo;s look at this from an API perspective here. Consider this: every control specific to WP7 development could have been built on top of Silverlight without a need for a modified runtime. Most controls could have been implemented simply by styling an existing control or applying a template. For example, the Pivot control can be implemented using a tab control with a custom template and some attached behaviors. In fact, wouldn&amp;rsquo;t it have been cool if you could just use a Tab control in WP7 and it just changed it&amp;rsquo;s appearance to work on the phone?! Wait, wasn&amp;rsquo;t that the idea behind templating and adaptive layout to begin with? Here&amp;rsquo;s another example: Behaviors. Perhaps you didn&amp;rsquo;t know that Microsoft built this twice? In WPF there were Triggers. In fact, in both WPF and the Blend behavior system, there is a class called TriggerBase. They have the same name! They do the same thing! But, you can&amp;rsquo;t create custom triggers or actions in WPF because the ctor is marked internal. Did it not occur to anyone that they should just remove that instead of re-inventing the wheel? As a result, we now have two methods of doing triggers, and you have to know which to use for what. It&amp;rsquo;s even true in Silverlight, which has limited support for &amp;ldquo;traditional&amp;rdquo; triggers, but does have some. Ridiculous. I could go on and on about the types of internal and cross-platform inconsistencies MS has created by not simply understanding the core capabilities of their own framework.&lt;/p&gt;
&lt;p&gt;All of this get&amp;rsquo;s really interesting if you consider that Mac is the platform that is considered most cutting edge and innovative in terms of UX&amp;hellip;and they&amp;rsquo;ve scarcely had any major breaking changes since 2002. Considering that their phone apps run on their tablet and they are porting a number iOS features back to OSX&amp;hellip;it must be nice only having to worry about two platforms and knowing that the OS vendor is making a visible, tangible effort to unify those two platforms&amp;hellip;..but I&amp;rsquo;m getting off topic now.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;End of Part One&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There are lots of problems with Xaml, but I chose to start this series with one of my particular pain points. Some developers neither care nor are affected (yet) by these sorts of version issues, but they have a big effect on the surrounding ecosystem and are going to be with us for the next decade. Over the next several blog posts, we&amp;rsquo;ll discuss many other problems, some technical, some not so much, but all have been singled out by multiple members of the community (read: not just me) as problems. It is my hope that Microsoft employees working on these technologies will read this and seriously consider what they can do to improve things going forward or at least not perpetuate the same mistakes again. I also hope that .NET developers will take a long, hard look at this part of the platform and make an honest valuation of its strengths and weaknesses.&lt;/p&gt;
&lt;h3&gt;Footnotes&lt;/h3&gt;
&lt;p&gt;1. Lakeshore is the name I&amp;rsquo;ve been hearing thrown around for the Xaml-runtime for XBox, which sources say is Silverlight-based, but drastically altered. I have no official word from Microsoft on this. It&amp;rsquo;s just what I heard through the grapevine, though I&amp;rsquo;m fairly confident in the accuracy of the information. Supposedly this is what is powering the &amp;ldquo;apps&amp;rdquo; in the new XBox dashboard which was released around last Thanksgiving. &amp;nbsp;EDIT: Apparently the XBox version is called Lakeview not Lakeshore.&lt;/p&gt;
&lt;p&gt;2. I don&amp;rsquo;t actually know when WinRT/Metro will be released. I imagine that 2012 is a reasonable guess.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=69682" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.0/default.aspx">.NET 3.0</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category></item><item><title>Boo-yah!!! Caliburn.Micro v1.3 RTW is Here</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2012/01/20/boo-yah-caliburn-micro-v1-3-rtw-is-here.aspx</link><pubDate>Sat, 21 Jan 2012 01:32:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:69352</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=69352</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2012/01/20/boo-yah-caliburn-micro-v1-3-rtw-is-here.aspx#comments</comments><description>&lt;p&gt;I&amp;rsquo;m extremely pleased to announce &lt;a target="_blank" href="http://caliburnmicro.codeplex.com/releases/view/80884"&gt;the release of Caliburn.Micro v1.3&lt;/a&gt;.&amp;nbsp; This is a great release with many bug fixes and several API improvements. We also support several new platforms. Here&amp;rsquo;s the highlights:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Support for WP7 Mango&lt;/li&gt;
&lt;li&gt;Support for Silverlight 5&lt;/li&gt;
&lt;li&gt;Basic MVVM Support for WinRT/Metro&lt;/li&gt;
&lt;li&gt;Awesome improvements to ViewModelLocator/ViewLocator which allow easier customization of conventions.&lt;/li&gt;
&lt;li&gt;Improved Design-Time Support for Conventions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks to the great community who provided awesome feedback during this release cycle. Thanks also to those who spent time to provide fixes and pull requests for bugs as well as for API improvements. I&amp;rsquo;d like to add a special thanks to Chin Bae for excellent work on making our ViewLocator and ViewModelLocator both more extensible and more accessible for common customizations.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re still just getting started. Enjoy &lt;a target="_blank" href="http://caliburnmicro.codeplex.com/releases/view/80884"&gt;the new bits&lt;/a&gt; and see what you can build!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=69352" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NuGet/default.aspx">NuGet</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVP/default.aspx">MVP</category></item><item><title>How I Lost, Regained and then Turned Down an MVP Award</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2012/01/04/how-i-lost-regained-and-then-turned-down-an-mvp-award.aspx</link><pubDate>Thu, 05 Jan 2012 01:46:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:68957</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>82</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=68957</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2012/01/04/how-i-lost-regained-and-then-turned-down-an-mvp-award.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;What Happened To Me&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d say that 2011 was a pretty good year for me as a .NET open source developer. After all, Caliburn.Micro had it&amp;rsquo;s first official release in April 2011 just in time for the Mix Open Source fest. At the festival, the framework had a great showing. I had tons of people literally coming up to me and dumping *all* their voting tokens into my bucket. In fact there were so many people constantly standing around my booth that my bucket didn&amp;rsquo;t even get collected for counting in the official vote. Thankfully someone standing around realized this and helped to remedy the situation. Needless to say, it was a successful event. Over the next several months I did two additional non-trivial releases and then began work on the v1.3 release. I also added support for Silverlight 5, WP7 Mango and preliminary support for WinRT/Metro. Furthermore, I began refactoring the entire framework so that it could be modularized into &amp;ldquo;feature&amp;rdquo; packages allowing a variety of different uses of the framework via Nuget. I even tested CM&amp;rsquo;s EventAggregator and IoC container to make sure they would run without issue on iOS and Android devices via Unity3d. In addition to the actual framework development, I wrote documentation, blogged, fixed dozens of bugs and added new features. I also participate daily in the Caliburn.Micro forums which currently have about 1k discussions. Caliburn.Micro is now used as the core enabling framework for thousands of applications across WPF, Silverlight and various versions of WP7. Depending on the day, Caliburn/Caliburn.Micro is the second or third most trafficked Xaml-related open source project in existence.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not trying to toot my own horn here. I&amp;rsquo;m just trying to set up a context. Considering the enormous amount of work in both creating the project and supporting the community&amp;hellip;you can imagine my surprise when I received the &amp;ldquo;form letter&amp;rdquo; stating that my MVP was not being renewed because I hadn&amp;rsquo;t accomplished enough in the last 12 months&amp;hellip;.and what I did do did not &amp;ldquo;stand out&amp;rdquo; in the community. Here&amp;rsquo;s the actual quote:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;The MVP Award is presented to individuals for their past year&amp;rsquo;s contributions to online and offline communities, which stand out from others in the communities that focus on Microsoft technologies. Your contributions were diligently evaluated over the past year against the contributions of others in the Silverlight community.&amp;nbsp; As a result of this evaluation, you were not awarded as a MicrosoftMVP for the January 2012 award cycle.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, I&amp;rsquo;m not really &amp;ldquo;attached&amp;rdquo; to being an MVP. I don&amp;rsquo;t attach a lot of self-worth or emotional satisfaction to it. It&amp;rsquo;s a nice thing to have though. So, I was really caught off guard by this and wondered how the MVP program could come to the conclusion that I hadn&amp;rsquo;t significantly contributed in the last year.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What I Did&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Being surprised as I was, and not being too fond of &amp;ldquo;generic&amp;rdquo; letters , I made one simple tweet:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Apparently Caliburn/Caliburn.Micro and my support of it is not a &amp;lsquo;good enough&amp;rsquo; contribution for Microsoft. I lost my MVP this year.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Community Response&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Immediately following this tweet, a storm of people responded with great affection for my work and general encouragement. I want to say thank you to everyone who responded so kindly. Paired with the encouragement was a general sense of befuddlement around how the MVP program could make such a conclusion. Apparently, I wasn&amp;rsquo;t the only surprised individual.&lt;/p&gt;
&lt;p&gt;I thought to myself &amp;ldquo;mistakes happen.&amp;rdquo; But as I was surveying the twitter-verse, I also learned that Jeremy Miller (StructureMap, FubuMVC, Storyteller) and Daniel Cazzulino (Moq) also lost their MVPs; two other prominent open source developers. Now I had had some problem during the re-evaluation process indicating my new MVP Lead clearly didn&amp;rsquo;t understand the nature of open source. When I was up for renewal, he asked me to fill out a rather ridiculous spreadsheet. If you could see it, you would notice something missing? There&amp;rsquo;s no category for Open Source!!! There&amp;rsquo;s not even a way to report it. I had this problem in previous years when I was asked to update my online MVP profile (a hideously painful UX by the way). The program uses that to evaluate you as well. Guess what? There&amp;rsquo;s no way to report Open Source work!!! Do you see a trend here? &lt;/p&gt;
&lt;p&gt;--Start Rant&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The thing that really disturbed me was that my MVP Lead didn&amp;rsquo;t know who I was or understand the nature of my contributions. What is it that an MVP Lead does anyways? I can&amp;rsquo;t tell. I get a useless mass email every week or so telling me things about Microsoft I don&amp;rsquo;t care about. Half of the time it isn&amp;rsquo;t even readable due to bad formatting, etc. My Lead never contacted me personally during the year. When I came up for renewal, I had to *defend* why I should have my award renewed using a bad Excel spreadsheet and a really bad online form which don&amp;rsquo;t even allow me to capture my real contributions. Shouldn&amp;rsquo;t it be an MVP Lead&amp;rsquo;s job to know his MVPs and what it is they are doing? Seriously. I sat down and calculated how much time it would take me to fill out the Excel form and the online form, plus writing a custom report for everything that wasn&amp;rsquo;t able to be captured via those broken mechanisms. I took that number of hours and multiplied it by my hourly consulting rate and determined that the money I would make working exceeded the material value of the MVP award. Haven&amp;rsquo;t I given enough free work to Microsoft? This isn&amp;rsquo;t a personal attack on *my* MVP Lead. I don&amp;rsquo;t know the guy. But, I wonder whether the role of MVP Lead is improperly defined or under-defined, because I know that I&amp;rsquo;m not the only person who has had this exact problem repeatedly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;--End Rant&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Microsoft Employees to the Rescue&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Also following my tweet, a number of Microsoft employees stepped in to investigate.&amp;nbsp; I have to thank them here personally. Much thanks to you (in no particular order) Tim Heuer, Pete Brown, Joe Healey, Glenn Block and Scott Hanselman. At one point I heard that this issue had even been escalated internally to Scott Guthrie. It&amp;rsquo;s truly an honor that so many well known and respected individuals *inside* Microsoft stepped up to personally investigate my situation. Thank you again. This is a tremendously good thing and points out something of great importance. Over the years I&amp;rsquo;ve very rarely had negative experiences with individual Microsoft employees. But, I&amp;rsquo;ve almost always had bad experiences interacting with groups, programs, etc. It seams that somehow the opinions of the individuals are lost in the system. That&amp;rsquo;s a real shame. &lt;/p&gt;
&lt;p&gt;If the opinion of many trusted Microsoft employees and the opinion of so many community members is not reflected in the MVP Award, then there certainly is a problem with the program&amp;hellip;or I don&amp;rsquo;t understand what the program is.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;An MVP Again&amp;hellip;for a few hours&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Thanks to the work of the gentlemen listed above, I was informed last night that I was being re-awarded an MVP for the 2012 year. I understand this sort of thing never happens. But, I&amp;rsquo;d already had several days to reflect on the MVP program and had several conversations with various people leading to several realizations listed above and several more detailed below. I was very unsettled.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why I Turned Down the MVP&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This morning I responded to the award email with a respectful &lt;em&gt;decline&lt;/em&gt;. Below are some of the reasons I chose to no longer be a part of the program and why I doubt I will participate again, unless serious reform happens.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Becoming an MVP&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One of the problems with the MVP program is that the whole thing is basically a mystery. Here&amp;rsquo;s where I first knock heads with the program. I value transparency and openness, even if it&amp;rsquo;s difficult or sometimes painful. The MVP program does not value openness. That&amp;rsquo;s why it&amp;rsquo;s basically a mystery how you get nominated for an MVP or what you have to do to get one. Let me do a little expos&amp;eacute; here. In my case, I&amp;rsquo;m fairly sure that my local Developer Evangelist saw the work I was doing in the local community and submitted me. That&amp;rsquo;s a good thing and it&amp;rsquo;s probably fairly common. But what happens from there? It&amp;rsquo;s my understanding that it&amp;rsquo;s completely out of DPE&amp;rsquo;s hands at that point. Who knows? From what I can tell, if the MVP program is interested in you, you then have to submit proof of your accomplishments to them. I remember doing this. It&amp;rsquo;s not like a normal award where the organization does the work to investigate your contributions and then decides whether or not to give you an award. No. If you are being considered for nomination, you literally have to *sell* yourself to the MVP program&amp;hellip;and selling is exactly what you are doing. Want to know why? Have you noticed that the MVP disciplines are strictly organized around internal product groups, regardless of how hindering to the particular MVP discipline it appears to be? An example of this is that Client AppDev, Silverlight, WP7 and Blend are all separate MVP groups even though they should be unified. Because they are different products, they are different MVPs (actually, they should all be the same product, but that&amp;rsquo;s a subject for another blog post). Do you know why this is? I&amp;rsquo;ll tell you: because each product group literally gets an MVP &amp;ldquo;budget&amp;rdquo; which they use to &amp;ldquo;purchase&amp;rdquo; MVPs for the year. Personally, I&amp;rsquo;m offended by this notion. But it would take drastic re-organization of the MVP program to fix it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;General Life as an MVP&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now you can just imagine how this division along product lines and MVP purchasing might affect things. Because Microsoft&amp;rsquo;s product teams are notorious for not only being non-communicative with one another but are often pitted against one another by the upper level management&amp;hellip;the various product teams can develop a vastly different set of values and beliefs with respect to interaction both internally and with the outside world. Depending on what MVP discipline you are a part of&amp;hellip;and the nature of your contributions&amp;hellip;you may have a great experience or you may be in store for hell. If the product group you are associated with is open, such as ASP.NET, you can expect lots of interaction, incorporation of your feedback into the product and probably a deep respect of open source work. If your product team is something like WP7, you can expect much less communication, very little change to the product based on your feedback and probably&amp;hellip;they don&amp;rsquo;t even know what open source is.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;My Life as an MVP&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As for myself, it&amp;rsquo;s clear that my major contribution is through an open source framework. What a fool I was&amp;hellip;there&amp;rsquo;s a certain insanity in building an open source framework on top of a proprietary UI stack. Back when I was awarded the MVP, I was given the Client AppDev designation, which basically means WPF (but for some reason, contrary to what I&amp;rsquo;ve said above, also included WinForms..interesting how they had WPF and WinForms in the same group but not WPF and Silverlight&amp;hellip;but I digress&amp;hellip;or do I?). Back then Xaml tech wasn&amp;rsquo;t so secretive. When Silverlight came along, they moved me into that group. That group was different. Silverlight was kept tightly sealed. When I was a Client AppDev, I actually felt like Rob Relyea and John Gossman were my kin. When I became a Silverlight MVP, I felt like I was an outsider being graced with a little tiny window to peer in on things. I say all that because when I started on Caliburn, while I was working on a proprietary platform, it felt more open. But when Silverlight came along, things changed. WP7 was even worse than Silverlight&amp;hellip;and WinRT/Metro&amp;hellip;well&amp;hellip;they didn&amp;rsquo;t talk to anyone. Now that Xaml has moved out of the Developer Division and into the Windows division, it&amp;rsquo;s only going to get worse.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Secret Societies&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve already mentioned how the organization of the MVP groups along product lines can be a hindrance to everyone. WPF, Silverlight, WP7, Metro and Blend&amp;hellip;which are all used by the same group of people, are actually different MVP groups. As a Silverlight MVP&amp;hellip;I had no access to anything happening with WP7. I had no knowledge of WinRT/Metro. I had no knowledge of Blend or any mechanism to directly interact with that product team. Now, Caliburn.Micro spans all of these technologies, but I could really only talk to Silverlight product team members&amp;hellip;and a few of my old WPF comrades. But would it surprise you if I told you the organizational absurdity went even farther. Did you know there are &amp;ldquo;insiders&amp;rdquo; groups. &amp;ldquo;Insiders&amp;rdquo; for a particular product group have more privileged knowledge than MVPs and more opportunities for direct interaction. Some MVPs are also insiders, but not all. Some insiders are not MVPs. But wait, there&amp;rsquo;s more. There&amp;rsquo;s also the TAP program&amp;hellip;.which seams to have more privileged connections and knowledge. To this day, I don&amp;rsquo;t know how one gets in a TAP program. I was in the WP7 Tap for about two days. Some guys already in the program were talking in the TAP forums about getting Caliburn.Micro working on WP7. They yelled loud enough and the powers that be invited me, since it seamed that significant apps were likely to be built with my framework. Unfortunately, things went public very shortly after that and the TAP was closed. LOL. But it doesn&amp;rsquo;t end there. It seams, based on observation, that there are even more secretive groups&amp;hellip;who pretty much know everything the product team knows. These guys don&amp;rsquo;t have a name and I don&amp;rsquo;t know how you get into that. Though, I&amp;rsquo;m pretty sure it has to do with being &amp;ldquo;chummy&amp;rdquo; to the right people. Childishness. The bottom line is that there are too many levels of secrecy and too many and the wrong types of divisions to enable an effective feedback loop. I don&amp;rsquo;t know if this is true of all MVP groups, but it was with Silverlight and it has got worse with each successive Xaml platform. Now that Xaml is in Windows, I don&amp;rsquo;t expect anyone to be able to provide decent feedback.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Fruitlessness&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Since things are so improperly organized, there are really only a few occasions where one can really provide good feedback on the product. Unfortunately, after three years as an MVP, I have to say that not a single bit of feedback I provided resulted in any sort of change to the product. With the Silverlight team..and almost always with the Blend team (when I could actually run one of them down), I would get some response like &amp;ldquo;yes, we&amp;rsquo;ll have to have a conversation about that.&amp;rdquo; And I&amp;rsquo;d be thinking&amp;hellip;&amp;rdquo;isn&amp;rsquo;t that why I&amp;rsquo;m here at the MVP summit talking to you now?&amp;rdquo; But they never seamed to want to engage in a real discussion on *anything* that affected me, my project or my clients. I had this happen every year at the summit. I had even more outrageous things happen in email and at BUILD. On the insiders email list (when I finally got on it), I tried to start a conversation about Convention over Configuration and improvements to tooling that would help support those scenarios and generally make tool extensibility better. Somehow I managed to get into a private email thread of the Blend team where they could engage me on that. You know what they said when I tried to continue the conversation? They said &amp;ldquo;we don&amp;rsquo;t want to discuss that right now.&amp;rdquo; Ok&amp;hellip;thanks. That made me really mad. Why am I an MVP again? But the real treat was at BUILD. I managed to track down two of the Blend PMs. I first talked to the PM in charge of the JavaScript Blend work. I told him about what I was building in JavaScript. He was really interested and wanted to follow up with me on what I was building and how it would work inside Blend. Then I took several steps to the right to talk to a Blend PM working on the Xaml side of things. I tried, once again, to discuss CoC. I know for a fact these guys either don&amp;rsquo;t understand it or don&amp;rsquo;t think it&amp;rsquo;s important in software at all. Well, they listened for a moment, then I asked about improving the tooling so I could have a plugin mechanism by which to improve that scenario for my customers. They were very not-helpful. I tried to bring up issues of developer productivity and better strategies for building applications. In a nutshell, the PM basically said to me &amp;ldquo;we don&amp;rsquo;t care about developers&amp;hellip;they aren&amp;rsquo;t part of our use cases.&amp;rdquo; I was pretty enraged by that. See how the product team&amp;rsquo;s culture affects the effectiveness of the MVP program? My main point though is that nothing I ever said or did affected any product team&amp;rsquo;s work. Nothing. It was a waste of time and energy&amp;hellip;and an emotional drain.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;MVP Quality&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now I want to tread lightly here with how I say this&amp;hellip;.not all MVPs are created equal. I&amp;rsquo;m going to be vague here. I met an MVP once for Technology X. It turned out that she had never built anything with Technology X and wasn&amp;rsquo;t overly knowledgeable about it. She liked Technology X a lot though. Each day she would scan her RSS feeds and post about 8 - 10 links on Technology X. That&amp;rsquo;s why she had her MVP. It looks good on a review doesn&amp;rsquo;t it? I blogged 365 posts on Technology X this year!!&amp;nbsp; Now, I&amp;rsquo;ve met some MVPs in various areas that were brilliant and obviously contributing a lot. But, I&amp;rsquo;ve met a fair share of MVPs who not only were not experts on the technology, but didn&amp;rsquo;t make half the contribution that other developers I knew did, who were never awarded MVPs. Not all MVPs are equal. If you are an employer, or looking for a speaker, expert, consultant&amp;hellip;whatever; you cannot assume that just because that person has an MVP that they know what they are talking about. It&amp;rsquo;s sad, but this describes a noticeable number of MVPs.&lt;/p&gt;
&lt;p&gt;One more word on MVP quality with respect to division along product team lines. You should never hire a highly product-specific MVP to help advise you on technology choices. I hope you realize the built-in problem with that. I know very few Technology X MVPs who would tell you not to use Technology X, even if there was a better, cheaper, faster way to build your solution. Be wary.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Open Source&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I just want to say a little more about this. As I mentioned, there&amp;rsquo;s nothing about the MVP program that explicitly allows for recognition of open source work. It&amp;rsquo;s hard to get nominated for it and it&amp;rsquo;s even harder to renew with it. MVP leads who play a major roll in the renewal process may not be technical at all and even may not understand Open Source. Since I&amp;rsquo;ve mentioned how MVPs are linked to product groups, you might guess that the effectiveness of your MVP as an OSS developer is entirely dependent on that particular product group&amp;rsquo;s understanding of and interest in OSS. In a group related to ASP.NET or JavaScript, developers on the team are likely to have run open source projects themselves. In a group like Silverlight or WP7, they are likely to have never done such a thing&amp;hellip;and not even have a clear idea of what is involved. I really came face to face with this when my non-renewed MVP&amp;hellip;got renewed. Why? Well, it felt like a sort of &amp;ldquo;benefit of the doubt&amp;rdquo; renewal. Here&amp;rsquo;s the advice I was given from the renewal email, elided:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EDIT: I removed this quotation because a good friend of mine was honest enough to remind me that quoting a personal email is neither professional nor polite. I repent of that.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;--Start Rant&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What!? I released one of the most popular Xaml-related OSS project this year. I did multiple version releases, nuget packages, podcasts, documentation, forum support&amp;hellip;the list goes on. What more do you want from me? And what should I do next year&amp;hellip;because Caliburn.Micro is so popular, that in order for me to do something bigger for next year&amp;hellip;I&amp;rsquo;d have to dump it entirely&amp;hellip;.completely abandoned it and build something totally different&amp;hellip;something even more popular for Silverlight!? How could I do that to my community? That&amp;rsquo;s not even nice. No, in 2012, I&amp;rsquo;m going to continue to fix bugs, add features, add platform support and do awesome things with Caliburn.Micro. I love my own community and I&amp;rsquo;m going to continue to work hard and support them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;--End Rant&lt;/p&gt;
&lt;p&gt;Now this kind of comment clearly expresses a deep lack of understanding for both the value of a project like Caliburn.Micro and the amount of time and resources it takes to maintain both the project and the community. If your OSS project is successful, it&amp;rsquo;s not just something you do one year and then move on to something else the next. In fact, building the first version of Caliburn.Micro was the easy part! It&amp;rsquo;s everything that&amp;rsquo;s happened afterwards and what is happening now that is hard work and will continue to be.&lt;/p&gt;
&lt;p&gt;Unfortunately, Microsoft just doesn&amp;rsquo;t have a way of recognizing OSS developers who improve their platform. The MVP program doesn&amp;rsquo;t do this and the product teams may not either. In fact, Balmer has explicitly said he isn&amp;rsquo;t creating any policy around OSS&amp;hellip;he&amp;rsquo;s totally dodging it entirely. This leaves the decision up to the individual teams&amp;hellip;which sometimes goes well, but often times does not. That&amp;rsquo;s irresponsible leadership.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Career Affects&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;No one ever hired me as a consultant because I had an MVP. They hired me because of my open source work and my recognized expertise in UI architecture. The company I&amp;rsquo;m working for&amp;hellip;I don&amp;rsquo;t even think they know what an MVP is. They hired me because they know *me* and know I can help them with their particular problem. I would say the personal career benefits of having an MVP are a wash except&amp;hellip;&lt;/p&gt;
&lt;p&gt;With Microsoft&amp;rsquo;s less than above the bar treatment and communication about Silverlight over the last year or so, you might imagine this could effect MVPs associated with the program. I&amp;rsquo;ve heard a lot of horrible stories in the last year. I didn&amp;rsquo;t have anything terribly bad happen to my business, but I was quite embarrassed recently. I was attending a .NET user group meeting, of which I am the president. Somehow I or someone else mentioned that I was a Silverlight MVP. I don&amp;rsquo;t remember the detail about how it came up, but I do remember what happened next. Someone laughed at me. Literally, I was made fun of because my MVP had the word Silverlight attached to it. Now, I&amp;rsquo;m just not willing to endure mockery for the sake of Silverlight, especially since I understood exactly why he was laughing at me. It has got to where being a &amp;ldquo;Silverlight&amp;rdquo; MVP is bad for my career.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;My Happiness&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Looking over the last three years, I&amp;rsquo;ve definitely been a less happy, more frustrated developer. I&amp;rsquo;m sure it&amp;rsquo;s linked to the sort of fake &amp;ldquo;value&amp;rdquo; being a Silverlight MVP gave me. Basically, they give you a couple of cheep gifts, then they pretend to listen to your feedback, while not actually doing anything. Year after year of that and you get really unhappy. It&amp;rsquo;s demoralizing. You start to realize that you really are a commodity. You are purchased by a product group and kept around as long as they perceive they need you&amp;hellip;your feedback is allowed, but not effective. Again, it&amp;rsquo;s probably not the case for all MVPs, it depends on the groups. I just don&amp;rsquo;t need that in my life.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m saying goodbye to the MVP program even after I was re-offered the award for 2012. If you&amp;rsquo;ve read this far, you can probably see why I made that decision. I&amp;rsquo;m really positive about the future of Caliburn.Micro and hopeful regarding my JavaScript framework. I think 2012 is going to be a wonderful year. If someone seriously reforms the MVP program or if Microsoft decides to properly recognize and reward open source efforts, then, maybe I&amp;rsquo;ll let them give me an award. But for now, I don&amp;rsquo;t need to suffer any more. I&amp;rsquo;m free and I&amp;rsquo;m going to do great things.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=68957" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.0/default.aspx">.NET 3.0</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NuGet/default.aspx">NuGet</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVP/default.aspx">MVP</category></item><item><title>Caliburn.Micro v1.2 RTW and Nuget Feature Packages!</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2011/07/30/caliburn-micro-v1-2-rtw-plus-nuget-feature-packages.aspx</link><pubDate>Sat, 30 Jul 2011 17:40:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:68054</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=68054</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2011/07/30/caliburn-micro-v1-2-rtw-plus-nuget-feature-packages.aspx#comments</comments><description>&lt;p&gt;Today, I&amp;rsquo;m pleased to announce &lt;a target="_blank" href="http://caliburnmicro.codeplex.com/releases/view/70940"&gt;the RTW of Caliburn.Micro v1.2&lt;/a&gt;. In this release we&amp;rsquo;ve had a number of bug fixes as well as a few incremental feature additions and refactorings. You can read the list of changes on the project site or get it as part of the download. Of course, v1.2 is now &lt;a target="_blank" href="http://nuget.org/List/Packages/Caliburn.Micro"&gt;available through Nuget&lt;/a&gt; as well. &lt;/p&gt;
&lt;p&gt;In addition to the standard release, I&amp;rsquo;m happy to announce something new we are doing with Caliburn.Micro: Feature Packages. Feature Packages allow developers a way pick and choose only the features they want from Caliburn.Micro and not have to take a dependency on other unused features of the framework. This allows for smaller Silverlight and WP7 applications as well as the ability to use some Caliburn.Micro features outside of the scope of a Xaml-application at all. Currently, we only have three feature packages available, but those will likely expand in the future.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a list of all the official Caliburn.Micro related packages on Nuget:&lt;/p&gt;
&lt;p&gt;Caliburn.Micro &amp;ndash; The full framework compiled into an assembly.&lt;/p&gt;
&lt;p&gt;Caliburn.Micro.Container &amp;ndash; The Caliburn.Micro inversion of control container (IoC), provided as a source code drop-in.&lt;/p&gt;
&lt;p&gt;Caliburn.Micro.EventAggregator &amp;ndash; The Caliburn.Micro event aggregator, provided as a source code drop-in.&lt;/p&gt;
&lt;p&gt;Caliburn.Micro.INPC &amp;ndash; The Caliburn.Micro INPC infrastructure: PropertyChangedBase, BindableCollection, Execute.OnUIThread and InDesignMode checking, provided as a source code drop-in.&lt;/p&gt;
&lt;p&gt;Interestingly, by combing the container, event aggregator and INPC packages, you basically get something equivalent to MVVMLight Toolkit. So, if you are looking to get started with the absolute minimal needed to do MVVM, we have a solution for you. Naturally, it&amp;rsquo;s source-code-identical to Caliburn.Micro, which means you can upgrade from any combination of feature packages to the full framework without having to change a line of your code.&lt;/p&gt;
&lt;p&gt;Happy app-building!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=68054" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NuGet/default.aspx">NuGet</category></item><item><title>Caliburn.Micro Soup to Nuts Part 9–New WP7 Features</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2011/06/09/caliburn-micro-soup-to-nuts-part-9-new-wp7-features.aspx</link><pubDate>Thu, 09 Jun 2011 17:23:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:67721</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=67721</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2011/06/09/caliburn-micro-soup-to-nuts-part-9-new-wp7-features.aspx#comments</comments><description>&lt;p&gt;In version 1.0 we had pretty good support for building apps for WP7, but in v1.1 we&amp;rsquo;ve taken things up a notch. Let&amp;rsquo;s look at the same HelloWP7 sample that we did &lt;a target="_blank" href="http://caliburnmicro.codeplex.com/wikipage?title=Working%20with%20Windows%20Phone%207&amp;amp;referringTitle=Documentation"&gt;previously&lt;/a&gt;, but see how it&amp;rsquo;s been updated to take advantage of our improved tombstoning, launcher/chooser support and strongly typed navigation. You&amp;rsquo;ll also notice that the code is cleaner overall.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bootstrapper&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the cleaned up boostrapper in v1.1.&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class HelloWP7Bootstrapper : PhoneBootstrapper {
    PhoneContainer container;

    protected override void Configure() {
        container = new PhoneContainer(RootFrame);

        container.RegisterPhoneServices();
        container.PerRequest&amp;lt;MainPageViewModel&amp;gt;();
        container.PerRequest&amp;lt;PivotPageViewModel&amp;gt;();
        container.PerRequest&amp;lt;TabViewModel&amp;gt;();

        AddCustomConventions();
    }

    static void AddCustomConventions() {
        //ellided
    }

    protected override object GetInstance(Type service, string key) {
        return container.GetInstance(service, key);
    }

    protected override IEnumerable&amp;lt;object&amp;gt; GetAllInstances(Type service) {
        return container.GetAllInstances(service);
    }

    protected override void BuildUp(object instance) {
        container.BuildUp(instance);
    }
}&lt;/pre&gt;
&lt;p&gt;There are two things to notice here. First, we&amp;rsquo;ve removed all the manual Caliburn.Micro service configuration and pushed it into the SimpleContainer. That gives you one line of code to configure the framework if you are using the OOTB container. Speaking of which, we now provide the SimpleContainer officially in the Caliburn.Micro.Extensions assembly. That helps you get started faster. You can always plug your own in, of coarse. In addition to the simplified configuration, notice that the ViewModels for pages are no longer registered using a string key. For v1.1 our ViewModelLocator has been re-implemented to pull VMs from the container by Type rather than key. It now follows the exact same naming strategies as the ViewLocator (but in reverse) and even derives possible interface names so that it resolves VMs from the container correctly. This both improves the consistency of ViewModel location as well as makes the configuration simpler.&lt;/p&gt;
&lt;p&gt;The boostrapper is added to your App.xaml as always:&lt;/p&gt;
&lt;pre name="code" class="xml:nogutter:nocontrols"&gt;&amp;lt;Application x:Class=&amp;quot;Caliburn.Micro.HelloWP7.App&amp;quot;
             xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;
             xmlns:x=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;
             xmlns:local=&amp;quot;clr-namespace:Caliburn.Micro.HelloWP7&amp;quot;&amp;gt;
    &amp;lt;Application.Resources&amp;gt;
        &amp;lt;local:HelloWP7Bootstrapper x:Key=&amp;quot;bootstrapper&amp;quot; /&amp;gt;
    &amp;lt;/Application.Resources&amp;gt;
&amp;lt;/Application&amp;gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Important Note About App.xaml.cs&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you create your WP7 application using a standard Visual Studio template, the generated App.xaml.cs file will have a lot of code in it. The purpose of this code is to set up the root frame for the application and make sure everything gets initialized properly. Of course, that&amp;#39;s what the bootstrapper&amp;#39;s job is too (and in fact it does a few things better than the out-of-the-box code in addition to configuring CM). So, you don&amp;#39;t need both. When using CM&amp;#39;s PhoneBootstrapper, be sure to clear out all the code from the App.xaml.cs file except for the call to InitializeComponent in the constructor.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;INavigationService&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s review what CM&amp;rsquo;s INavigationService&amp;nbsp; does for you. First, remember that WP7 enforces a View-First approach to UI at the platform level. Like it or not, the platform is going to create pages at will and the Frame control is going to conduct your application thusly. You don&amp;rsquo;t get to control that and there are no extensibility points, unlike the Silverlight version of the navigation framework. Rather than fight this, I&amp;rsquo;m going to recommend embracing the View-First approach for Pages in WP7, but maintaining a Model-First composition strategy for the sub-components of those pages and a Model-First approach to coding against the navigation system. In order to bridge this gap, I&amp;rsquo;ve enabled the INavigationService to hook into the native navigation frame&amp;rsquo;s functionality and augment it with the following behaviors:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;When Navigating To a Page&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use the new ViewModelLocator to conventionally determine the Type of the VM that should be attached to the page being navigated to. Pull that VM by Type out of the container.&lt;/li&gt;
&lt;li&gt;If a VM is found, use the ViewModelBinder to connect the Page to the located ViewModel.&lt;/li&gt;
&lt;li&gt;Examine the Page&amp;rsquo;s QueryString. Look for properties on the VM that match the QueryString parameters and inject them, performing the necessary type coercion.&lt;/li&gt;
&lt;li&gt;If the ViewModel implements the IActivate interface, call its Activate method.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;When Navigating Away From a Page&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Detect whether the associated ViewModel implements the IGuardClose interface.&lt;/li&gt;
&lt;li&gt;If IGuardClose is implemented and the app is not being tombstoned or closed, invoke the CanClose method and use its result to optionally cancel page navigation.&lt;sup&gt;1&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;If the ViewModel can close and implements the IDeactivate interface, call it&amp;rsquo;s Deactivate method. Always pass &amp;ldquo;false&amp;rdquo; to indicate that the VM should deactivate, but not necessarily close. This is because the phone may be deactivating, but not actually tombstoning or closing. There&amp;rsquo;s no way to know.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The behavior of the navigation service allows the correct VM to be hooked up to the page, allows that VM to be notified that it is being navigated to (IActivate), allows it to prevent navigation away from the current page (IGuardClose) and allows it to clean up after itself on navigation away, tombstoning or normal &amp;ldquo;closing&amp;rdquo; of the application (IDeactivate). All these interfaces (and a couple more) are implemented by the Screen class. If you prefer not to inherit from Screen, you can implement any of the interfaces individually of coarse. They provide a nice View-Model-Centric, testable and predictable way of responding to navigation without needing to wire up a ton of event handlers or write important application flow logic in the page&amp;rsquo;s code-behind.&lt;/p&gt;
&lt;p&gt;These hooks into phone navigation enable a really smooth way of interacting with the phone&amp;rsquo;s navigation lifecycle. But now that we have an improved ViewModelLocator that matches exactly the ViewLocator and works on types, we can take things further. In v1.1 we&amp;rsquo;ve introduced support for strongly-typed navigation. Here&amp;rsquo;s what the new MainPageViewModel from the sample looks like using this new feature:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class MainPageViewModel {
    readonly INavigationService navigationService;

    public MainPageViewModel(INavigationService navigationService) {
        this.navigationService = navigationService;
    }

    public void GotoPageTwo() {
        navigationService.UriFor&amp;lt;PivotPageViewModel&amp;gt;()
            .WithParam(x =&amp;gt; x.NumberOfTabs, 5)
            .Navigate();
    }
}&lt;/pre&gt;
&lt;p&gt;This allows you to specify a ViewModel to navigate to along with the query string parameters. Since this all happens using generics and lambdas, you can never miss-type a page Uri or mess up your query strings&amp;hellip;.and refactoring will work beautifully.&lt;/p&gt;
&lt;p&gt;For the sake of completeness, here&amp;rsquo;s the page that will be bound to MainPageViewModel:&lt;/p&gt;
&lt;pre name="code" class="xml:nogutter:nocontrols"&gt;&amp;lt;phone:PhoneApplicationPage x:Class=&amp;quot;Caliburn.Micro.HelloWP7.MainPage&amp;quot;
                            xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;
                            xmlns:x=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;
                            xmlns:phone=&amp;quot;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone&amp;quot;
                            xmlns:shell=&amp;quot;clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone&amp;quot;
                            xmlns:cal=&amp;quot;clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro&amp;quot;
                            SupportedOrientations=&amp;quot;Portrait&amp;quot;
                            Orientation=&amp;quot;Portrait&amp;quot;
                            shell:SystemTray.IsVisible=&amp;quot;True&amp;quot;&amp;gt;
    &amp;lt;Grid Background=&amp;quot;Transparent&amp;quot;&amp;gt;
        &amp;lt;Grid.RowDefinitions&amp;gt;
            &amp;lt;RowDefinition Height=&amp;quot;Auto&amp;quot; /&amp;gt;
            &amp;lt;RowDefinition Height=&amp;quot;*&amp;quot; /&amp;gt;
        &amp;lt;/Grid.RowDefinitions&amp;gt;
        &amp;lt;StackPanel Grid.Row=&amp;quot;0&amp;quot;
                    Margin=&amp;quot;24,24,0,12&amp;quot;&amp;gt;
            &amp;lt;TextBlock Text=&amp;quot;WP7 Caliburn.Micro&amp;quot;
                       Style=&amp;#39;{StaticResource PhoneTextNormalStyle}&amp;#39; /&amp;gt;
            &amp;lt;TextBlock Text=&amp;#39;Main Page&amp;#39;
                       Margin=&amp;#39;-3,-8,0,0&amp;#39;
                       Style=&amp;#39;{StaticResource PhoneTextTitle1Style}&amp;#39; /&amp;gt;
        &amp;lt;/StackPanel&amp;gt;

        &amp;lt;Grid Grid.Row=&amp;#39;1&amp;#39;&amp;gt;
            &amp;lt;Button x:Name=&amp;#39;GotoPageTwo&amp;#39;
                    Content=&amp;#39;Goto Page Two&amp;#39; /&amp;gt;
        &amp;lt;/Grid&amp;gt;
    &amp;lt;/Grid&amp;gt;

    &amp;lt;phone:PhoneApplicationPage.ApplicationBar&amp;gt;
        &amp;lt;shell:ApplicationBar IsVisible=&amp;#39;True&amp;#39;&amp;gt;
            &amp;lt;shell:ApplicationBar.Buttons&amp;gt;
                &amp;lt;cal:AppBarButton IconUri=&amp;#39;ApplicationIcon.png&amp;#39;
                                  Text=&amp;#39;Page Two&amp;#39;
                                  Message=&amp;#39;GotoPageTwo&amp;#39; /&amp;gt;
            &amp;lt;/shell:ApplicationBar.Buttons&amp;gt;
        &amp;lt;/shell:ApplicationBar&amp;gt;
    &amp;lt;/phone:PhoneApplicationPage.ApplicationBar&amp;gt;
&amp;lt;/phone:PhoneApplicationPage&amp;gt;&lt;/pre&gt;
&lt;p&gt;There&amp;rsquo;s really nothing new here in v1.1. But I just wanted to remind you that Caliburn.Micro supports Actions on the AppBar&amp;nbsp; as long as you use CM&amp;rsquo;s AppBarButton and AppBarMenuItem :) &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IPhoneService&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The IPhoneService wraps the phone&amp;rsquo;s frame and provides access to important information and events. We had this service in v1.0 but we&amp;rsquo;ve expanded it in v1.1 to expose a better event model. Those familiar with WP7 know that the phone has a series of events that fire in different circumstances: Launching, Activated, Deactivated and Closing. Unfortunately, these events obscure whether the phone is actually resurrecting from a tombstoned state or simply continuing execution. The current SDK does not make it easy for the developer to actually determine this, so Caliburn.Micro does the heavy lifting for you and provides the following event model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Launching - Occurs when a fresh instance of the application is launching.&lt;/li&gt;
&lt;li&gt;Activated - Occurs when a previously paused/tombstoned app is resumed/resurrected.&lt;/li&gt;
&lt;li&gt;Deactivated - Occurs when the application is being paused or tombstoned.&lt;/li&gt;
&lt;li&gt;Closing - Occurs when the application is closing.&lt;/li&gt;
&lt;li&gt;Continuing -&amp;nbsp; Occurs when the app is continuing from a temporarily paused state.&lt;/li&gt;
&lt;li&gt;Continued - Occurs after the app has continued from a temporarily paused state.&lt;/li&gt;
&lt;li&gt;Resurrecting - Occurs when the app is &amp;quot;resurrecting&amp;quot; from a tombstoned state.&lt;/li&gt;
&lt;li&gt;Resurrected - Occurs after the app has &amp;quot;resurrected&amp;quot; from a tombstoned state.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using these new events, you can more intelligently make decisions about whether or not you need to restore data. In the forthcoming Mango release, the platform will provide us information on whether the app is continuing or resurrecting. However, developers working with Caliburn.Micro can have that information now and when Mango arrives, we&amp;rsquo;ll update our implementation to use the new bits. Your code won&amp;rsquo;t have to change.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tombstoning&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As you might imagine, our new tombstoning mechanism takes advantage of the new events so that it can more reliably and accurately save/restore important data. Let&amp;rsquo;s have a look at the PivotPageViewModel to see how it interacts with the tombstoning mechanism.&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class PivotPageViewModel : Conductor&amp;lt;IScreen&amp;gt;.Collection.OneActive {
    readonly Func&amp;lt;TabViewModel&amp;gt; createTab;

    public PivotPageViewModel(Func&amp;lt;TabViewModel&amp;gt; createTab) {
        this.createTab = createTab;
    }

    public int NumberOfTabs { get; set; }

    protected override void OnInitialize() {
        Enumerable.Range(1, NumberOfTabs).Apply(x =&amp;gt; {
            var tab = createTab();
            tab.DisplayName = &amp;quot;Item &amp;quot; + x;
            Items.Add(tab);
        });

        ActivateItem(Items[0]);
    }
}&lt;/pre&gt;
&lt;p&gt;The PivotPageViewModel will receive the number of pivot items to create through it&amp;rsquo;s NumberOfTabs property, which is pushed in from the query string, as mentioned above. It will then add these items to the conductor and activate the first one. If you&amp;rsquo;re familiar with the Pivot and CM&amp;rsquo;s previous sample, you&amp;rsquo;ll notice that our PivotFix is gone. Pivot has a horrible bug that will crash your application if you try to set the SelectedItem or SelectedIndex to an item 3 or greater from either end of the pivot collection, while the Pivot itself is not visible. This makes it really hard to restore this control from a tombstoned state because you have to set the value at the exact right time. Previously we used a PivotFix hack to work around the control&amp;rsquo;s bug, but the new tombstoning mechanism is powerful and extensible enough to just make it work. You&amp;rsquo;ll notice that there are no attributes describing tombstoning behavior. They&amp;rsquo;ve been removed in favor of a poco model inspired by Fluent NHibhernate. If you would rather have the attributes, you can actually build them on top of the new system. The new system is also more reliable than previously and has a lot more options for storage. Let&amp;rsquo;s see the class that describes the tombstoning behavior for PivotPageViewModel:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class PivotPageModelStorage : StorageHandler&amp;lt;PivotPageViewModel&amp;gt; {
    public override void Configure() {
        this.ActiveItemIndex()
            .InPhoneState()
            .RestoreAfterViewLoad();
    }
}&lt;/pre&gt;
&lt;p&gt;All you&amp;nbsp; have to do to make a class participate in tombstoning is to inherit from StorageHandler&amp;lt;T&amp;gt;. The PhoneContainer will auto-register anything of this type in the assembly. Just override the Configure method and declare the tombstoning instructions. I&amp;rsquo;ve created some extension methods for common scenarios. Here&amp;rsquo;s what the above declaration states:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;-Persist the Conductor&amp;rsquo;s ActiveItem&amp;rsquo;s index&lt;/li&gt;
&lt;li&gt;-Store the index in PhoneState&lt;/li&gt;
&lt;li&gt;-Restore the value after the associated view has been loaded.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s look at the storage handler for the TabViewModel to see some more options:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class TabViewModelStorage : StorageHandler&amp;lt;TabViewModel&amp;gt; {
    public override void Configure() {
        Id(x =&amp;gt; x.DisplayName);

        Property(x =&amp;gt; x.Text)
            .InPhoneState()
            .RestoreAfterActivation();
    }
}&lt;/pre&gt;
&lt;p&gt;Here we are specifying an Id because we actually need to persist multiple instances of the same VM. When we restore, we&amp;rsquo;ll need to know how to map the properties back. We&amp;rsquo;re also storing the data in PhoneState, but this time we&amp;rsquo;re not waiting for the view to load, but just waiting for the TabViewModel to be activated by its owning Conductor.&lt;/p&gt;
&lt;p&gt;Out of the box, we also support storing data in AppSettings. For example, if you wanted to same tab to be selected *across application restarts* not just when tombstoned, you could define the PivotPageModelStorage like this:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class PivotPageModelStorage : StorageHandler&amp;lt;PivotPageViewModel&amp;gt; {
    public override void Configure() {
        this.ActiveItemIndex()
            .InAppSettings()
            .RestoreAfterViewLoad();
    }
}&lt;/pre&gt;
&lt;p&gt;Pretty easy? All this works by collaborating with the IoC container and keying off of the new event model exposed by the IPhoneService. It&amp;rsquo;s pretty powerful and extensible. You can add your own storage mechanism or define your own restore timing. You can even implement IStorageHandler directly to write completely custom code on a class by class basis. You could easily add a version that inspected classes for custom attributes and built up the configuration, if you like the attribute model better. You can also store whole instances, not just their properties, and have them rehydrated properly and available for ctor injection.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Launchers and Choosers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Launchers and Choosers are painful to work with if you want to do MVVM. In v1.0 we provided a solution to this. I wasn&amp;rsquo;t happy with its implementation&amp;hellip;it was unpredictable in certain scenarios. Once we established the new phone events, better IoC integration and new tombstoning mechanism, I realized I could build a better launcher/chooser system. Let&amp;rsquo;s take a look at the updated version of TabViewModel in order to see how it works:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class TabViewModel : Screen, IHandle&amp;lt;TaskCompleted&amp;lt;PhoneNumberResult&amp;gt;&amp;gt; {
    string text;
    readonly IEventAggregator events;

    public TabViewModel(IEventAggregator events) {
        this.events = events;
    }

    public string Text {
        get { return text; }
        set {
            text = value;
            NotifyOfPropertyChange(() =&amp;gt; Text);
        }
    }

    public void Choose() {
        events.RequestTask&amp;lt;PhoneNumberChooserTask&amp;gt;();
    }

    public void Handle(TaskCompleted&amp;lt;PhoneNumberResult&amp;gt; message) {
        MessageBox.Show(&amp;quot;The result was &amp;quot; + message.Result.TaskResult, DisplayName, MessageBoxButton.OK);
    }

    protected override void OnActivate() {
        events.Subscribe(this);
        base.OnActivate();
    }

    protected override void OnDeactivate(bool close) {
        events.Unsubscribe(this);
        base.OnDeactivate(close);
    }
}&lt;/pre&gt;
&lt;p&gt;The most significant architectural change I made was to re-implement the launcher/chooser mechanism to work on top of the IEventAggregator. Take a look at the Choose method. The RequestTask method is just an extension method of the IEventAggregator that publishes a special event that the framework is subscribed to. The framework then starts the task. When it&amp;rsquo;s completed, the framework publishes an event TaskCompleted&amp;lt;T&amp;gt; where T is the result the the chooser returns. You can register for this in the same VM that published the chooser event or in an entirely different one if you like. In the case of our sample, we have 5 TabViewModels that can launch the same chooser. That&amp;rsquo;s probably not normal, but you can handle this situation in three ways. In our case, the VMs are in a Conductor, and only one of them can be active at a time, so we just Subscribe/Unsubscribe based on the Screen lifecycle so that only the active VM will receive the result. This is a version of &lt;a target="_blank" href="http://codebetter.com/jeremymiller/2007/07/02/build-your-own-cab-12-rein-in-runaway-events-with-the-quot-latch-quot/"&gt;the Latch pattern&lt;/a&gt;. The second way to handle this is through the event state. When you call the RequestTask method you can pass a state object which you can use for identification purposes later. Yes, this will be present even if the chooser causes a tombstone event. The final way is to have a single object that registers for the completed event, decoupling the launching from the completion. Thus multiple VM could launch the same chooser, but only one class would handle the result.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IWindowManager&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The IWindowManager was actually in v1.0, as a last minute addition. It&amp;rsquo;s a really easy way to show native-looking, custom message boxes or modal dialogs. You can also use it to show popups. We&amp;rsquo;ll talk more about the window manager, on all platforms, in the next post.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Referenced Samples&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Caliburn.Micro.HelloWP7&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Footnotes&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Even though the IGuardClose interface was designed to handle async scenarios, you must use it synchronously in WP7. This is due to a flaw in the design of Silverlight Navigation Framework which doesn&amp;rsquo;t account for async shutdown scenarios.&lt;/li&gt;
&lt;/ol&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=67721" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/DSL/default.aspx">DSL</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Tutorial/default.aspx">Tutorial</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category></item><item><title>Caliburn.Micro v1.1 RTW</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2011/06/01/caliburn-micro-v1-1-rtw.aspx</link><pubDate>Wed, 01 Jun 2011 17:08:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:67427</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=67427</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2011/06/01/caliburn-micro-v1-1-rtw.aspx#comments</comments><description>&lt;p&gt;Today I&amp;rsquo;m happy to announce the release of &lt;a target="_blank" href="http://caliburnmicro.codeplex.com/releases/view/67451"&gt;Caliburn.Micro v1.1&lt;/a&gt;. You can get it on &lt;a target="_blank" href="http://caliburnmicro.codeplex.com/releases/view/67451"&gt;our project site&lt;/a&gt; or by &lt;a target="_blank" href="http://nuget.org/List/Packages/Caliburn.Micro"&gt;using Nuget&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve had a number of bug fixes, general improvements and a few new features added. Here&amp;rsquo;s the highlights:&lt;/p&gt;
&lt;p&gt;For WP7&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A new Tombstoning API based on ideas from Fluent NHibernate&lt;/li&gt;
&lt;li&gt;A new Launcher/Chooser API&lt;/li&gt;
&lt;li&gt;Strongly typed Navigation&lt;/li&gt;
&lt;li&gt;SimpleContainer included&lt;/li&gt;
&lt;li&gt;The full phone lifecycle is made easy to work with
&lt;ul&gt;
&lt;li&gt;ie. we figure out whether your app is actually Resurrecting of just Continuing and tell you&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For WPF&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Support for the Client Profile&lt;/li&gt;
&lt;li&gt;Better support for WinForms integration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All Platforms&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A powerful new RegEx-based ViewLocator and ViewModelLocator
&lt;ul&gt;
&lt;li&gt;Special thanks to &lt;a href="http://www.codeplex.com/site/users/view/cb55555"&gt;cb55555&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Polymorphic subscriptions and custom thread marshaling for the EventAggregator&lt;/li&gt;
&lt;li&gt;Numerous bug fixes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can get the complete list of changes in the release notes. Enjoy!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=67427" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NuGet/default.aspx">NuGet</category></item><item><title>Caliburn.Micro Soup to Nuts Part 8–The EventAggregator</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2011/05/30/caliburn-micro-soup-to-nuts-part-8-the-eventaggregator.aspx</link><pubDate>Mon, 30 May 2011 16:06:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:67406</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=67406</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2011/05/30/caliburn-micro-soup-to-nuts-part-8-the-eventaggregator.aspx#comments</comments><description>&lt;p&gt;In Caliburn.Micro we have a series of supporting services for building presentation tiers. Among them is the EventAggregator, a service which supports in-process publish/subscribe. There are various implementations of this pattern available in other frameworks, but I think you&amp;rsquo;ll find that Caliburn.Micro&amp;rsquo;s implementation sports the cleanest API and the richest set of features. Let&amp;rsquo;s start by having a look at the IEventAggregator interface:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public interface IEventAggregator {
    void Subscribe(object instance);
    void Unsubscribe(object instance);
    void Publish(object message, Action&amp;lt;System.Action&amp;gt; marshal = null);
}&lt;/pre&gt;
&lt;p&gt;Below we&amp;rsquo;ll dig into how the default implementation of this interface (EventAggregator) works.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Subscribe&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With the Caliburn.Micro EventAggregator we don&amp;rsquo;t actually leverage events under the covers. Events are prone to memory leaks and it&amp;rsquo;s extremely difficult to avoid them or to write a flawless weak event implementation. Instead, we allow you to subscribe an object instance. Under the covers we hold a weak reference. That makes things quite simple. But, how do we know what messages to subscribe to and what methods to use as callbacks? Well, we follow a declarative model by requiring subscribers to implement an interface which states which message they are interested in and provides the callback method. The interface looks like this:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public interface IHandle&amp;lt;TMessage&amp;gt; : IHandle {
    void Handle(TMessage message);
}&lt;/pre&gt;
&lt;p&gt;And it&amp;rsquo;s used like this:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class MyViewModel : IHandle&amp;lt;SomeMessage&amp;gt;{
    public void Handle(SomeMessage message){
        //do something with the message
    }
}&lt;/pre&gt;
&lt;p&gt;Because we use an interface, you can implement IHandle&amp;lt;T&amp;gt; as many times as you want on a given class. This approach keeps things declarative, strongly-typed and free from memory leaks. You can even use explicit interface implementations to hide the handlers if you desire.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Unsubscribe&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s not too much to say about this. When you call this method, we search our list of subscribers and remove the specified instance. You may be wondering why this is even necessary if subscribers are held with weak references to begin with. It turns out that there are a number of cases where you want to control the subscription&amp;rsquo;s activation. Imagine you have a Screen Collection and only the Active Screen is supposed to receive events. In this case, you&amp;rsquo;d want to subscribe when the screen was activated and unsubscribe when it was deactivated. See the v1.1 HelloWP7 sample for an example of how this works with the new Launcher/Choosers mechanism.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Publish&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As you might expect, calling Publish actually sends a message to all it&amp;rsquo;s subscribers. Here&amp;rsquo;s how you might use it:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class MyOtherViewModel{
    IEventAggregator events;

    public MyOtherViewModel(IEventAggregator events){
        this.events = events;
    }

    public void DoSomething(){
        events.Publish(new SomeMessage{
            SomeNumber = 5,
            SomeString = &amp;quot;Blah...&amp;quot;
        });
    }
}&lt;/pre&gt;
&lt;p&gt;Here, we get an instance of the IEventAggregator service via constructor injection. Then, when the DoSomething method is invoked, we publish the SomeMessage message along with its data. Assuming MyViewMododel above had subscribed itself to the aggregator, it would then have it&amp;#39;s Handle method called with the SomeMessage instance. So how does this work? We do this by iterating our list of subscribers to see if any of them implement IHandle&amp;lt;T&amp;gt; where T is assignable from the message that is being published. All the matches that are found then have their handlers called on the UI thread.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Marker Interface&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;IHandle&amp;lt;T&amp;gt; inherits from a marker interface IHandle. This allows the use of casting to determine if an object instance subscribes to any events. This enables simple auto-subscribing if you integrate with an IoC container. Most IoC containers (including the SimpleContainer) provide a hook for being called when a new instance is created. Simply wire for your container&amp;rsquo;s callback, inspect the instance being created to see if it implement IHandle, and if it does, call Subscribe on the event aggregator. Just remember, you probably don&amp;rsquo;t want to use this technique if you need conditional subscription as I described above.&lt;/p&gt;
&lt;h2&gt;New in v1.1&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Custom Publication Marshaling&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Those familiar with v1.0 may notice a few interesting differences in the interface. Among them is the optional &amp;ldquo;marshal&amp;rdquo; parameter of the Publish method. By default messages will be automatically published synchronously on the UI thread. However, this is not always desirable. The optional parameter allows you to provide an action which marshals the publication to a custom thread. By using this extension point, a developer could easily write extension methods such as: PublishOnCurrentThread, PublishOnBackgroundThread or PublishOnUIThreadAsync.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Polymorphic Event Subscriptions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Above I stated that during publication we check for handlers &amp;ldquo;where T is assignable from the message being published.&amp;rdquo; We do this with reflection in v1.1 rather than casting (v1.0) in order to enable polymorphic event subscriptions. Let me explain what this means by providing an example:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public interface ICustomerMessage{
    //implementation here
}

public interface ICustomerCreated : ICustomerMessage{
    //implementation here
}

public interface ICustomerDeleted : ICustomerMessage{
    //implementation here
}

public class AnUnrelatedMessage{
    //implementation here
}

public class MyObserver :
    IHandle&amp;lt;object&amp;gt;, 
    IHandle&amp;lt;ICustomerMessage&amp;gt;, 
    IHandle&amp;lt;ICustomerDeleted&amp;gt; {
    
    public void Handle(object message){
        //will handle every message in the application
    }

    public void Handle(ICustomerMessage message){
        //handles ICustomerCreated and ICustomerDeleted
    }

    public void Handle(ICustomerDeleted message){
        //handles only ICustomerDeleted
    }
}&lt;/pre&gt;
&lt;p&gt;This turns out to be very powerful, especially when you need to evolve a system over time.&lt;/p&gt;
&lt;p&gt;You can see the EventAggregator in action and step through some code by opening up the HelloEventAggregator sample under source. This sample creates a ShellViewModel with two child view models. Each child publishes a message that the other child is subscribed to. The ShellViewModel is subscribed to all messages via the polymorphic features of the aggregator. Here&amp;rsquo;s a screen shot after some messages have been published:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/HelloEventAggregator_5F00_775C276C.png"&gt;&lt;img height="370" width="501" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/HelloEventAggregator_5F00_thumb_5F00_1D51D7C3.png" alt="HelloEventAggregator" border="0" title="HelloEventAggregator" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=67406" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Tutorial/default.aspx">Tutorial</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category></item><item><title>Caliburn.Micro RTW, NuGet Support, Mix Open Source Festival!</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2011/04/11/caliburn-micro-rtw-nuget-support-mix-open-source-festival.aspx</link><pubDate>Mon, 11 Apr 2011 22:32:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:66873</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=66873</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2011/04/11/caliburn-micro-rtw-nuget-support-mix-open-source-festival.aspx#comments</comments><description>&lt;p&gt;Today, I&amp;rsquo;m proud to announce&lt;a href="http://caliburnmicro.codeplex.com/releases/view/64274"&gt; the v1.0 RTW of Caliburn.Micro for WPF, Silverlight and Window Phone 7&lt;/a&gt;!&amp;nbsp; The idea was born last year at Mix10 after my &lt;a href="http://channel9.msdn.com/Events/MIX/MIX10/EX15"&gt;Build Your Own MVVM Framework&lt;/a&gt; talk received overwhelmingly positive feedback. I want to give a big thanks to the developers who put their time into this. Thanks &lt;a href="http://devlicio.us/blogs/christopher_bennage/default.aspx"&gt;Christopher&lt;/a&gt;, &lt;a href="http://marcoamendola.wordpress.com/"&gt;Marco&lt;/a&gt; and &lt;a href="http://blog.cromwellhaus.com/"&gt;Ryan&lt;/a&gt;! Also, I want to say thanks to the community. It&amp;rsquo;s been exciting to see how fast a rich community of developers has grown up around this project and to see how many people are speaking about Caliburn.Micro at their local user groups, code camps and even major conferences such as &lt;a href="http://codestock.org/"&gt;Codestock&lt;/a&gt; and &lt;a href="http://www.msteched.com/2010/NewZealand/WPH301"&gt;teched&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Along with his release comes a number of bug fixes and even a few new features, such as the new WindowManager for WP7 which provides View-Model-First modal dialogs with animations designed after the native MessageBox. Be sure to thank Marco for that. After you thank Marco, you need to give props to Ryan who spearheaded the NuGet package development. As of right now, Caliburn.Micro can be installed quite easily from Visual Studio. If you have NuGet 1.2 or later installed, from the Package Manager Console, just type:&lt;/p&gt;
&lt;p&gt;Install-Package Caliburn.Micro&lt;/p&gt;
&lt;p&gt;Then, follow the few steps in the web page that pops up so that you get your bootstrapper added to App.xaml correctly, run the app and enjoy sweet Caliburn.Micro bliss :)&lt;/p&gt;
&lt;p&gt;The first release of Caliburn.Micro comes on the day of the first &lt;a href="http://live.visitmix.com/OpenSourceFest"&gt;Mix Open Source Festival&lt;/a&gt;. I&amp;rsquo;ll be there tonight representing the project and would love to meet you if you are present. Please come by, say hello, tell me about the cool stuff you are building&amp;hellip;and vote for the project of course! If you can&amp;rsquo;t make the festival, but will be at Mix, find me. I&amp;rsquo;m the short one.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=66873" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NuGet/default.aspx">NuGet</category></item><item><title>The Future of Blue Spire</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2011/04/07/the-future-of-blue-spire.aspx</link><pubDate>Thu, 07 Apr 2011 18:44:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:66831</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=66831</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2011/04/07/the-future-of-blue-spire.aspx#comments</comments><description>&lt;p&gt;Recently my good friend and business partner, Christopher Bennage, &lt;a href="http://devlicio.us/blogs/christopher_bennage/archive/2011/04/06/a-punctuated-life.aspx"&gt;made a decision&lt;/a&gt; to move his family to Redmond and take a job with Microsoft&amp;rsquo;s P&amp;amp;P team. A few people have been asking me what that means for Blue Spire. In short, I&amp;rsquo;m going to be focusing the company on what I know and do best: UI Architecture and Engineering. To that end there are three big areas I&amp;rsquo;m working on in the near future:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Caliburn.Micro&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Caliburn.Micro is an opinionated framework designed to ease the authoring of maintainable presentation tiers on Xaml-based platforms. There are a lot of apps being built with it and a great support community too. You will see the RTW release along with NuGet support *very* soon. After that, it&amp;rsquo;s on to work on the next version. I&amp;rsquo;ve got quite a few improvements planned now, not to mention support for Silverlight 5. In the next few months I&amp;rsquo;ll be initiating a Caliburn.Micro sponsorship program and possibly some other goodies&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Master Classes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a lot of talk in the .NET community about MVVM. There&amp;rsquo;s a lot of bad examples on the web of how to do it. Furthermore, the drone on the subject has unfortunately steered many developers away from an honest and deep exploration of UI engineering in general. This may come as a shock to many, but MVVM is not the only way and not always the right way to solve a problem. I&amp;rsquo;m working on putting together a 3 &amp;ndash; 5 day master class that focuses strictly on UI engineering. At first, I&amp;rsquo;ll be traveling to various cities around the U.S. delivering this course. I have plans to visit Europe in the future as well. The goal is to take experienced Xaml-developers and infuse a very deep understanding of object-oriented programming as it applies to the presentation tier. Sure we&amp;rsquo;ll talk about MVVM, we&amp;rsquo;ll work with Caliburn.Micro, etc. but we&amp;rsquo;ll be talking and working through a lot more things you&amp;rsquo;ll need to have mastery of to work effectively in this space. In addition to the standard courses, I&amp;rsquo;ll also be putting together a package geared towards companies that wish to invest in this type of training for their developers internally.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Consulting&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As always, I&amp;rsquo;m available as a consultant. I won&amp;rsquo;t lie. It&amp;rsquo;s not cheap to hire me to work on your presentation tier, but all my clients will tell you that they get tremendous &lt;em&gt;value&lt;/em&gt; for their money. In addition to traditional consulting, I&amp;rsquo;m offering two other special services. The first is code reviews. I&amp;rsquo;ve found that having an expert spend a few hours reviewing your code can make a tremendous difference. It can be anything from &amp;ldquo;Our application works fine, but it&amp;rsquo;s been difficult adding new features, how can we improve our design?&amp;rdquo; to &amp;ldquo;We have a WPF application and were wondering if/how difficult it would be to port it to Silverlight?&amp;rdquo; to &amp;ldquo;We have a complex feature and we need some advice on how we should proceed.&amp;rdquo; Maybe you would say &amp;ldquo;We have a brownfield WPF application with no separated presentation. We&amp;rsquo;re looking at improving things by using Caliburn.Micro. Can you help us gracefully accomplish that transition?&amp;rdquo; Basically, we time box some hours, I dive into your code and I come back out with some answers to help you on your way. Finally, in addition to the Master Classes above, I&amp;rsquo;ll be delivering week-long development Bootcamps for companies that want an intense combination of training and focused development on one of their products. Basically, I&amp;rsquo;ll be on site, developing along with your team, helping in key architectural decisions, teaching UI engineering and helping you to leverage Caliburn.Micro along the way. It might be a brownfeld application that needs refactoring because of maintenance issues or it might be a completely new project that your team wants a really strong start with.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Durandal&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I said three things didn&amp;rsquo;t I? Well, I can&amp;rsquo;t really help mentioning the Javascript RIA platform I&amp;rsquo;m working on. If you like the WPF/Silverlight development style and especially if you like Caliburn.Micro&amp;hellip;this is going to blow your mind. I&amp;rsquo;m very excited about it. If you&amp;rsquo;re going to be at Mix this year, come find me and maybe I&amp;rsquo;ll give you a little sneak peak :) As you might imagine, when it arrives, I&amp;rsquo;m going to provide a version of my UI Engineering master class geared around it as well as the bootcamps and consulting services. It&amp;rsquo;s a bit down the road, but I&amp;rsquo;m really looking forward to being able to share more with you about it.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=66831" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.0/default.aspx">.NET 3.0</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category></item><item><title>Two Caliburn Releases in One Day!</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2011/02/21/two-caliburn-releases-in-one-day.aspx</link><pubDate>Mon, 21 Feb 2011 19:18:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:66614</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=66614</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2011/02/21/two-caliburn-releases-in-one-day.aspx#comments</comments><description>&lt;p&gt;Today, I&amp;#39;m happy to make available the Release Candidates for both &lt;a target="_blank" href="http://caliburn.codeplex.com/releases/view/61383"&gt;Caliburn 2.0&lt;/a&gt;&amp;nbsp;and &lt;a target="_blank" href="http://caliburnmicro.codeplex.com/releases/view/61385"&gt;Caliburn.Micro 1.0&lt;/a&gt;! The docs for both have been updated significantly, though they will continue to evolve over the coming months. Get em&amp;#39; while they&amp;#39;re hot!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=66614" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category></item><item><title>Caliburn.Micro Soup to Nuts Part 7 - All About Conventions</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2010/12/16/caliburn-micro-soup-to-nuts-part-7-all-about-conventions.aspx</link><pubDate>Thu, 16 Dec 2010 20:49:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:63987</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=63987</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2010/12/16/caliburn-micro-soup-to-nuts-part-7-all-about-conventions.aspx#comments</comments><description>&lt;p&gt;One of the main features of Caliburn.Micro is manifest in its ability to remove the need for boiler plate code by acting on a series of conventions. Some people love conventions and some hate them. That&amp;rsquo;s why CM&amp;rsquo;s conventions are fully customizable and can even be turned off completely if not desired. If you are going to use conventions, and since they are ON by default, it&amp;rsquo;s good to know what those conventions are and how they work. That&amp;rsquo;s the subject of this article.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;View Resolution (ViewModel-First)&lt;/h2&gt;
&lt;h3&gt;Basics&lt;/h3&gt;
&lt;p&gt;The first convention you are likely to encounter when using CM is related to view resolution. This convention affects any ViewModel-First areas of your application. In ViewModel-First, we have an existing ViewModel that we need to render to the screen. To do this, CM uses a simple naming pattern to find a UserControl&lt;sup&gt;1&lt;/sup&gt; that it should bind to the ViewModel and display. So, what is that pattern? Let&amp;rsquo;s just take a look at ViewLocator.LocateForModelType to find out:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public static Func&amp;lt;Type, DependencyObject, object, UIElement&amp;gt; LocateForModelType = (modelType, displayLocation, context) =&amp;gt;{
    var viewTypeName = modelType.FullName.Replace(&amp;quot;Model&amp;quot;, string.Empty);
    if(context != null)
    {
        viewTypeName = viewTypeName.Remove(viewTypeName.Length - 4, 4);
        viewTypeName = viewTypeName + &amp;quot;.&amp;quot; + context;
    }

    var viewType = (from assmebly in AssemblySource.Instance
                    from type in assmebly.GetExportedTypes()
                    where type.FullName == viewTypeName
                    select type).FirstOrDefault();

    return viewType == null
        ? new TextBlock { Text = string.Format(&amp;quot;{0} not found.&amp;quot;, viewTypeName) }
        : GetOrCreateViewType(viewType);
};&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s ignore the &amp;ldquo;context&amp;rdquo; variable at first. To derive the view, we make an assumption that you are using the text &amp;ldquo;ViewModel&amp;rdquo; in the naming of your VMs, so we just change that to &amp;ldquo;View&amp;rdquo; everywhere that we find it by removing the word &amp;ldquo;Model&amp;rdquo;. This has the effect of changing both type names and namespaces. So ViewModels.CustomerViewModel would become Views.CustomerView. Or if you are organizing your application by feature: CustomerManagement.CustomerViewModel becomes CustomerManagement.CustomerView. Hopefully, that&amp;rsquo;s pretty straight forward. Once we have the name, we then search for types with that name. We search any assembly you have exposed to CM as searchable via AssemblySource.Instance.&lt;sup&gt;2&lt;/sup&gt; If we find the type, we create an instance (or get one from the IoC container if it&amp;rsquo;s registered) and return it to the caller. If we don&amp;rsquo;t find the type, we generate a view with an appropriate &amp;ldquo;not found&amp;rdquo; message.&lt;/p&gt;
&lt;p&gt;Now, back to that &amp;ldquo;context&amp;rdquo; value. This is how CM supports multiple Views over the same ViewModel. If a context (typically a string or an enum) is provided, we do a further transformation of the name, based on that value. This transformation effectively assumes you have a folder (namespace) for the different views by removing the word &amp;ldquo;View&amp;rdquo; from the end and appending the context instead. So, given a context of &amp;ldquo;Master&amp;rdquo; our ViewModels.CustomerViewModel would become Views.Customer.Master.&lt;/p&gt;
&lt;h3&gt;Other Things To Know&lt;/h3&gt;
&lt;p&gt;Besides instantiation of your View, GetOrCreateViewType will call InitializeComponent on your View (if it exists). This means that for Views created by the ViewLocator, you don&amp;rsquo;t have to have code-behinds at all. You can delete them if that makes you happy :) You should also know that ViewLocator.LocateForModelType is never called directly. It is always called indirectly through ViewLocator.LocateForModel. LocateForModel takes an instance of your ViewModel and returns an instance of your View. One of the functions of LocateForModel is to inspect your ViewModel to see if it implements IViewAware. If so, it will call it&amp;rsquo;s GetView method to see if you have a cached view or if you are handling View creation explicitly. If not, then it passes your ViewModel&amp;rsquo;s type to LocateForModelType.&lt;/p&gt;
&lt;h3&gt;Customization&lt;/h3&gt;
&lt;p&gt;The out-of-the-box convention is pretty simple and based on a number of patterns we&amp;rsquo;ve used and seen others use in the real world. However, by no means are you limited to these simple patterns. You&amp;rsquo;ll notice that all the methods discussed above are implemented as Funcs rather than actual methods. This means that you can customize them by simply replacing them with your own implementations. If you just want to add to the existing behavior, simply store the existing Func in a variable, create a new Func that calls the old and and assign the new Func to ViewLocator.LocateForModelType.&lt;sup&gt;3&lt;/sup&gt;&lt;/p&gt;
&lt;h3&gt;Framework Usage&lt;/h3&gt;
&lt;p&gt;There are three places that the framework uses the ViewLocator; three places where you can expect the view location conventions to be applied. The first place is in Bootstrapper&amp;lt;T&amp;gt;. Here, your root ViewModel is passed to the locator in order to determine how your application&amp;rsquo;s shell should be rendered.&amp;nbsp; In Silverlight this results in the setting or your RootVisual. In WPF, this creates your MainWindow. In fact, in WPF the bootstrapper delegates this to the WindowManager, which brings me to&amp;hellip; The second place the ViewLocator is used is the WindowManager, which calls it to determine how any dialog ViewModels should be rendered. The third and final place that leverages these conventions is the View.Model attached property. Whenever you do ViewModel-First composition rendering by using the View.Model attached property on a UIElement, the locator is invoked to see how that composed ViewModel should be rendered at that location in the UI. You can use the View.Model attached property explicitly in your UI (optionally combining it with the View.Context attached property for contextual rendering), or it can be added by convention, thus causing conventional composition of views to occur. See the section below on property binding conventions.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;ViewModel Resolution (View-First) &lt;/h2&gt;
&lt;h3&gt;Basics&lt;/h3&gt;
&lt;p&gt;Though Caliburn.Micro prefers ViewModel-First development, there are times when you may want to take a View-First approach, especially when working with WP7. In the case where you start with a view, you will likely then need to resolve a ViewModel. We use a similar naming convention for this scenario as we did with view location. Let&amp;rsquo;s take a look at ViewModelLocator.LocateForViewType:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public static Func&amp;lt;Type, object&amp;gt; LocateForViewType = viewType =&amp;gt;{
    var typeName = viewType.FullName;

    if(!typeName.EndsWith(&amp;quot;View&amp;quot;))
        typeName += &amp;quot;View&amp;quot;;

    var viewModelName = typeName.Replace(&amp;quot;View&amp;quot;, &amp;quot;ViewModel&amp;quot;);
    var key = viewModelName.Substring(viewModelName.LastIndexOf(&amp;quot;.&amp;quot;) + 1);

    return IoC.GetInstance(null, key);
};&lt;/pre&gt;
&lt;p&gt;While with View location we change instances of &amp;ldquo;ViewModel&amp;rdquo; to &amp;ldquo;View&amp;rdquo;, with ViewModel location we change &amp;ldquo;View&amp;rdquo; to &amp;ldquo;ViewModel.&amp;rdquo; The other interesting difference is in how we get the instance of the ViewModel itself. Because your ViewModels may be registered by an interface or a concrete class, we don&amp;rsquo;t pull them from the container by type. Instead we pull them by key, using just the derived name, minus all the namespace stuff.&lt;/p&gt;
&lt;h3&gt;Other Things To Know&lt;/h3&gt;
&lt;p&gt;ViewModelLocator.LocateForViewType is actually never called directly by the framework. It&amp;rsquo;s called internally by ViewModelLocator.LocateForView. LocateForView first checks your View instance&amp;rsquo;s DataContext to see if you&amp;rsquo;ve previous cached or custom created your ViewModel. If the DataContext is null, only then will it call into LocateForViewType. A final thing to note is that automatic InitializeComponent calls are not supported by view first, by its nature.&lt;/p&gt;
&lt;h3&gt;Customization&lt;/h3&gt;
&lt;p&gt;You may not be happy with the way that LocateForViewType retrieves your ViewModel from the IoC container by key. No problem. Simply replace the Func with your own implementation. As you can see, it doesn&amp;rsquo;t really require that much code to map one thing to another.&lt;/p&gt;
&lt;h3&gt;Framework Usage&lt;/h3&gt;
&lt;p&gt;The ViewModelLocator is only used by the WP7 version of the framework. It&amp;rsquo;s used by the FrameAdapter which insures that every time you navigate to a page, it is supplied with the correct ViewModel. It could be easily adapted for use by the Silverlight Navigation Framework if desired.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;ViewModelBinder&lt;/h2&gt;
&lt;h3&gt;Basics&lt;/h3&gt;
&lt;p&gt;When we bind together your View and ViewModel, regardless of whether you use a ViewModel-First or a View-First approach, the ViewModelBinder.Bind method is called. This method sets the Action.Target of the View to the ViewModel and correspondingly sets the DataContext to the same value.&lt;sup&gt;4&lt;/sup&gt; It also checks to see if your ViewModel implements IViewAware, and if so, passes the View to your ViewModel. This allows for a more SupervisingController style design, if that fits your scenario better. The final important thing the ViewModelBinder does is determine if it needs to create any conventional property bindings or actions. To do this, it searches the UI for a list of element candidates for bindings/actions and compares that against the properties and methods of your ViewModel. When a match is found, it creates the binding or the action on your behalf.&lt;/p&gt;
&lt;h3&gt;Other Things To Know&lt;/h3&gt;
&lt;p&gt;On the WP7 platform, if the View you are binding is a PhoneApplicationPage, this service is responsible for wiring up actions to the ApplicationBar&amp;rsquo;s Buttons and Menus. See the &lt;a target="_blank" href="http://caliburnmicro.codeplex.com/wikipage?title=Working%20with%20Windows%20Phone%207&amp;amp;referringTitle=Documentation"&gt;WP7 specific docs&lt;/a&gt; for more information on that.&lt;/p&gt;
&lt;h3&gt;Customization&lt;/h3&gt;
&lt;p&gt;Should you decide that you don&amp;rsquo;t like the behavior of the ViewModelBinder (more details below), it follows the same patterns as the above framework services. It has several Funcs you can replace with your own implementations, such as Bind, BindActions and BindProperties. Probably the most important aspect of customization though, is the ability to turn off the binder&amp;rsquo;s convention features. To do this, set ViewModelBinder.ApplyConventionsByDefault to false. If you want to enable it on a view-by-view basis, you can set the View.ApplyConventions attached property to true on your View. This attached property works both ways. So, if you have conventions on by default, but need to turn them off on a view-by-view basis, you just set this property to false.&lt;/p&gt;
&lt;h3&gt;Framework Usage&lt;/h3&gt;
&lt;p&gt;The ViewModelBinder is used in three places inside of Caliburn.Micro. The first place is inside the implementation of the View.Model attached property. This property takes your ViewModel, locates a view using the ViewLocator and then passes both of them along to the ViewModelBinder. After binding is complete, the View is injected inside the element on which the property is defined. That&amp;rsquo;s the ViewModel-First usage pattern. The second place that uses the ViewModelBinder is inside the implementation of the Bind.Model attached property. This property takes a ViewModel and passes it along with the element on which the property is defined to the ViewModelBinder. In other words, this is View-First, since you have already instantiated the View inline in your Xaml and are then just invoking the binding against a ViewModel. The final place that the ViewModelBinder is used is in the WP7 version of the framework. Inside of the FrameAdapter, when a page is navigated to, the ViewModelLocator is first used to obtain the ViewModel for that page. Then, the ViewModelBinder is uses to connect the ViewModel to the page.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Element Location&lt;/h2&gt;
&lt;h3&gt;Basics&lt;/h3&gt;
&lt;p&gt;Now that you understand the basic role of the ViewModelBinder and where it is used by the framework, I want to dig into the details of how it applies conventions. As mentioned above, the ViewModelBinder &amp;ldquo;searches the UI for a list of &lt;em&gt;element candidates&lt;/em&gt; for bindings/actions and compares that against the properties and methods of your ViewModel.&amp;rdquo; The first step in understanding how this works is knowing how the framework determines which elements in your UI may be candidates for conventions. It does this by using a func on the static ExtensionMethods class called GetNamedElementsInScope.&lt;sup&gt;5&lt;/sup&gt; Basically this method does two things. First, it identifies a scope to search for elements in. This means it walks the tree until it finds a suitable root node, such as a Window, UserControl or element without a parent (indicating that we are inside a DataTemplate). Once it defines the &amp;ldquo;outer&amp;rdquo; borders of the scope, it begins it&amp;rsquo;s second task: locating all elements in that scope that have names. The search is careful to respect an &amp;ldquo;inner&amp;rdquo; scope boundary by not traversing inside of child user controls. The elements that are returned by this function are then used by the ViewModelBinder to apply conventions.&lt;/p&gt;
&lt;h3&gt;Other Things To Know&lt;/h3&gt;
&lt;p&gt;There are a few limitations to what the GetNamedElementsInScope method can accomplish out-of-the-box. It can only search the visual tree, ContentControl.Content and ItemsControl.Items. In WPF, it also searches HeaderContentControl.Header and HeaderedItemsControl.Header. What this means is that things like ContextMenus, Tooltips or anything else that isn&amp;rsquo;t in the visual tree or one of these special locations won&amp;rsquo;t get found when trying to apply conventions.&lt;/p&gt;
&lt;h3&gt;Customization&lt;/h3&gt;
&lt;p&gt;You may not encounter issues related to the above limitations of element location. But if you do, you can easily replace the default implementation with your own. Here&amp;rsquo;s an interesting technique you might choose to use: If the view is a UserControl or Window, instead of walking the tree for elements, use some reflection to discover all private fields that inherit from FrameworkElement. We know that when Xaml files are compiled, a private field is created for everything with an x:Name. Use this to your advantage. You will have to fall back to the existing implementation for DataTemplate UI though. I don&amp;rsquo;t provide this implementation out-of-the-box, because it is not guaranteed to succeed in Silverlight. The reason is due to the fact that Silverlight doesn&amp;rsquo;t allow you to get the value of a private field unless the calling code is the code that defines the field. However, if all of your views are defined in a single assembly, you can easily make the modification I just described by creating your new implementation in the same assembly as the views. Furthermore, if you have a multi-assembly project, you could write a little bit of plumbing code that would allow the GetNamedElementsInScope Func to find the assembly-specific implementation which could actually perform the reflection.&lt;sup&gt;6&lt;/sup&gt;&lt;/p&gt;
&lt;h3&gt;Framework Usage&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve already mentioned that element location occurs when the ViewModelBinder attempts to bind properties or methods by convention. But, there is a second place that uses this functionality: the Parser. Whenever you use Message.Attach and your action contains parameters, the message parser has to find the elements that you are using as parameter inputs. It would seem that we could just do a simple FindName, but FindName is case-sensitive. As a result, we have to use our custom implementation which does a case-insensitive search. This ensures that the same semantics for binding are used in both places.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Action Matching&lt;/h2&gt;
&lt;h3&gt;Basics&lt;/h3&gt;
&lt;p&gt;The next thing the ViewModelBinder does after locating the elements for convention bindings is inspect them for matches to methods on the ViewModel. It does this by using a bit of reflection to get the public methods of the ViewModel. It then loops over them looking for a case-insensitive name match with an element. If a match is found, and there aren&amp;rsquo;t any pre-existing Interaction.Triggers on the element, an action is attached. The check for pre-existing triggers is used to prevent the convention system from creating duplicate actions to what the developer may have explicitly declared in the markup. To be on the safe side, if you have declared any triggers on the matched element, it is skipped.&lt;/p&gt;
&lt;h3&gt;Other Things To Know&lt;/h3&gt;
&lt;p&gt;The conventional actions are created by setting the Message.Attach attached property on the element. Let&amp;rsquo;s look at how that is built up:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;var message = method.Name;
var parameters = method.GetParameters();

if(parameters.Length &amp;gt; 0)
{
    message += &amp;quot;(&amp;quot;;

    foreach(var parameter in parameters)
    {
        var paramName = parameter.Name;
        var specialValue = &amp;quot;$&amp;quot; + paramName.ToLower();

        if(MessageBinder.SpecialValues.Contains(specialValue))
            paramName = specialValue;

        message += paramName + &amp;quot;,&amp;quot;;
    }

    message = message.Remove(message.Length - 1, 1);
    message += &amp;quot;)&amp;quot;;
}

Log.Info(&amp;quot;Added convention action for {0} as {1}.&amp;quot;, method.Name, message);
Message.SetAttach(foundControl, message);&lt;/pre&gt;
&lt;p&gt;As you can see, we build a string representing the message. This string contains only the action part of the message; no event is declared. You can also see that it loops through the parameters of the method so that they are included in the action. If the parameter name is the same as a special parameter value, we make sure to append the &amp;ldquo;$&amp;rdquo; to it so that it will be recognized correctly by the Parser and later by the MessageBinder when the action is invoked.&lt;/p&gt;
&lt;p&gt;When the Message.Attach property is set, the Parser immediately kicks in to convert the string message into some sort of TriggerBase with an associated ActionMessage. Because we don&amp;rsquo;t declare an event as part of the message, the Parser looks up the default Trigger for the type of element that the message is being attached to. For example, if the message was being attached to a Button, then we would get an EventTrigger with it&amp;rsquo;s Event set to Click. This information is configured through the ConventionManager with reasonable defaults out-of-the-box. See the sections on ConventionManager and ElementConventions below for more information on that. The ElementConvention is used to create the Trigger and then the parser converts the action information into an ActionMessage. The two are connected together and then added to the Interaction.Triggers collection of the element.&lt;/p&gt;
&lt;h3&gt;Customization&lt;/h3&gt;
&lt;p&gt;ViewModelBinder.BindActions is a Func and thus can be entirely replaced if desired. Adding to or changing the ElementConventions via the ConventionManager will also effect how actions are put together. More on that below.&lt;/p&gt;
&lt;h3&gt;Framework Usage&lt;/h3&gt;
&lt;p&gt;BindActions is used exclusively by the ViewModelBinder.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Property Matching&lt;/h2&gt;
&lt;h3&gt;Basics&lt;/h3&gt;
&lt;p&gt;Once action binding is complete, we move on to property binding. It follows a similar process by looping through the named elements and looking for case-insensitive name matches on properties. Once a match is found, we then get the ElementConventions from the ConventionManager so we can determine just how databinding on that element should occur. The ElementConvention defines an ApplyBinding Func that takes the view model type, property path, property info, element instance, and the convention itself. This Func is responsible for creating the binding on the element using all the contextual information provided. The neat thing is that we can have custom binding behaviors for each element if we want. CM defines a basic implementation of ApplyBinding for most elements, which lives on the ConventionManager. It&amp;rsquo;s called SetBinding and looks like this:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public static Func&amp;lt;Type, string, PropertyInfo, FrameworkElement, ElementConvention, bool&amp;gt; SetBinding =
    (viewModelType, path, property, element, convention) =&amp;gt; {
        var bindableProperty = convention.GetBindableProperty(element);
        if(HasBinding(element, bindableProperty))
            return false;

        var binding = new Binding(path);

        ApplyBindingMode(binding, property);
        ApplyValueConverter(binding, bindableProperty, property);
        ApplyStringFormat(binding, convention, property);
        ApplyValidation(binding, viewModelType, property);
        ApplyUpdateSourceTrigger(bindableProperty, element, binding);

        BindingOperations.SetBinding(element, bindableProperty, binding);

        return true;
    };&lt;/pre&gt;
&lt;p&gt;The first thing this method does is get the dependency property that should be bound by calling GetBindableProperty on the ElementConvention. Next we check to see if there is already a binding set for that property. If there is, we don&amp;rsquo;t want to overwrite it. The developer is probably doing something special here, so we return false indicating that a binding has not been added. Assuming no binding exists, this method then basically delegates to other methods on the ConventionManager for the details of binding application. Hopefully that part makes sense. Once the binding is fully constructed we add it to the element and return true indicating that the convention was applied.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s another important aspect to property matching that I haven&amp;rsquo;t yet mentioned. We can match on deep property paths by convention as well. So, let&amp;rsquo;s say that you have a Customer property on your ViewModel that has a FirstName property you want to bind a Textbox to. Simply give the TextBox an x:Name of &amp;ldquo;Customer_FirstName&amp;rdquo; The ViewModelBinder will do all the work to make sure that that is a valid property and will pass the correct view model type, property info and property path along to the ElementConvention&amp;rsquo;s ApplyBinding func.&lt;/p&gt;
&lt;h3&gt;Other Things To Know&lt;/h3&gt;
&lt;p&gt;I mentioned above that &amp;ldquo;CM defines a basic implementation of ApplyBinding for most elements.&amp;rdquo; It also defines several custom implementations of the ApplyBinding Func for elements that are typically associated with specific usage patterns or composition. For WPF and Silverlight, there are custom binding behaviors for ItemsControl and Selector. In addition to binding the ItemsSource on an ItemsControl, the ApplyBinding func also inspects the ItemTemplate, DisplayMemberPath and ItemTemplateSelector (WPF) properties. If none of these are set, then the framework knows that since you haven&amp;rsquo;t specified a renderer for the items, it should add one conventionally.&lt;sup&gt;7&lt;/sup&gt; So, we set the ItemTemplate to a default DataTemplate. Here&amp;rsquo;s what it looks like:&lt;/p&gt;
&lt;pre name="code" class="xml:nogutter:nocontrols"&gt;&amp;lt;DataTemplate xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;
              xmlns:cal=&amp;quot;clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro&amp;quot;&amp;gt;
    &amp;lt;ContentControl cal:View.Model=&amp;quot;{Binding}&amp;quot; 
                    VerticalContentAlignment=&amp;quot;Stretch&amp;quot;
                    HorizontalContentAlignment=&amp;quot;Stretch&amp;quot; /&amp;gt;
&amp;lt;/DataTemplate&amp;gt;&lt;/pre&gt;
&lt;p&gt;Since this template creates a ContentControl with a View.Model attached property, we create the possibility of rich composition for ItemsControls. So, whatever the Item is, the View.Model attached property allows us to invoke the ViewModel-First workflow: locate the view for the item, pass the item and the view to the ViewModelBinder (which in turn sets it&amp;rsquo;s own conventions, possibly invoking more composition) and then take the view and inject it into the ContentControl. Selectors have the same behavior as ItemsControls, but with an additional convention around the SelectedItem property. Let&amp;rsquo;s say that your Selector is called Items. We follow the above conventions first by binding ItemsSource to Items and detecting whether or not we need to add a default DataTemplate. Then, we check to see if the SelectedItem property has been bound. If not, we look for three candidate properties on the ViewModel that could be bound to SelectedItem: ActiveItem, SelectedItem and CurrentItem. If we find one of these, we add the binding. So, the pattern here is that we first call ConventionManager.Singularize on the collection property&amp;rsquo;s name. In this case &amp;ldquo;Items&amp;rdquo; becomes &amp;ldquo;Item&amp;rdquo; Then we call ConventionManager.DerivePotentialSelectionNames which prepends &amp;ldquo;Active&amp;rdquo; &amp;ldquo;Selected&amp;rdquo; and &amp;ldquo;Current&amp;rdquo; to &amp;ldquo;Item&amp;rdquo; to make the three candidates above. Then, we create a binding if we find one of these on the ViewModel. For WPF, we have a special ApplyBinding behavior for the TabControl.&lt;sup&gt;8&lt;/sup&gt; It takes on all the conventions of Selector (setting it&amp;rsquo;s ContentTemplate instead of ItemTemplate to the DefaultDataTemplate), plus an additional convention for the tab header&amp;rsquo;s content. If the TabControl&amp;rsquo;s DisplayMemberPath is not set and the ViewModel implements IHaveDisplayName, then we set it&amp;rsquo;s ItemTemplate to the DefaultHeaderTemplate, which looks like this:&lt;/p&gt;
&lt;pre name="code" class="xml:nogutter:nocontrols"&gt;&amp;lt;DataTemplate xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&amp;gt;
    &amp;lt;TextBlock Text=&amp;quot;{Binding DisplayName, Mode=TwoWay}&amp;quot; /&amp;gt;
&amp;lt;/DataTemplate&amp;gt;&lt;/pre&gt;
&lt;p&gt;So, for a named WPF TabControl we can conventionally bind in the list of tabs (ItemsSource), the tab item&amp;rsquo;s name (ItemTemplate), the content for each tab (ContentTemplate) and keep the selected tab synchronized with the model (SelectedItem). That&amp;rsquo;s not bad for one line of Xaml like this:&lt;/p&gt;
&lt;pre name="code" class="xml:nogutter:nocontrols"&gt;&amp;lt;TabControl x:Name=&amp;quot;Items&amp;quot; /&amp;gt;&lt;/pre&gt;
&lt;p&gt;In addition to the special cases listed above, we have one more that is important: ContentControl. In this case, we don&amp;rsquo;t supply a custom ApplyBinding Func, but we do supply a custom GetBindableProperty Func. For ContentControl, when we go to determine which property to bind to, we inspect the ContentTemplate and ContentTemplateSelector (WPF). If they are both null, you haven&amp;rsquo;t specified a renderer for your model. Therefore, we assume that you want to use the ViewModel-First workflow. We implement this by having the GetBindableProperty Func return the View.Model attached property as the property to be bound. In all other cases ContentControl would be bound on the Content property. By selecting the View.Model property in the absence of a ContentTemplate, we enable rich composition.&lt;/p&gt;
&lt;p&gt;I hope you will find that these special cases make sense when you think about them. As always, if you don&amp;rsquo;t like them, you can change them&amp;hellip;&lt;/p&gt;
&lt;h3&gt;Customization&lt;/h3&gt;
&lt;p&gt;As you might imagine, the BindProperties functionality is completely customizable by replacing the Func on the ViewModelBinder. For example, if you like the idea of Action conventions but not Property conventions, you could just replace this Func with one that doesn&amp;rsquo;t do anything. However, it&amp;rsquo;s likely that you will want more fine grained control. Fortunately, nearly every aspect of the ConventionManager or of a particular ElementConvention is customizable. More details about the ConventionManager are below.&lt;/p&gt;
&lt;p&gt;One of the common ways you will configure conventions is by adding new conventions to the system. Most commonly this will be in adding the Silverlight toolkit controls or the WP7 toolkit controls. Here&amp;rsquo;s an example of how you would set up an advanced convention for the WP7 Pivot control which would make it work like the WPF TabControl:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;ConventionManager.AddElementConvention&amp;lt;Pivot&amp;gt;(Pivot.ItemsSourceProperty, &amp;quot;SelectedItem&amp;quot;, &amp;quot;SelectionChanged&amp;quot;).ApplyBinding =
    (viewModelType, path, property, element, convention) =&amp;gt; {
        ConventionManager
            .GetElementConvention(typeof(ItemsControl))
            .ApplyBinding(viewModelType, path, property, element, convention);
        ConventionManager
            .ConfigureSelectedItem(element, Pivot.SelectedItemProperty, viewModelType, path);
        ConventionManager
            .ApplyHeaderTemplate(element, Pivot.HeaderTemplateProperty, viewModelType);
    };&lt;/pre&gt;
&lt;p&gt;Pretty cool?&lt;/p&gt;
&lt;h3&gt;Framework Usage&lt;/h3&gt;
&lt;p&gt;BindProperties is used exclusively by the ViewModelBinder.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;ConventionManager&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;ve read this far, you know that the ConventionManager is leveraged heavily by the Action and Property binding mechanisms. It is the gateway to fine-tuning the majority of the convention behavior in the framework. What follows is a list of the replaceable Funcs and Properties which you can use to customize the conventions of the framework:&lt;/p&gt;
&lt;h3&gt;Properties&lt;/h3&gt;
&lt;p&gt;BooleanToVisibilityConverter &amp;ndash; The default IValueConverter used for converting Boolean to Visibility and back. Used by ApplyValueConverter.&lt;/p&gt;
&lt;p&gt;IncludeStaticProperties - Indicates whether or not static properties should be included during convention name matching. False by default.&lt;/p&gt;
&lt;p&gt;DefaultItemTemplate &amp;ndash; Used when an ItemsControl or ContentControl needs a DataTemplate.&lt;/p&gt;
&lt;p&gt;DefaultHeaderTemplate &amp;ndash; Used by ApplyHeaderTemplate when the TabControl needs a header template.&lt;/p&gt;
&lt;h3&gt;Funcs&lt;/h3&gt;
&lt;p&gt;Singularize &amp;ndash; Turns a word from its plural form to its singular form. The default implementation is really basic and just strips the trailing &amp;lsquo;s&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;DerivePotentialSelectionNames &amp;ndash; Given a base collection name, returns a list of possible property names representing the selection. Uses Singularize.&lt;/p&gt;
&lt;p&gt;SetBinding &amp;ndash; The default implementation of ApplyBinding used by ElementConventions (more info below). Changing this will change how all conventional bindings are applied. Uses the following Funcs internally:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HasBinding - Determines whether a particular dependency property already has a binding on the provided element. If a binding already exists, SetBinding is aborted.&lt;/li&gt;
&lt;li&gt;ApplyBindingMode - Applies the appropriate binding mode to the binding.&lt;/li&gt;
&lt;li&gt;ApplyValidation - Determines whether or not and what type of validation to enable on the binding.&lt;/li&gt;
&lt;li&gt;ApplyValueConverter - Determines whether a value converter is is needed and applies one to the binding. It only checks for BooleanToVisibility conversion by default.&lt;/li&gt;
&lt;li&gt;ApplyStringFormat - Determines whether a custom string format is needed and applies it to the binding. By default, if binding to a DateTime, uses the format &amp;quot;{0:MM/dd/yyyy}&amp;quot;.&lt;/li&gt;
&lt;li&gt;ApplyUpdateSourceTrigger - Determines whether a custom update source trigger should be applied to the binding. For WPF, always sets to UpdateSourceTrigger=PropertyChanged. For Silverlight, calls ApplySilverlightTriggers.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Methods&lt;/h3&gt;
&lt;p&gt;AddElementConvention &amp;ndash; Adds or replaces an ElementConvention.&lt;/p&gt;
&lt;p&gt;GetElementConvention &amp;ndash; Gets the convention for a particular element type. If not found, searches the type hierarchy for a match.&lt;/p&gt;
&lt;p&gt;ConfigureSelectedItem &amp;ndash; Configures the SelectedItem convention on an element.&lt;/p&gt;
&lt;p&gt;ApplyHeaderTemplate &amp;ndash; Applies the header template convention to an element.&lt;/p&gt;
&lt;p&gt;ApplySilverlightTriggers &amp;ndash; For TextBox and PasswordBox, wires the appropriate events to binding updates in order to simulate WPF&amp;rsquo;s UpdateSourceTrigger=PropertyChanged.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;ElementConvention&lt;/h2&gt;
&lt;p&gt;ElementConventions can be added or replaced through ConventionManager.AddElementConvention. But, it&amp;rsquo;s important to know what these conventions are and how they are used throughout the framework. At the very bottom of this article is a code listing showing how all the elements are configured out-of-the-box. Here are the Properties and Funcs of the ElementConvention class with brief explanations:&lt;/p&gt;
&lt;h3&gt;Properties&lt;/h3&gt;
&lt;p&gt;ElementType &amp;ndash; The type of element to which the convention applies.&lt;/p&gt;
&lt;p&gt;ParameterProperty &amp;ndash; When using Message.Attach to declare an action, if a parameter that refers to an element is specified, but the property of that element is not, the ElementConvention will be looked up and the ParameterProperty will be used. For example, if we have this markup:&lt;/p&gt;
&lt;pre name="code" class="xml:nogutter:nocontrols"&gt;&amp;lt;TextBox x:Name=&amp;quot;something&amp;quot; /&amp;gt;
&amp;lt;Button cal:Message.Attach=&amp;quot;MyMethod(something)&amp;quot; /&amp;gt;&lt;/pre&gt;
&lt;p&gt;When the Button&amp;rsquo;s ActionMessage is created, we look up &amp;ldquo;something&amp;rdquo;, which is a TextBox. We get the ElementConvention for TextBox which has its ParameterProperty set to &amp;ldquo;Text.&amp;rdquo; Therefore, we create the parameter for MyMethod from something.Text.&lt;/p&gt;
&lt;h3&gt;Funcs&lt;/h3&gt;
&lt;p&gt;GetBindableProperty &amp;ndash; Gets the property for the element which should be used in convention binding.&lt;/p&gt;
&lt;p&gt;CreateTrigger &amp;ndash; When Message.Attach is used to declare an Action, and the specific event is not specified, the ElementConvention will be looked up and the CreateTrigger Func will be called to create the Interaction.Trigger. For example in the Xaml above, when the ActionMessage is created for the Button, the Button&amp;rsquo;s ElementConvention will be looked up and its CreateTrigger Func will be called. In this case, the ElementConvention returns an EventTrigger configured to use the Click event.&lt;/p&gt;
&lt;p&gt;ApplyBinding &amp;ndash; As described above, when conventional databinding occurs, the element we are binding has its ElementConvention looked up and it&amp;rsquo;s ApplyBinding func is called. By default this just passes through to ConventionManager.SetBinding. But certain elements (see above&amp;hellip;or below) customize this in order to enable more powerful composition scenarios.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Footnotes&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The WindowManager uses the ViewLocator under the covers. It inspects types to see if they are UserControl or Window/ChildWindow. If they are not, it automatically creates a parent Window/ChildWindow. So, you can choose to create your dialog views either as a UserControl or Window/ChildWindow in this particular scenario and the framework will take care of the rest. I typically make views UserControls when I can because that makes them a bit more reusable. &lt;/li&gt;
&lt;li&gt;The bootstrapper is responsible for making sure that your application&amp;rsquo;s assembly is added to the AssemblySource, but you can add any additional assemblies by overriding the Bootstrapper&amp;rsquo;s SelectAssemblies method and returning the full list. You can also add additional assemblies to this collection at any time during application execution. So, if you are dynamically downloading modules that contain more views, you can handle that scenario pretty easily. &lt;/li&gt;
&lt;li&gt;This pattern is borrowed from Javascript and I felt it generally made extensibility simpler for the most common use cases. &lt;/li&gt;
&lt;li&gt;Recall that in Caliburn.Micro DataContext has the purpose of specifying to what instance databinding expressions are resolved and Action.Target specifies the instance that handles an Action. Thus, DataContext and Action.Target are allowed to vary independently of one another. By default, whenever the Action.Target is set, the DataContext is set to the same value though. To change this you can set DataContext explicitly to a different value or more commonly, you can use the Action.TargetWithoutContext attached property to set only the Action.Target without affecting the DataContext. &lt;/li&gt;
&lt;li&gt;GetNamedElementsInScope used to be an extension method. However, it became apparent that developers wanted to customize the implementation. So, I made it into a Func. For lack of a better place to put it, it still lives on the ExtensionMethods class. &lt;/li&gt;
&lt;li&gt;Well, I assume this would work. I haven&amp;rsquo;t actually tried it though. &lt;/li&gt;
&lt;li&gt;If your item is a ValueType or a String we don&amp;rsquo;t generate a default DataTemplate. We assume that you want to use the default ToString rendering that the platform provides.&lt;/li&gt;
&lt;li&gt;We don&amp;rsquo;t have this convention in Silverlight because A. TabControl is not part of the core framework and B. Silverlight&amp;rsquo;s TabControl is broken for databinding and has been for two versions of the framework without a fix. Please vote this issue up &lt;a href="http://silverlight.codeplex.com/workitem/3604"&gt;http://silverlight.codeplex.com/workitem/3604&lt;/a&gt; It was reported about a year and a half ago and is not yet fixed.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Out-Of-The-Box Element Conventions&lt;/h2&gt;
&lt;p&gt;Following is the full code-listing showing how the built-in controls have their ElementConventions configured out-of-the-box:&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;#if SILVERLIGHT
AddElementConvention&amp;lt;HyperlinkButton&amp;gt;(HyperlinkButton.ContentProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Click&amp;quot;);
AddElementConvention&amp;lt;PasswordBox&amp;gt;(PasswordBox.PasswordProperty, &amp;quot;Password&amp;quot;, &amp;quot;PasswordChanged&amp;quot;);
#else
AddElementConvention&amp;lt;PasswordBox&amp;gt;(PasswordBox.DataContextProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;PasswordChanged&amp;quot;);
AddElementConvention&amp;lt;Hyperlink&amp;gt;(Hyperlink.DataContextProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Click&amp;quot;);
AddElementConvention&amp;lt;RichTextBox&amp;gt;(RichTextBox.DataContextProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;TextChanged&amp;quot;);
AddElementConvention&amp;lt;Menu&amp;gt;(Menu.ItemsSourceProperty,&amp;quot;DataContext&amp;quot;, &amp;quot;Click&amp;quot;);
AddElementConvention&amp;lt;MenuItem&amp;gt;(MenuItem.ItemsSourceProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Click&amp;quot;);
AddElementConvention&amp;lt;Label&amp;gt;(Label.ContentProperty, &amp;quot;Content&amp;quot;, &amp;quot;DataContextChanged&amp;quot;);
AddElementConvention&amp;lt;Slider&amp;gt;(Slider.ValueProperty, &amp;quot;Value&amp;quot;, &amp;quot;ValueChanged&amp;quot;);
AddElementConvention&amp;lt;Expander&amp;gt;(Expander.IsExpandedProperty, &amp;quot;IsExpanded&amp;quot;, &amp;quot;Expanded&amp;quot;);
AddElementConvention&amp;lt;StatusBar&amp;gt;(StatusBar.ItemsSourceProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Loaded&amp;quot;);
AddElementConvention&amp;lt;ToolBar&amp;gt;(ToolBar.ItemsSourceProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Loaded&amp;quot;);
AddElementConvention&amp;lt;ToolBarTray&amp;gt;(ToolBarTray.VisibilityProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Loaded&amp;quot;);
AddElementConvention&amp;lt;TreeView&amp;gt;(TreeView.ItemsSourceProperty, &amp;quot;SelectedItem&amp;quot;, &amp;quot;SelectedItemChanged&amp;quot;);
AddElementConvention&amp;lt;TabControl&amp;gt;(TabControl.ItemsSourceProperty, &amp;quot;ItemsSource&amp;quot;, &amp;quot;SelectionChanged&amp;quot;)
    .ApplyBinding = (viewModelType, path, property, element, convention) =&amp;gt; {
        if(!SetBinding(viewModelType, path, property, element, convention))
            return;

        var tabControl = (TabControl)element;
        if(tabControl.ContentTemplate == null &amp;amp;&amp;amp; tabControl.ContentTemplateSelector == null &amp;amp;&amp;amp; property.PropertyType.IsGenericType) {
            var itemType = property.PropertyType.GetGenericArguments().First();
            if(!itemType.IsValueType &amp;amp;&amp;amp; !typeof(string).IsAssignableFrom(itemType))
                tabControl.ContentTemplate = DefaultItemTemplate;
        }

        ConfigureSelectedItem(element, Selector.SelectedItemProperty, viewModelType, path);

        if(string.IsNullOrEmpty(tabControl.DisplayMemberPath))
            ApplyHeaderTemplate(tabControl, TabControl.ItemTemplateProperty, viewModelType);
    };
AddElementConvention&amp;lt;TabItem&amp;gt;(TabItem.ContentProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;DataContextChanged&amp;quot;);
AddElementConvention&amp;lt;Window&amp;gt;(Window.DataContextProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Loaded&amp;quot;);
#endif
AddElementConvention&amp;lt;UserControl&amp;gt;(UserControl.VisibilityProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Loaded&amp;quot;);
AddElementConvention&amp;lt;Image&amp;gt;(Image.SourceProperty, &amp;quot;Source&amp;quot;, &amp;quot;Loaded&amp;quot;);
AddElementConvention&amp;lt;ToggleButton&amp;gt;(ToggleButton.IsCheckedProperty, &amp;quot;IsChecked&amp;quot;, &amp;quot;Click&amp;quot;);
AddElementConvention&amp;lt;ButtonBase&amp;gt;(ButtonBase.ContentProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Click&amp;quot;);
AddElementConvention&amp;lt;TextBox&amp;gt;(TextBox.TextProperty, &amp;quot;Text&amp;quot;, &amp;quot;TextChanged&amp;quot;);
AddElementConvention&amp;lt;TextBlock&amp;gt;(TextBlock.TextProperty, &amp;quot;Text&amp;quot;, &amp;quot;DataContextChanged&amp;quot;);
AddElementConvention&amp;lt;Selector&amp;gt;(Selector.ItemsSourceProperty, &amp;quot;SelectedItem&amp;quot;, &amp;quot;SelectionChanged&amp;quot;)
    .ApplyBinding = (viewModelType, path, property, element, convention) =&amp;gt; {
        if (!SetBinding(viewModelType, path, property, element, convention))
            return;

        ConfigureSelectedItem(element, Selector.SelectedItemProperty,viewModelType, path);
        ConfigureItemsControl((ItemsControl)element, property);
    };
AddElementConvention&amp;lt;ItemsControl&amp;gt;(ItemsControl.ItemsSourceProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Loaded&amp;quot;)
    .ApplyBinding = (viewModelType, path, property, element, convention) =&amp;gt; {
        if (!SetBinding(viewModelType, path, property, element, convention))
            return;

        ConfigureItemsControl((ItemsControl)element, property);
    };
AddElementConvention&amp;lt;ContentControl&amp;gt;(ContentControl.ContentProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Loaded&amp;quot;).GetBindableProperty =
    delegate(DependencyObject foundControl) {
        var element = (ContentControl)foundControl;
#if SILVERLIGHT
        return element.ContentTemplate == null &amp;amp;&amp;amp; !(element.Content is DependencyObject)
            ? View.ModelProperty
            : ContentControl.ContentProperty;
#else
        return element.ContentTemplate == null &amp;amp;&amp;amp; element.ContentTemplateSelector == null &amp;amp;&amp;amp; !(element.Content is DependencyObject)
            ? View.ModelProperty
            : ContentControl.ContentProperty;
#endif
    };
AddElementConvention&amp;lt;Shape&amp;gt;(Shape.VisibilityProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;MouseLeftButtonUp&amp;quot;);
AddElementConvention&amp;lt;FrameworkElement&amp;gt;(FrameworkElement.VisibilityProperty, &amp;quot;DataContext&amp;quot;, &amp;quot;Loaded&amp;quot;);&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=63987" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Tutorial/default.aspx">Tutorial</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn+Micro/default.aspx">Caliburn Micro</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WP7/default.aspx">WP7</category></item></channel></rss>