<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Matt Hidinger</title>
        <link>http://www.matthidinger.com/Default.aspx</link>
        <description>Live like you'll die tomorrow, learn like you'll live forever.</description>
        <language>en-US</language>
        <copyright>Matt Hidinger</copyright>
        <generator>Subtext Version 2.5.1.0</generator>
        <image>
            <title>Matt Hidinger</title>
            <url>http://www.matthidinger.com/images/RSS2Image.gif</url>
            <link>http://www.matthidinger.com/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>Video and code from my Build talk on Sharing Code between Platforms</title>
            <link>http://www.matthidinger.com/archive/2013/07/02/video-and-code-from-my-build-talk-on-sharing-code.aspx</link>
            <description>&lt;p&gt;&lt;img title="buildconf" style="display: none" border="0" alt="buildconf" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/b630e246904a_9C6D/buildconf_thumb.png" /&gt; Last week I had another incredible time at Microsoft’s annual &lt;a href="http://www.buildwindows.com/" target="_blank"&gt;Build conference&lt;/a&gt;. This year was particularly exciting for me, as I was invited to speak about some real-world experience on &lt;a href="http://channel9.msdn.com/Events/Build/2013/2-215" target="_blank"&gt;Building Apps for both Windows and Windows Phone&lt;/a&gt;. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;This talk is all about cutting to the chase: cross-platform development is challenging. It's also increasingly a reality we must accept, embrace, and learn to take advantage of. By demonstrating a "real-world" app designed for Windows and Windows Phone, you will learn six battle-tested techniques for maximizing both code and skill reuse between multiple platforms. &lt;/p&gt; &lt;/blockquote&gt; &lt;iframe style="height: 540px; width: 960px" src="http://channel9.msdn.com/Events/Build/2013/2-215/player?w=960&amp;amp;h=540" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;  &lt;h2&gt;Get the code&lt;/h2&gt;  &lt;p&gt;If you enjoyed the talk and would like to check out the code for the Real-world Stocks apps that were built on stage, use the following Github link:&lt;/p&gt;  &lt;h4&gt;&lt;a title="https://github.com/matthidinger/Build2013RealWorldStocks" href="https://github.com/matthidinger/Build2013RealWorldStocks"&gt;https://github.com/matthidinger/Build2013RealWorldStocks&lt;/a&gt;&lt;/h4&gt;  &lt;p&gt; &lt;/p&gt;  &lt;h2&gt;Introspective&lt;/h2&gt;  &lt;p&gt;This was my first talk at a major conference. It’s funny watching yourself on video for the first time; you certainly observe some habits to work on. I quickly realized that I was pacing a lot in the beginning, but thankfully my clicker started to die early on which virtually tethered me to the podium! &lt;/p&gt;  &lt;p&gt;That said, any other feedback on the presentation would be greatly appreciated! Was the pace ok? I’ve already received feedback that I was both too fast, and too slow, so this will definitely vary depending on one’s own comfort level with the technologies discussed, but I’d love any additional comments.&lt;/p&gt;  &lt;p&gt;Thanks for watching! &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:408489e5-72f2-42d6-a0d4-d188dd1c141b" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/winrt" rel="tag"&gt;winrt&lt;/a&gt;,&lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/wp7" rel="tag"&gt;wp7&lt;/a&gt;,&lt;a href="http://technorati.com/tags/presentations" rel="tag"&gt;presentations&lt;/a&gt;,&lt;a href="http://technorati.com/tags/pcl" rel="tag"&gt;pcl&lt;/a&gt;,&lt;a href="http://technorati.com/tags/xaml" rel="tag"&gt;xaml&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/114.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2013/07/02/video-and-code-from-my-build-talk-on-sharing-code.aspx</guid>
            <pubDate>Tue, 02 Jul 2013 16:40:34 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2013/07/02/video-and-code-from-my-build-talk-on-sharing-code.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/114.aspx</wfw:commentRss>
        </item>
        <item>
            <title>A Windows Phone Developer&amp;rsquo;s take on Xamarin</title>
            <link>http://www.matthidinger.com/archive/2013/04/21/a-windows-phone-developerrsquos-take-on-xamarin.aspx</link>
            <description>&lt;h2&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/378d9bf4981b_91E1/WP_20130416_002_2.jpg"&gt;&lt;img title="WP_20130416_002" align="right" style="border-width: 0px; margin: 0px 0px 6px 6px; height: auto; padding-top: 0px; padding-right: 0px; padding-left: 0px; float: right; display: inline; max-width: 60%; background-image: none;" alt="WP_20130416_002" border="0" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/378d9bf4981b_91E1/WP_20130416_002_thumb.jpg" /&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://xamarin.com/"&gt;Xamarin&lt;/a&gt; is all the rage in mobile development right now. They just threw an &lt;a href="http://xamarin.com/evolve"&gt;amazing conference&lt;/a&gt; in Austin and started trending on Twitter during the opening keynote.&lt;/p&gt;
&lt;p&gt;But I’ve identified myself as a Microsoft platform dev for years now, and Xamarin is all about iOS and Android. Why am I, and more importantly Microsoft, seemingly so interested in this product?&lt;/p&gt;
&lt;h2&gt;Xamarin&lt;/h2&gt;
&lt;p&gt;If you haven’t been following along, Xamarin is a company that is now 22 months old, founded by &lt;a href="https://twitter.com/migueldeicaza"&gt;Miguel de Icaza&lt;/a&gt; and &lt;a href="https://twitter.com/natfriedman"&gt;Nat Friedman&lt;/a&gt;. Their product allows you to develop native iOS and Android apps using the most wonderful language of all time: C#.&lt;/p&gt;
&lt;p&gt;Their toolset, among other things, lets you use Visual Studio to build these apps, offering rich designer experiences, and even let you compile iOS apps using Windows thanks to some neat remoting technology.&lt;/p&gt;
&lt;h2&gt;Evolve Conference&lt;/h2&gt;
&lt;p&gt;Last week they threw their very first conference, and it was a truly impressive feat. A giant stage, exciting keynotes, new product announcements, live recordings of all sessions, and amazing one-on-one support with Xamarin engineers. Oh and one of the most friendly and helpful communities I’ve ever been a part of. &lt;/p&gt;
&lt;p&gt;What more could you ask for? &lt;a href="https://twitter.com/MattHidinger/status/324305594494373888"&gt;Parties&lt;/a&gt;? &lt;a href="https://twitter.com/MattHidinger/status/324380618714644481"&gt;After-parties&lt;/a&gt;? They had those too. &lt;/p&gt;
&lt;h2&gt;The Windows angle&lt;/h2&gt;
&lt;p&gt;Ok so they throw a great conference and have some impressive tooling for building iOS and Android apps. But Microsoft was a platinum sponsor of the Evolve conference. I also ran into 8 or 9 Microsoft employees while there. This puzzled a lot of people. &lt;/p&gt;
&lt;p&gt;Why would Microsoft show interest in a platform designed to sell licenses for developing software on competing platforms?&lt;/p&gt;
&lt;h3&gt;An analogy is in order.&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/378d9bf4981b_91E1/WP_20130416_010_4.jpg"&gt;&lt;img title="WP_20130416_010" align="left" style="margin: 0px 10px 0px 0px; border: 0px currentColor; height: auto; padding-top: 0px; padding-right: 0px; padding-left: 0px; float: left; display: inline; max-width: 40%; background-image: none;" alt="WP_20130416_010" border="0" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/378d9bf4981b_91E1/WP_20130416_010_thumb_1.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Take the image to the left. The bar at the conference was serving cocktails named iOS, Android, and Windows. The drinks were colored according to the platform. It was a fun idea.&lt;/p&gt;
&lt;p&gt;What’s the primary ingredient in all of these drinks? Vodka.&lt;/p&gt;
&lt;h3&gt;The Vodka is Xamarin. The shared language, the shared tools, the shared core.&lt;/h3&gt;
&lt;p&gt;The rest of the drink-specific ingredients? Those are the UX, animations, and native platform APIs. &lt;/p&gt;
&lt;p&gt;If architected properly, as described by a few talks at the conference, these other ingredients can be quite small comparatively. And these ingredients are focused on delighting the user, not porting all of your HTTP interfaces, models, logging, and generic business logic. The fun stuff; not the laborious, time consuming monotony.&lt;/p&gt;
&lt;h3&gt;Windows Phone needs a genuine app infusion. &lt;/h3&gt;
&lt;p&gt;Microsoft has made decent headway getting the “top 50” apps onto the platform. But what about the top 500? What about getting them in a timely manner relative to other platforms? &lt;/p&gt;
&lt;p&gt;The chain reaction the platform needs will start with &lt;em&gt;genuine developer interest&lt;/em&gt;, and without market-share numbers the only business drive to supporting Windows Phone will come from &lt;em&gt;lowering cost and effort&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;Xamarin offers that lower cost/effort. &lt;/h3&gt;
&lt;p&gt;In my humble opinion, Microsoft should be promoting Xamarin developers every chance it gets. &lt;/p&gt;
&lt;p&gt;The more iOS apps written in C#, the more apps can be ported to Windows at a significantly lower cost. The developers will already know the language, they know the IDE, they know the .NET BCL. They most likely just need to learn XAML, and the Windows application lifecycle, which is very similar to the other platforms anyway.&lt;/p&gt;
&lt;h2 style="clear: left;"&gt;It’s a cross-platform world&lt;/h2&gt;
&lt;p&gt;This is obvious to anyone working in the mobile space, but the idea of 95% market-share of a single client-platform is a thing of the past. Rocky Lhotka had a great article on the &lt;a href="http://www.lhotka.net/weblog/FutureOfTheSmartClient.aspx"&gt;future of the smart client&lt;/a&gt; and what this means for developers, although we may differ on which language could take us to that future. &lt;/p&gt;
&lt;p&gt;The one thing we all agree on: this is going to be a fun ride.&lt;/p&gt;
&lt;h3&gt;So let’s all enjoy a xammy whammy&lt;/h3&gt;
&lt;p&gt;I’d like to wrap-up with a special thanks the entire Xamarin community, I met a ton of great people and definitely look forward to seeing everyone next year! And of course a huge thanks to &lt;a href="http://twitter.com/she_travels"&gt;Stephanie Schatz&lt;/a&gt;, &lt;a href="https://twitter.com/epolzin"&gt;Erik Polzin&lt;/a&gt;, and &lt;a href="https://twitter.com/anooj"&gt;Anuj Bhatia&lt;/a&gt; for the warm welcome and great conversations throughout the week.&lt;/p&gt;
&lt;p&gt;See you all at BUILD 2013!&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4af1a740-b713-433f-b236-2c8238d4ee11" style="margin: 0px; padding: 0px; float: none; display: inline;"&gt;Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/wp7"&gt;wp7&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/wp7dev"&gt;wp7dev&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/xamarin"&gt;xamarin&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/xplat"&gt;xplat&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/ios"&gt;ios&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/android"&gt;android&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/113.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2013/04/21/a-windows-phone-developerrsquos-take-on-xamarin.aspx</guid>
            <pubDate>Sun, 21 Apr 2013 17:29:42 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2013/04/21/a-windows-phone-developerrsquos-take-on-xamarin.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/113.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Sharing Code: Windows 8 and Windows Phone</title>
            <link>http://www.matthidinger.com/archive/2012/12/05/sharing-code-windows-8-and-windows-phone.aspx</link>
            <description>&lt;p&gt;I recently had the opportunity to speak at Microsoft’s &lt;a href="http://www.microsoft.com/enterprise/events/theneweraofwork3/#fbid=7bLqKFFM2kc" target="_blank"&gt;New Era of Work&lt;/a&gt; conference in Chicago. Below you’ll find the presentation material, the Real-World Stocks project which demonstrates the principles, and a high-level recap of the lessons learned while practicing the following techniques in actual apps.&lt;/p&gt;  &lt;h2&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/image_8.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/image_thumb_3.png" width="200" height="358" /&gt;&lt;/a&gt; &lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/screenshot_12052012_110659_2.png"&gt;&lt;img title="screenshot_12052012_110659" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="screenshot_12052012_110659" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/screenshot_12052012_110659_thumb.png" width="591" height="357" /&gt;&lt;/a&gt;&lt;/h2&gt;  &lt;h2&gt;Slides&lt;/h2&gt;  &lt;p&gt;A number of slides were provided by Microsoft, and many specifically from &lt;a href="http://twitter.com/matthiasshap" target="_blank"&gt;Matthias Shapiro&lt;/a&gt;. Be sure to check out &lt;a href="http://matthiasshapiro.com/" target="_blank"&gt;his blog&lt;/a&gt; for more excellent Windows Phone articles!&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2" width="783" border="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="212"&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/WP_20121128_001_2.jpg"&gt;&lt;img title="WP_20121128_001" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="WP_20121128_001" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/WP_20121128_001_thumb.jpg" width="201" height="356" /&gt;&lt;/a&gt; &lt;/td&gt;        &lt;td valign="top" width="569"&gt;&lt;iframe height="355" src="https://skydrive.live.com/embed?cid=7B7C1346ED380DA9&amp;amp;resid=7B7C1346ED380DA9%214920&amp;amp;authkey=AMQxDTvr5HKdfNI&amp;amp;em=2" frameborder="0" width="436" scrolling="no"&gt;&lt;/iframe&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt; &lt;/p&gt;  &lt;h2&gt;source&lt;/h2&gt;  &lt;table cellspacing="0" cellpadding="2" border="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="208"&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/image_6.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/image_thumb_2.png" width="202" height="354" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top"&gt;         &lt;p&gt;For this talk I started with my &lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx" target="_blank"&gt;Real-World Stocks Windows Phone&lt;/a&gt; project, extracted the central logic into a Portable Class Library, and used File-Linking to share Controls and Converters between the two projects. &lt;/p&gt;          &lt;p&gt;The full source code for Real-World Stocks can be downloaded at the following link, inside a new folder named &lt;strong&gt;CodeSharingSample&lt;/strong&gt;.&lt;/p&gt;         &lt;a title="http://realworldstocks.codeplex.com/" href="http://realworldstocks.codeplex.com/"&gt;           &lt;br /&gt;&lt;font size="5"&gt;http://realworldstocks.codeplex.com/&lt;/font&gt;&lt;/a&gt;           &lt;br /&gt;          &lt;br /&gt;          &lt;p&gt;           &lt;br /&gt;For my mercurial fans…&lt;/p&gt;          &lt;br /&gt;&lt;font size="5"&gt;hg clone &lt;/font&gt;&lt;font size="5"&gt;https://hg.codeplex.com/realworldstocks&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;br /&gt;  &lt;h2&gt;Recap: the six techniques of sharing&lt;/h2&gt;  &lt;p&gt;Sharing code is getting easier, but like all things, there is no silver bullet. Below are six techniques I’ve used in every app I’ve shared code between -- you will very likely use a combination of all of them in a single solution. &lt;/p&gt;  &lt;h4&gt; &lt;/h4&gt;  &lt;h4&gt;Ctrl-C, Ctrl-V&lt;/h4&gt;  &lt;p&gt;The tried and true technique for sharing code. Simple, elegant, and a potential maintenance nightmare.&lt;/p&gt;  &lt;p&gt;Copy/pasting files is still very useful for sharing some XAML across platforms. It will let you copy the XAML as a starting point, and tweak it to look best on the alternate platform. The obvious trade-off being that these files are no way associated, so any tweaks to the XAML in the future will need to be made in both places.&lt;/p&gt;  &lt;h4&gt; &lt;/h4&gt;  &lt;h4&gt;Linked Files&lt;/h4&gt;  &lt;p&gt;Sometimes you need to share a raw .cs file between projects. You can copy/paste the file or use &lt;em&gt;Add Existing Item, &lt;/em&gt;but this will create a duplicate file on disk, so any changes made in the future will need to be copy/pasted again.&lt;em&gt; &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Linking &lt;/em&gt;source files between projects will come in very handy when you want to share a custom Control, or maybe a handful of custom Converters. Since Linked Files are still the same file on disk, any change made in one will be persisted between all projects. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Pro tip:&lt;/strong&gt; Finally in VS 2012, you can hold the Left-Alt key and drag entire folders between projects… It will Add a Link for every file inside the folder!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/image_13.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/image_thumb_1.png" width="624" height="337" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt; &lt;/h4&gt;  &lt;h4&gt;Linked Files enhanced with #if blocks&lt;/h4&gt;  &lt;p&gt;Sometimes your Linked Files won’t immediately compile on both platforms. &lt;/p&gt;  &lt;p&gt;A very common nuisance is when accessibility modifier are different. For example, sharing a custom Control I wrote for Real-World Stocks: in Silverlight the method signature for &lt;em&gt;OnApplyTemplate&lt;/em&gt;&lt;strong&gt; &lt;/strong&gt;is &lt;em&gt;public; &lt;/em&gt;in Windows it’s marked &lt;em&gt;protected&lt;/em&gt;. To work around this I had to write a rather silly #if block to tweak how this code will be compiled, depending on which platform it’s compiling on.&lt;/p&gt;  &lt;pre class="brush: c-sharp; toolbar: false"&gt;namespace RealWorldStocks.UI.Phone.Controls
{
    [TemplateVisualState(Name = "Positive", GroupName = "PriceStates")]
    [TemplateVisualState(Name = "Negative", GroupName = "PriceStates")]
    public class PriceChangeArrow : Control
    {
        public PriceChangeArrow()
        {
            DefaultStyleKey = typeof (PriceChangeArrow);
        }

#if NETFX_CORE
        protected override void OnApplyTemplate()
#else
        public override void OnApplyTemplate()
#endif
        {
            LayoutUpdated += PriceChangeArrow_LayoutUpdated;
            base.OnApplyTemplate();
        }
    }
}&lt;/pre&gt;

&lt;h4&gt; &lt;/h4&gt;

&lt;h4&gt;Portable Class Libraries (PCLs)&lt;/h4&gt;

&lt;p&gt;When you want to move away from sharing raw source assets you will want to check out PCLs.&lt;/p&gt;

&lt;p&gt;When you Add –&amp;gt; New Project and select a Portable Class Library, you will see the following dialog, allowing you to specify exactly which platforms you’d like to target. IntelliSense and the tooling will only surface APIs which are common across all chosen platforms.&lt;/p&gt;

&lt;p&gt;Your end result is a single project, with a single codebase, &lt;em&gt;outputting a single assembly &lt;/em&gt;(.dll) that is able to be referenced by any of the targeted platforms.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/image_15.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/image_thumb_5.png" width="283" height="276" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h4&gt;A Platform Adapter Abstraction&lt;/h4&gt;

&lt;p&gt;PCLs are excellent tools, but not all .NET APIs are currently available to them. &lt;/p&gt;

&lt;p&gt;Suppose you want to write a shared HTTP stack in your PCL, which will certainly need the ability to do GZip decompression. Unfortunately you realize the PCL has no GZipStream type. To solve this, I create an abstract class named &lt;em&gt;PlatformAdapter&lt;/em&gt;, which has a static property to access the &lt;em&gt;Current &lt;/em&gt;instance. Each platform is then responsible for implementing a concrete platform adapter to provide the implementation &lt;strong&gt;and &lt;/strong&gt;initialize the Current property on startup. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Download the full sample project to see how these pieces fit together.&lt;/em&gt;&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;namespace RealWorldStocks.Core
{
    public abstract class PlatformAdapter
    {
        /// &amp;lt;summary&amp;gt;
        /// Provides acess to the current platform adapter
        /// &amp;lt;/summary&amp;gt;
        public static PlatformAdapter Current { get; set; }


        public abstract string ReadCompressedResponseStream(HttpWebResponse response);
        public abstract void BeginInvoke(Action actionToInvoke);
        public abstract ISettingsStore Settings { get; }
    }
}&lt;/pre&gt;

&lt;h4&gt;
  &lt;br /&gt;Your skills – it’s not always about sharing raw assets&lt;/h4&gt;

&lt;p&gt;Lastly, and arguably the biggest thing worth sharing: your skills. &lt;/p&gt;

&lt;p&gt;You know C#. You know .NET. You know (and love) XAML. These skills will you get a huge head-start, specifically on the XAML stacks. They aren’t 100% identical, as seen above, but the overarching concepts are exactly the same.&lt;/p&gt;

&lt;h3&gt;
  &lt;br /&gt;&lt;/h3&gt;

&lt;h1&gt;Finally, above all else…&lt;/h1&gt;

&lt;h2&gt;Make a great user experience!&lt;/h2&gt;

&lt;p&gt;Sharing code, assets, and skills are all great tools for more efficient software delivery. Just don’t forget that you are creating software for different platforms, and the user should always have the optimal experience on each. Not every screen is going to show the same data, in the same way. 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/image_17.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Sharing-Code-Windows-8-and-Windows-Phone_83EC/image_thumb_6.png" width="787" height="293" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:b5e98c9d-24de-435e-8197-8d4b6d87e63f" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/presentations" rel="tag"&gt;presentations&lt;/a&gt;,&lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/winrt" rel="tag"&gt;winrt&lt;/a&gt;,&lt;a href="http://technorati.com/tags/xaml" rel="tag"&gt;xaml&lt;/a&gt;,&lt;a href="http://technorati.com/tags/pcl" rel="tag"&gt;pcl&lt;/a&gt;,&lt;a href="http://technorati.com/tags/architecture" rel="tag"&gt;architecture&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/112.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2012/12/05/sharing-code-windows-8-and-windows-phone.aspx</guid>
            <pubDate>Wed, 05 Dec 2012 18:26:12 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2012/12/05/sharing-code-windows-8-and-windows-phone.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/112.aspx</wfw:commentRss>
        </item>
        <item>
            <title>How to get the Windows Phone user agent string</title>
            <link>http://www.matthidinger.com/archive/2012/07/05/how-to-get-the-windows-phone-user-agent-string.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/45d9f34867d2_B652/IE_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="IE" border="0" alt="IE" align="right" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/45d9f34867d2_B652/IE_thumb.png" width="194" height="194" /&gt;&lt;/a&gt;On a recent project I needed to extract the &lt;a href="http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx" target="_blank"&gt;windows phone user-agent string&lt;/a&gt; for our usage analytics, and it had to be the same user-agent as the IE requests. While this didn’t end up being as straight forward and I had hoped, the code below involves a few simple steps. First we have to insert a collapsed browser onto the page, then we can navigate it to specifically crafted HTML/JavaScript, which will in-turn notify the WebBrowser control of it’s user-agent. All you need to do is store it somewhere; in my case, I put it into a custom ApplicationSettings class, but you can store it anywhere you want.&lt;/p&gt;  &lt;h3&gt;Usage&lt;/h3&gt;  &lt;p&gt;Since this code requires adding a WebBrowser control to a page, it’s probably easier to do in code-behind as opposed to a view model.&lt;/p&gt;  &lt;pre class="brush: c-sharp; toolbar: false"&gt;public partial class HomeView : PhoneApplicationPage
{
    public HomeView()
    {
        InitializeComponent();
        Loaded += HomeView_Loaded;
    }

    private void HomeView_Loaded(object sender, RoutedEventArgs e)
    {
        UserAgentHelper.GetUserAgent(
            LayoutRoot,
            userAgent =&amp;gt;
                {
                    // TODO: Store this wherever you want
                    ApplicationSettings.Current.UserAgent = userAgent;
                });
    }
}&lt;/pre&gt;

&lt;h3&gt;The Helper&lt;/h3&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public static class UserAgentHelper
{
    private const string Html =
        @"&amp;lt;!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.01 Transitional//EN""&amp;gt;

        &amp;lt;html&amp;gt;
        &amp;lt;head&amp;gt;
        &amp;lt;script language=""javascript"" type=""text/javascript""&amp;gt;
            function notifyUA() {
	            window.external.notify(navigator.userAgent);
            }
        &amp;lt;/script&amp;gt;
        &amp;lt;/head&amp;gt;
        &amp;lt;body onload=""notifyUA();""&amp;gt;&amp;lt;/body&amp;gt;
        &amp;lt;/html&amp;gt;";

    public static void GetUserAgent(Panel rootElement, Action&amp;lt;string&amp;gt; callback)
    {
        var browser = new Microsoft.Phone.Controls.WebBrowser();
        browser.IsScriptEnabled = true;
        browser.Visibility = Visibility.Collapsed;
        browser.Loaded += (sender, args) =&amp;gt; browser.NavigateToString(Html);
        browser.ScriptNotify += (sender, args) =&amp;gt;
                                    {
                                        string userAgent = args.Value;
                                        rootElement.Children.Remove(browser);
                                        callback(userAgent);
                                    };
        rootElement.Children.Add(browser);
    }
}&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:d5548f84-d15a-4ff1-add5-1c2bdee5b7c4" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/wp7" rel="tag"&gt;wp7&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/110.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2012/07/05/how-to-get-the-windows-phone-user-agent-string.aspx</guid>
            <pubDate>Thu, 05 Jul 2012 18:31:50 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2012/07/05/how-to-get-the-windows-phone-user-agent-string.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/110.aspx</wfw:commentRss>
        </item>
        <item>
            <title>A simple IndexingObservableCollection for zebra-striping rows</title>
            <link>http://www.matthidinger.com/archive/2012/07/02/a-simple-indexingobservablecollection-for-zebra-striping-rows.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/58c4cfa70f46_956D/zebra-camo_2.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 10px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="zebra-camo" border="0" alt="zebra-camo" align="right" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/58c4cfa70f46_956D/zebra-camo_thumb.jpg" width="379" height="258" /&gt;&lt;/a&gt;I’m currently wrapping up a Windows Phone project and thought this would be a good time to share some of the more reusable stuff we needed.&lt;/p&gt; &lt;h3&gt;Zebra-striping alternate rows&lt;/h3&gt; &lt;p&gt;This particular app displays a lot of tabular data, so we wanted to zebra-stripe the rows to make them easier to discern. At first we tried using a ValueConverter to get the index of the current container, but this method didn’t end up working with the &lt;a href="http://www.telerik.com/products/windows-phone/overview/all-controls.aspx#databoundlistbox"&gt;Telerik DataBoundListBox&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;Instead, we wrote a simple IndexingObservableCollection that will automatically populate the Index of each item as it’s added to the collection. This method also works with the &lt;a href="http://www.telerik.com/help/windows-phone/raddataboundlistbox-features-datavirtualization-overview.html"&gt;infinite scrolling feature of Telerik’s listbox&lt;/a&gt; – which we actually needed anyway.&lt;/p&gt; &lt;h3&gt;IndexingObservableCollection&lt;/h3&gt; &lt;p&gt;To use it, you have to implement the IIndexable interface which ensure an Index property on your model. Then simply replace the ObservableCollection property on your view-model with the following IndexingObservableCollection.&lt;/p&gt;&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class IndexingObservableCollection&amp;lt;T&amp;gt; : ObservableCollection&amp;lt;T&amp;gt; where T : IIndexable
{
    protected override void InsertItem(int index, T item)
    {
        item.Index = index;
        base.InsertItem(index, item);
    }

    protected override void SetItem(int index, T item)
    {
        item.Index = index;
        base.SetItem(index, item);
    }
}

public interface IIndexable
{
    int Index { get; set; }
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;Tweaking your model&lt;/h3&gt;
&lt;p&gt;Below is a sample model that could be used for displaying a list of products. In this case I’m returning a specific Brush for odd-numbered rows, and the XAML Grid simply binds Background="{Binding Background}"&lt;/p&gt;&lt;pre class="brush: c-sharp; toolbar: false"&gt; &lt;/pre&gt;&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class ProductRow : IIndexable
{
    public int Index { get; set; }

    public string ProductName { get; set; }

    public string Price { get; set; }

    public Brush Background
    {
        get
        {
            return Index % 2 == 1
                    ? new SolidColorBrush(Colors.DarkGray)
                    : new SolidColorBrush(Colors.White);
        }
    }
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:3f11b9de-2309-4d1f-862e-08409a11f433" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/wp7" rel="tag"&gt;wp7&lt;/a&gt;,&lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/xaml" rel="tag"&gt;xaml&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/109.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2012/07/02/a-simple-indexingobservablecollection-for-zebra-striping-rows.aspx</guid>
            <pubDate>Mon, 02 Jul 2012 17:12:30 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2012/07/02/a-simple-indexingobservablecollection-for-zebra-striping-rows.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/109.aspx</wfw:commentRss>
        </item>
        <item>
            <title>WindyCityGo, StirTrek, Windows 8 Anchor</title>
            <link>http://www.matthidinger.com/archive/2012/05/06/windycitygo-stirtrek-windows-8-anchor.aspx</link>
            <description>&lt;h3&gt;This blog is quiet… too quiet.&lt;/h3&gt;  &lt;p&gt;It’s been a busy couple of months since starting at &lt;a href="http://claritycon.com/" target="_blank"&gt;Clarity&lt;/a&gt; in January. PowerPoint, for better or worse, became my after-hours IDE. Below you will find some of the recent talks accompanied by their slides and code. Hopefully I didn’t forget anything, but please shoot me a comment if I did!&lt;/p&gt;  &lt;h3&gt;WindyCityGo&lt;/h3&gt;  &lt;h4&gt;Apr 5 – 6, 2012&lt;/h4&gt;  &lt;p&gt;&lt;a href="http://windycitygo.org/"&gt;WindyCityGo&lt;/a&gt; is a two-day conference in Chicago that covers all things mobile. &lt;/p&gt;  &lt;p&gt;This year they added Windows Phone to their lineup and I was invited to speak on “Real World Windows Phone Development.” My talk covered an intro to metro and supports my &lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx"&gt;tutorial series on building a polished Stocks app for windows phone&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;And now that my speaking gigs are winding down I can finally get back to that series!&lt;/p&gt;  &lt;h4&gt;&lt;font size="5"&gt;&lt;a href="http://realworldstocks.codeplex.com/"&gt;GET THE CODE&lt;/a&gt;&lt;/font&gt;&lt;/h4&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="906"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="410"&gt;         &lt;p&gt;&lt;iframe height="327" src="https://r.office.microsoft.com/r/rlidPowerPointEmbed?p1=1&amp;amp;p2=1&amp;amp;p3=SD7B7C1346ED380DA9!1294&amp;amp;p4=&amp;amp;ak=!AKn0Dd_x5FFBEEM&amp;amp;kip=1" frameborder="0" width="402" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="494"&gt;&lt;a href="http://windycitygo.org/" target="_blank"&gt;&lt;img style="display: inline" alt="" src="https://lh4.googleusercontent.com/-PQvNSqMlV8s/T4_NVSoBhrI/AAAAAAAAORk/twmdX24iHG4/s839/2012_WindyCityGo_0170.jpg" width="486" height="325" /&gt;&lt;/a&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt; &lt;/p&gt;  &lt;h3&gt;Windows 8 Anchor at Navy Pier&lt;/h3&gt;  &lt;h4&gt;Apr 26, 2012&lt;/h4&gt;  &lt;p align="left"&gt;This event was put on by Microsoft to help get our excellent mid-west developers ready for Windows 8.&lt;/p&gt;  &lt;p align="left"&gt;Since Clarity had been using the consumer preview tools to build a few metro-style apps already, &lt;a href="https://twitter.com/#!/eklimcz"&gt;Erik Klimczak&lt;/a&gt; and I were invited to talk about “Windows 8 from the Trenches.” We really wanted to cover our experience from three perspectives: business, design, and development.&lt;/p&gt;  &lt;p align="left"&gt;Overall this was a very exciting event with nearly 400 people eager to see what’s coming with windows 8 and this new metro design language. &lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="807"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="410"&gt;&lt;iframe height="327" src="https://r.office.microsoft.com/r/rlidPowerPointEmbed?p1=1&amp;amp;p2=1&amp;amp;p3=SD7B7C1346ED380DA9!1295&amp;amp;p4=&amp;amp;ak=!AKA0Xvpj9I9aADo&amp;amp;kip=1" frameborder="0" width="402" scrolling="no"&gt;&lt;/iframe&gt;&lt;/td&gt;        &lt;td valign="top" width="395"&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/9e7703fc2670_A43F/eventPics3_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" id="hero" title="eventPics3" border="0" alt="eventPics3" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/9e7703fc2670_A43F/eventPics3_thumb.png" width="387" height="327" /&gt;&lt;/a&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;h3&gt; &lt;/h3&gt;  &lt;h3&gt;StirTrek&lt;/h3&gt;  &lt;h4&gt;May 4, 2012&lt;/h4&gt;  &lt;p&gt;&lt;a href="http://stirtrek.com/"&gt;StirTrek&lt;/a&gt; is one of the coolest conferences I’ve been to so far. My buddy &lt;a href="http://csell.net"&gt;Clark Sell&lt;/a&gt; and I flew out to Columbus for the one-day event that takes place at a movie theater. This was StirTrek’s fourth year and they impressively sold out 1,000 tickets in under 10 minutes. &lt;/p&gt;  &lt;p&gt;My talk was on “WinJS for C# Developers” where I gave a crash course into JavaScript development from a C# perspective. I ended up building a Stocks app on stage, on one of the worst market days in recent memory. It always makes for a good demo to show people how much money they are losing!&lt;/p&gt;  &lt;p&gt;That said, thankfully I did not have to compete with Scott Hansleman in my time slot. My condolences for those who did!&lt;/p&gt;  &lt;h4&gt;&lt;font size="5"&gt;&lt;a href="http://realworldstocks.codeplex.com/"&gt;GET THE CODE&lt;/a&gt;&lt;/font&gt;&lt;/h4&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="866"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="410"&gt;&lt;iframe height="327" src="https://r.office.microsoft.com/r/rlidPowerPointEmbed?p1=1&amp;amp;p2=1&amp;amp;p3=SD7B7C1346ED380DA9!1293&amp;amp;p4=&amp;amp;ak=!AB9ycLVdss_FvYY&amp;amp;kip=1" frameborder="0" width="402" scrolling="no"&gt;&lt;/iframe&gt;&lt;/td&gt;        &lt;td valign="top" width="454"&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/9e7703fc2670_A43F/389594_10150889640849224_546684223_11989723_2067556539_n%5B1%5D_2.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="389594_10150889640849224_546684223_11989723_2067556539_n[1]" border="0" alt="389594_10150889640849224_546684223_11989723_2067556539_n[1]" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/9e7703fc2670_A43F/389594_10150889640849224_546684223_11989723_2067556539_n%5B1%5D_thumb.jpg" width="436" height="327" /&gt;&lt;/a&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;h3&gt; &lt;/h3&gt;  &lt;h3&gt;ThatConference&lt;/h3&gt;  &lt;h4&gt;Aug 13 – 15, 2012&lt;/h4&gt;  &lt;p&gt;&lt;a href="http://www.thatconference.com/?s=badge"&gt;&lt;img style="margin: 0px 10px 0px 0px; display: inline; float: left" border="0" alt="That Conference" align="left" src="http://www.thatconference.com/Images/SiteBadges/440w.jpg?s=badge" width="363" height="248" /&gt;&lt;/a&gt;This one is coming up soon and I’m really pumped for it. Be sure to check it out, registration should open soon!&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Spend &lt;strong&gt;3&lt;/strong&gt; days, with &lt;strong&gt;1000&lt;/strong&gt; of your fellow campers in &lt;strong&gt;125&lt;/strong&gt; sessions geeking out on everything &lt;strong&gt;Mobile, Web&lt;/strong&gt; and &lt;strong&gt;Cloud&lt;/strong&gt; at a giant waterpark.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;With over &lt;a href="http://thatconference.com/Sessions"&gt;125 sessions&lt;/a&gt; to choose from, your head will eventually start to overheat. Cool off in one of the many nearby pools, because unlike your traditional technology conference, you will be camping at a giant indoor waterpark. Be sure to follow us on &lt;a href="http://twitter.com/thatConference/"&gt;twitter&lt;/a&gt; and check us out on &lt;a href="http://facebook.com/thatconference/"&gt;facebook&lt;/a&gt;. Then start practicing your cannon balls. &lt;/p&gt;  &lt;div class="clear"&gt; &lt;/div&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:09219d48-44d7-40a9-8ece-02bd54869524" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/speaking" rel="tag"&gt;speaking&lt;/a&gt;,&lt;a href="http://technorati.com/tags/community" rel="tag"&gt;community&lt;/a&gt;,&lt;a href="http://technorati.com/tags/win8" rel="tag"&gt;win8&lt;/a&gt;,&lt;a href="http://technorati.com/tags/winjs" rel="tag"&gt;winjs&lt;/a&gt;,&lt;a href="http://technorati.com/tags/metro" rel="tag"&gt;metro&lt;/a&gt;,&lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/wp7" rel="tag"&gt;wp7&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/108.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2012/05/06/windycitygo-stirtrek-windows-8-anchor.aspx</guid>
            <pubDate>Sun, 06 May 2012 19:31:29 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2012/05/06/windycitygo-stirtrek-windows-8-anchor.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/108.aspx</wfw:commentRss>
        </item>
        <item>
            <title>A Smarter Infrastructure: Automatically filtering an EF 4.1 DbSet</title>
            <link>http://www.matthidinger.com/archive/2012/01/25/a-smarter-infrastructure-automatically-filtering-an-ef-4-1-dbset.aspx</link>
            <description>&lt;p&gt;If you &lt;strike&gt;drink from the fire hose&lt;/strike&gt; read &lt;a href="http://ayende.com/blog"&gt;Ayende’s blog&lt;/a&gt; you would notice a lot of &lt;a href="http://ayende.com/blog/search?q=repository+pattern"&gt;Anti-Repository talk&lt;/a&gt; over the past couple years – which I fully agree with.&lt;/p&gt;  &lt;p&gt;Back in 2009 he declared &lt;a href="http://ayende.com/blog/3955/repository-is-the-new-singleton"&gt;repository is the new singleton&lt;/a&gt;, stating:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;My current approach for data access now is:&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;When using a database, use NHibernate’s ISession directly &lt;/li&gt;      &lt;li&gt;Encapsulate complex queries into query objects that construct an ICriteria query that I can get and manipulate further &lt;/li&gt;      &lt;li&gt;When using something other than a database, create a DAO for that, respecting the underlying storage implementation &lt;/li&gt;      &lt;li&gt;Don’t try to &lt;a href="http://davybrion.com/blog/2009/04/educate-developers-instead-of-protecting-them/"&gt;protect developers&lt;/a&gt; &lt;/li&gt;   &lt;/ul&gt; &lt;/blockquote&gt;  &lt;p&gt;Naturally he gets a slew of comments asking how he handles certain scenarios without using the repository abstraction. One such question, &lt;a href="http://ayende.com/blog/153702/ask-ayende-handling-filtering"&gt;asked just today is&lt;/a&gt;: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;With regards to my queries against repositories, Matt &lt;a href="http://ayende.com/blog/153058/northwind-starter-kit-review-data-access-review-thoughts?key=852c1fa5de554460b9a8b4fbc2e2843a#comment4"&gt;asks&lt;/a&gt;: &lt;/p&gt;    &lt;p&gt;…if my aggregate root query should exclude entities that have, for example, and IsActive = false flag, I also don't want to repeatedly exclude the IsActive = false entities. Using the repository pattern I can expose my Get method where internally it ALWAYS does this.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Ayende responds by stating that the additional abstraction is not necessary; one can simply rely on making a smarter infrastructure. Since he briefly describes how he would solve it using NHibernate, I figured I would also explain how I solve it using EF 4.1 code-first.&lt;/p&gt;  &lt;h2&gt;A life without repositories&lt;/h2&gt;  &lt;p&gt;Like Ayende, I prefer to access my ORM abstraction directly (NHibernate has &lt;strong&gt;ISession&lt;/strong&gt;; I create a single &lt;strong&gt;IDataContext&lt;/strong&gt;). Rather than having separate Repositories for each aggregate root I am able to access all of them directly from the IDataContext.&lt;/p&gt;  &lt;h3&gt;Using the IDataContext&lt;/h3&gt;  &lt;p&gt;Here is a typical controller with constructor injection to obtain an IDataContext. &lt;/p&gt;  &lt;p&gt;The Categories table has 3 rows in it, but one of them has IsDeleted set to true. If you were to execute the following query, you would see that only 2 of the rows are returned.&lt;/p&gt;  &lt;pre class="brush: c-sharp; toolbar: false"&gt;public class EFController : Controller
{
    private readonly IDataContext _db;

    public EFController(IDataContext db)
    {
        _db = db;
    }

    public ActionResult Index()
    {
        // _db.Categories will only return categories where IsDeleted == false
        var categories = _db.Categories;
        return Content(string.Format("Found {0} active categories", categories.Count()));
    }
}&lt;/pre&gt;

&lt;p&gt;To prove it, here is the SQL Profiler output when I hit the controller from a browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Smarter-Infrastructure-Autom.1-DbContext_AA28/SNAGHTML3d115fad.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="SNAGHTML3d115fad" border="0" alt="SNAGHTML3d115fad" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Smarter-Infrastructure-Autom.1-DbContext_AA28/SNAGHTML3d115fad_thumb.png" width="441" height="370" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Creating the IDataContext&lt;/h3&gt;

&lt;p&gt;Now let me show you what the IDataContext looks like. It’s pretty simple. Each of the properties are of type IDbSet&amp;lt;T&amp;gt; and not IList&amp;lt;T&amp;gt;, which would commonly be found in a repository abstraction. &lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public interface IDataContext
{
    IDbSet&amp;lt;Category&amp;gt; Categories { get; set; }
    IDbSet&amp;lt;Product&amp;gt; Products { get; set; }
}&lt;/pre&gt;

&lt;div class="update"&gt;
  &lt;h4&gt;“OMG you’re spreading EF throughout your entire app!”&lt;/h4&gt;

  &lt;p&gt;IDbSet comes from EntityFramework.dll. This means that anyone who uses the IDataContext will have some (small) knowledge of Entity Framework. Some developers are very concerned over this architectural dependency. &lt;/p&gt;

  &lt;p&gt;My argument is that Entity Framework, like any popular ORM, is &lt;strong&gt;already&lt;/strong&gt; an abstraction over your database. It will take care of translating your needs into the appropriate SQL depending on the underlying store (MSSQL, Oracle, etc). As a firm believer in YAGNI, I highly doubt I will need to swap out my entire data access layer some day down the road, so why should I introduce architectural complexity for something that will very likely never come up? And even if it somehow does, I don’t know of a single instance where an application has been able to seamlessly swap completely different data stores (like going from SQL Server to RavebDB), without redesign, significant code re-write, and re-testing.&lt;/p&gt;
&lt;/div&gt;

&lt;h3&gt;Implementing the IDataContext (and adding filtering into our infrastructure)&lt;/h3&gt;

&lt;p&gt;Below is our concrete data context. It inherits from DbContext (From EF) and implements the interface we created. EF will automatically initialize the DbSet properties for us (as in the case of Products below), but we could also initialize it ourselves (as in the case of Categories).&lt;/p&gt;

&lt;p&gt;Using this &lt;a href="http://stackoverflow.com/questions/5676280/can-a-dbcontext-enforce-a-filter-policy"&gt;answer from StackOverflow&lt;/a&gt; I found a great implementation of IDbSet called &lt;strong&gt;FilteredDbSet&lt;/strong&gt;, which takes an Expression in the constructor to represent a WHERE clause. This WHERE clause will be automatically added to every query against the Categories property (and of course, translated all the way to SQL).&lt;/p&gt;

&lt;p&gt;Since consumers of the IDataContext are only ever working with IDbSet, they have no idea that this automatic filtering is taking place behind the scenes. Hooray: a smarter infrastructure.&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class ECommerceDb : DbContext, IDataContext
{
    public ECommerceDb()
    {
        // Automatically filter out Categories where IsDeleted == false
        Categories = new FilteredDbSet&amp;lt;Category&amp;gt;(this, c =&amp;gt; c.IsDeleted == false);
    }

    public IDbSet&amp;lt;Category&amp;gt; Categories { get; set; }
    public IDbSet&amp;lt;Product&amp;gt; Products { get; set; }
}&lt;/pre&gt;

&lt;h2&gt;What about Unit Testing?&lt;/h2&gt;

&lt;p&gt;Repositories offer a great unit testing abstraction. And so does this design. IDataContext exposes properties of type IDbSet – which is an interface just like IList, and ripe for the mocking!&lt;/p&gt;

&lt;p&gt;Someone has even created a great &lt;strong&gt;InMemoryDbSet&lt;/strong&gt; and added it to NuGet for our consuming pleasure. &lt;/p&gt;

&lt;p&gt;&lt;a title="http://nuget.org/packages/FakeDbSet" href="http://nuget.org/packages/FakeDbSet"&gt;http://nuget.org/packages/FakeDbSet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now it becomes painlessly simple to create a fake IDataContext instance and populate it with InMemoryDbSets just like an in-memory repository would offer.&lt;/p&gt;

&lt;h2&gt;What about accessing the unfiltered set?&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://twitter.com/klabranche"&gt;Kevin LaBranche&lt;/a&gt; asked below how I might handle a scenario where I needed to bypass the filter, such as for reporting. One way to solve this would be to create an Unfiltered extension method which could check if the IDbSet is a FilteredDbSet, and if so, return underlying set instead of the filtered one.&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public static class DbSetHelper
{
    public static IQueryable&amp;lt;TEntity&amp;gt; Unfiltered&amp;lt;TEntity&amp;gt;(this IDbSet&amp;lt;TEntity&amp;gt; set) where TEntity : class
    {
        var filteredDbSet = set as FilteredDbSet&amp;lt;TEntity&amp;gt;;
        return filteredDbSet != null ? filteredDbSet.Unfiltered() : set;
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I also had to add the following method to the FilteredDbSet class&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public IQueryable&amp;lt;TEntity&amp;gt; Unfiltered()
{
    return _set;
}&lt;/pre&gt;

&lt;h4&gt;Which could then be used as follows:&lt;/h4&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public ActionResult Index()
{
    var categories = _db.Categories;
    var unfiltered = _db.Categories.Unfiltered();
    return Content(string.Format("Found {0} active categories. Found {1} total.", categories.Count(), unfiltered.Count()));
}&lt;/pre&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;Like the saying goes: complexity is easy; simplicity is hard.&lt;/p&gt;

&lt;p&gt;Striving for a clean and simple architecture, without needless layers of complexity, is a goal we should all have. Sometimes it makes sense to try and make your infrastructure smarter, instead of adding yet another layer of indirection.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:eb879543-c0c6-4396-b787-f0d5adee790c" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/entity+framework" rel="tag"&gt;entity framework&lt;/a&gt;,&lt;a href="http://technorati.com/tags/architecture" rel="tag"&gt;architecture&lt;/a&gt;,&lt;a href="http://technorati.com/tags/expression+trees" rel="tag"&gt;expression trees&lt;/a&gt;,&lt;a href="http://technorati.com/tags/codefirst" rel="tag"&gt;codefirst&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/106.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2012/01/25/a-smarter-infrastructure-automatically-filtering-an-ef-4-1-dbset.aspx</guid>
            <pubDate>Wed, 25 Jan 2012 20:02:34 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2012/01/25/a-smarter-infrastructure-automatically-filtering-an-ef-4-1-dbset.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/106.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Adding rich Selector support for MVC</title>
            <link>http://www.matthidinger.com/archive/2012/01/23/adding-rich-selector-support-for-mvc.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Adding-really-rich-Selector-support-for-_8379/image_6.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 5px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Adding-really-rich-Selector-support-for-_8379/image_thumb_2.png" width="550" height="480" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;By using the the simple &lt;strong&gt;SelectorAttribute&lt;/strong&gt; and &lt;strong&gt;EditorTemplate&lt;/strong&gt; described in this post, you will get rich support the following very common scenarios (and flip between the various modes with ease):&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Single &lt;/strong&gt;selection from a &lt;strong&gt;Drop Down&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Single &lt;/strong&gt;selection from &lt;strong&gt;Radio Buttons&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Multiple &lt;/strong&gt;selection from &lt;strong&gt;Check Boxes&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Multiple &lt;/strong&gt;selection from a &lt;strong&gt;List Box&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Read-only&lt;/strong&gt; mode combines multiple values into a comma-delimited string &lt;/li&gt; &lt;/ol&gt;  &lt;h2&gt;The Canonical example&lt;/h2&gt;  &lt;p&gt;Say you’re inserting a new Product and need to set the &lt;strong&gt;CategoryId&lt;/strong&gt; property. You make a simple input Model wanting to use EditorFor, but &lt;strong&gt;CategoryId&lt;/strong&gt; gets rendered as a useless textbox. The challenge is:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Retrieving the list of categories to present to the user &lt;/li&gt;    &lt;li&gt;Keeping the selected item(s) in sync with the list of choices &lt;/li&gt; &lt;/ol&gt;  &lt;pre class="brush: c-sharp; toolbar: false"&gt;public class Product
{
    [Required]
    public string Name { get; set; }

    [Required]
    [Display(Name = "Category")]
    public int? CategoryId { get; set; }
}&lt;/pre&gt;

&lt;h3&gt;Enter the SelectorAttribute&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The only change from the model above is the new [CategorySelector] attribute on the property.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;Single Selection vs. Multiple Selection&lt;/h4&gt;

&lt;p&gt;Since the [CategorySelector] was placed on an int? property, the selector will render in Single-select mode (only one int can be stored into the property). If however, it were a List&amp;lt;int?&amp;gt; property, the selector would render in Multi-select mode, allowing the user to choose more than one int value. I personally find this automatic behavior pretty cool and very helpful!&lt;/p&gt;

&lt;h4&gt;The full model&lt;/h4&gt;

&lt;p&gt;The screenshot you saw easier is rendered simply by using following Model and EditorFor. The magic lies in the&lt;strong&gt; [CategorySelector]&lt;/strong&gt; and &lt;strong&gt;[DisplayModeSelector]&lt;/strong&gt; attributes.&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class DisplayModeOptions
{
    public DisplayModeOptions()
    {
        ReadOnly = new List&amp;lt;DisplayMode&amp;gt; { DisplayMode.HomePage, DisplayMode.BrowseOnly};
    }

    [Required]
    [Display(Name = "Category")]
    [CategorySelector]
    public int? CategoryId { get; set; }

    [Required]
    [DisplayModeSelector(BulkSelectionThreshold = 0)]
    public DisplayMode? DropDown { get; set; }

    [Required]
    [DisplayModeSelector]
    public DisplayMode? RadioButtons { get; set; }


    [Required]
    [DisplayModeSelector(BulkSelectionThreshold = 0)]
    public List&amp;lt;DisplayMode&amp;gt; ListBox { get; set; }

    [Required]
    [DisplayModeSelector]
    public List&amp;lt;DisplayMode&amp;gt; CheckBoxes { get; set; }

    [ReadOnly(true)]
    [DisplayModeSelector]
    public List&amp;lt;DisplayMode&amp;gt; ReadOnly { get; set; }
}&lt;/pre&gt;

&lt;h4&gt;The View is nothing more than&lt;/h4&gt;

&lt;pre class="brush: xhtml; toolbar: false"&gt;&amp;lt;form action="" method="post"&amp;gt;
    &amp;lt;div class="two-column"&amp;gt;
        &amp;lt;div class="field-group"&amp;gt;
            &amp;lt;h4&amp;gt;Single Selection&amp;lt;/h4&amp;gt;
            @Html.FullFieldEditor(m =&amp;gt; m.RadioButtons)
            @Html.FullFieldEditor(m =&amp;gt; m.DropDown)
            @Html.FullFieldEditor(m =&amp;gt; m.CategoryId)
        &amp;lt;/div&amp;gt;
        
        &amp;lt;div class="field-group"&amp;gt;
            &amp;lt;h4&amp;gt;Multiple Selection&amp;lt;/h4&amp;gt;
            @Html.FullFieldEditor(m =&amp;gt; m.CheckBoxes)
            @Html.FullFieldEditor(m =&amp;gt; m.ListBox)
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;input type="submit" value="Save"/&amp;gt;
&amp;lt;/form&amp;gt;&lt;/pre&gt;

&lt;h3&gt;Other helpful features&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Respects existing validators like &lt;strong&gt;[Required]&lt;/strong&gt; and shows a nice custom validation UI on failure &lt;/li&gt;

  &lt;li&gt;Customizable &lt;strong&gt;OptionLabel &lt;/strong&gt;(or don’t show one at all) &lt;/li&gt;

  &lt;li&gt;If the &lt;strong&gt;SelectorAttribute&lt;/strong&gt; is placed on an &lt;strong&gt;IEnumerable&lt;/strong&gt; Property it will &lt;strong&gt;automatically&lt;/strong&gt; render in multi-selection mode &lt;em&gt;(notice the difference between the RadioButtons and CheckBoxes property above)&lt;/em&gt; &lt;/li&gt;

  &lt;li&gt;Automatically converts to &lt;strong&gt;bulk items mode&lt;/strong&gt; if the number of choices exceeds your specified threshold. (You wouldn’t really want to show a user 50 checkboxes would you?) &lt;/li&gt;

  &lt;li&gt;A handy enum helper displays the enum values as the choices in the UI &lt;em&gt;(seen below in the DisplayModeSelectorAttribute code)&lt;/em&gt; &lt;/li&gt;

  &lt;li&gt;Of course it retains all user selected values on posts, very common in validation failures &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Creating your own SelectorAttributes&lt;/h3&gt;

&lt;p&gt;You’ll need to create your own SelectorAttributes in order to specify the list of choices that should be displayed to the user.&lt;/p&gt;

&lt;p&gt;The DisplayModeSelector displays all possible choices within an enum. &lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class DisplayModeSelectorAttribute : SelectorAttribute
{
    public override IEnumerable&amp;lt;SelectListItem&amp;gt; GetItems()
    {
        return Selector.GetItemsFromEnum&amp;lt;DisplayMode&amp;gt;();
    }
}&lt;/pre&gt;

&lt;p&gt;The CategorySelector demonstrates how you might access a database to get a list of items dynamically.&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class CategorySelectorAttribute : SelectorAttribute
{
    public CategorySelectorAttribute()
    {
        // The Category selector should always be rendered as a drop down
        BulkSelectionThreshold = 0;
    }

    public override IEnumerable&amp;lt;SelectListItem&amp;gt; GetItems()
    {
        // You could of course get these values from a database, similar to:
        // var dataContext = DependencyResolver.Current.GetService&amp;lt;IDataContext&amp;gt;();

        var categories = new List&amp;lt;Category&amp;gt;
                                {
                                    new Category {Id = 1, Name = "Beverages"},
                                    new Category {Id = 2, Name = "Tools"},
                                    new Category {Id = 3, Name = "Soup"},
                                };
        return Selector.GetItems(categories, m =&amp;gt; m.Id, m =&amp;gt; m.Name);
    }
}&lt;/pre&gt;

&lt;h2&gt;Get the Code!&lt;/h2&gt;

&lt;p&gt;Rather than pasting the full source here, I will be publishing it along with a sample project at &lt;a href="http://mvcgrabbag.codeplex.com"&gt;&lt;strong&gt;http://mvcgrabbag.codeplex.com&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;What you need for Selector support&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;Selectors\Selector.cs &lt;/li&gt;

  &lt;li&gt;Selectors\SelectorAttribute.cs &lt;/li&gt;

  &lt;li&gt;Views\Shared\EditorTemplates\Selector.cshtml &lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;Pull it down locally&lt;/h4&gt;

&lt;p&gt;Using &lt;a href="http://tortoisehg.bitbucket.org/"&gt;&lt;strong&gt;TortoiseHg&lt;/strong&gt;&lt;/a&gt; simply clone the URL: &lt;a href="https://hg01.codeplex.com/mvcgrabbag"&gt;&lt;strong&gt;https://hg01.codeplex.com/mvcgrabbag&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Adding-really-rich-Selector-support-for-_8379/image_8.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Adding-really-rich-Selector-support-for-_8379/image_thumb_3.png" width="602" height="189" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Browse the code&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://mvcgrabbag.codeplex.com/SourceControl/changeset/view/2ea3da6732a6#MvcGrabBag.Web%2fSelectors%2fSelectorAttribute.cs"&gt;&lt;strong&gt;Browse the Selector code, MvcGrabBag.Web/Selectors folder&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:bb0da749-1d9a-4dc1-a39a-d1b3a04bfa8e" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/aspnet+mvc" rel="tag"&gt;aspnet mvc&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/105.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2012/01/23/adding-rich-selector-support-for-mvc.aspx</guid>
            <pubDate>Mon, 23 Jan 2012 21:58:10 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2012/01/23/adding-rich-selector-support-for-mvc.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/105.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Simplifying application caching</title>
            <link>http://www.matthidinger.com/archive/2012/01/13/simplifying-application-caching.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/11fa22879ac6_B1E4/image_thumb%5B4%5D_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 5px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="image_thumb[4]" border="0" alt="image_thumb[4]" align="right" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/11fa22879ac6_B1E4/image_thumb%5B4%5D_thumb.png" width="466" height="404" /&gt;&lt;/a&gt;Many ASP.NET applications utilize the &lt;strong&gt;System.Web.Caching.Cache&lt;/strong&gt; in some way. While it offers a pretty simple Dictionary-like API that your app can start using immediately, I typically create a combined “tell-don’t-ask” wrapper around it – which has some additional architectural benefits as well.&lt;/p&gt;  &lt;h3&gt;Out of the box concerns&lt;/h3&gt;  &lt;p&gt;A very common usage of the Cache API can be seen below, but there are a few initial problems I have with it:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Ugly, non-generic casting &lt;/li&gt;    &lt;li&gt;Manual null checks &lt;/li&gt;    &lt;li&gt;Duplicating the string for the key &lt;/li&gt;    &lt;li&gt;Lots of implementation details sprinkled around &lt;/li&gt;    &lt;li&gt;No out of box way to scope the cache. For example, cache a unique copy of the item for each User &lt;/li&gt; &lt;/ol&gt;  &lt;div class="clear"&gt; &lt;/div&gt;  &lt;pre class="brush: c-sharp; toolbar: false"&gt;public ActionResult Bad()
{
    var firstVisit = HttpContext.Cache.Get("FirstVisit") as DateTime?;
    if(firstVisit == null)
    {
        firstVisit = DateTime.Now;
        HttpContext.Cache.Insert("FirstVisit", firstVisit, null, DateTime.Now.AddMinutes(1), TimeSpan.Zero);
    }

    return View("Index", firstVisit.Value);
}&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;A simple ICache/HttpCache wrapper&lt;/h3&gt;

&lt;p&gt;The wrapper I create is used below. It’s nothing revolutionary, but does try to cut down on the redundancy, while adding a few features as well. The following code functions exactly the same as the code above.&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public ActionResult Index()
{
    var firstVisit = _cache.Get(CacheScope.User, "FirstVisit", TimeSpan.FromMinutes(1), () =&amp;gt; DateTime.Now);
    return View(firstVisit);
}&lt;/pre&gt;

&lt;p&gt;The three biggest changes are:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Implicit generic casting (the Get() method is automatically returning a nice, typed DateTime object because the Func&amp;lt;T&amp;gt; at the end became a Func&amp;lt;DateTime&amp;gt;) &lt;/li&gt;

  &lt;li&gt;Tell-don’t-ask. Instead of asking the cache if it already contains something by checking for null, then creating and adding the new item into the cache, I’d rather just combine these 2 functions and have the cache figure out what it needs to do. The last method parameter is a Func&amp;lt;T&amp;gt; which will be invoked if the item is not already in the cache. &lt;/li&gt;

  &lt;li&gt;Added a CacheScope which allows the developer to cache something application-wide, or for each user individually. &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Architectural advantages&lt;/h3&gt;

&lt;p&gt;Aside from these API usage changes we also get 2 big architectural advantages:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The application can rely on a new ICache interface, which means you can access the cache from a lower, non-web layer without having to reference System.Web &lt;/li&gt;

  &lt;li&gt;The provided implementation of ICache is an HttpCache, which by default uses HttpContext.Current, but provides a nice testability hook to plug in your own mocked HttpContextBase if you want to do some integration testing &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Going the extra mile&lt;/h3&gt;

&lt;p&gt;You may notice that our controller still has intimate knowledge of our caching strategy: duration, scope, the string-based key, etc. This code-duplication lightning-rod could easily be copy-pasted around. One possible way to solve this would be to create something like the following AppCache.&lt;/p&gt;

&lt;h4&gt;A central AppCache&lt;/h4&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;/// &amp;lt;summary&amp;gt;
/// This class demonstrates fully abstracting the details of your caching strategy and could serve as the single entry point for cached data
/// &amp;lt;/summary&amp;gt;
public static class AppCache
{
    public static ICache InternalCache = new HttpCache();

    public static DateTime UsersFirstVisit = InternalCache.Get(CacheScope.User, "FirstVisit", TimeSpan.FromMinutes(1), () =&amp;gt; DateTime.Now);
}&lt;/pre&gt;

&lt;h4&gt;Usage in a Controller&lt;/h4&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public ActionResult FullyAbstracted()
{
    var firstVisit = AppCache.UsersFirstVisit;
    return View("Index", firstVisit);
}&lt;/pre&gt;

&lt;p&gt;Now we are completely free to change the caching strategy of our application in a single place.&lt;/p&gt;

&lt;h2&gt;Get the Code&lt;/h2&gt;

&lt;p&gt;Rather than pasting the full source here, I will be publishing it along with a sample project at &lt;a href="http://mvcgrabbag.codeplex.com"&gt;&lt;strong&gt;http://mvcgrabbag.codeplex.com&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;&lt;a href="http://mvcgrabbag.codeplex.com/SourceControl/changeset/view/2ea3da6732a6#MvcGrabBag.Web%2fCaching%2fHttpCache.cs" target="_blank"&gt;&lt;font style="font-weight: bold"&gt;Browse the HttpCache code, MvcGrabBag.Web/Caching folder&lt;/font&gt;&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:b1212d98-d7fd-44ac-a848-58e56eb44569" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/aspnet+mvc" rel="tag"&gt;aspnet mvc&lt;/a&gt;,&lt;a href="http://technorati.com/tags/caching" rel="tag"&gt;caching&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/104.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2012/01/13/simplifying-application-caching.aspx</guid>
            <pubDate>Fri, 13 Jan 2012 20:40:32 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2012/01/13/simplifying-application-caching.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/104.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Tidy up MVC forms with a simple HtmlFormHelper</title>
            <link>http://www.matthidinger.com/archive/2012/01/10/tidy-up-mvc-forms-with-a-simple-htmlformhelper.aspx</link>
            <description>&lt;p&gt;Many line-of-business applications contain dozens of forms similar to the following, each field consisting of a few common characteristics:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;A Label with the name of the field &lt;/li&gt;    &lt;li&gt;The field editor itself &lt;/li&gt;    &lt;li&gt;Asterisks and special styling for required fields &lt;/li&gt;    &lt;li&gt;A tooltip that can be hovered for a detailed description of the field &lt;/li&gt;    &lt;li&gt;Validation messages if the input is incorrect &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;a href="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/1d7e768239e6_E33C/image_19.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/1d7e768239e6_E33C/image_thumb_8.png" width="698" height="524" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;To achieve this, we can create the following Model&lt;/p&gt;  &lt;pre class="brush: c-sharp; toolbar: false"&gt;public class ProductInput
{
    [HiddenInput(DisplayValue = false)]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    [Display(Description = "A brief description of the product")]
    [DataType(DataType.MultilineText)]
    public string Description { get; set; }


    [Display(Description = "An optional alternate description of the product to display when featured on the home page")]
    [DataType(DataType.MultilineText)]
    public string FeaturedDescription { get; set; }

    [Required]
    public decimal? Price { get; set; }

    [Display(Description = "Price of the product during a sale")]
    public decimal? SalePrice { get; set; }
}&lt;/pre&gt;

&lt;p&gt;However, when it comes to actually rendering the view,  many MVC forms contain some variation of the following pattern, &lt;em&gt;repeated over and over for every single field.&lt;/em&gt;&lt;/p&gt;

&lt;pre class="brush: xhtml; toolbar: false"&gt;&amp;lt;div class="field-wrapper"&amp;gt;
    &amp;lt;div class="field-label"&amp;gt;
        @Html.LabelFor(m =&amp;gt; m.Name)
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="field-input"&amp;gt;
        @Html.EditorFor(m =&amp;gt; m.Name)
        @Html.TooltipFor(m =&amp;gt; m.Name)
        @Html.ValidationMessageFor(m =&amp;gt; m.Name)
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;

&lt;p&gt;While this pattern certainly takes advantage of great MVC functionality like Editor Templates and strongly-typed inputs, it’s clear that this template is going to be pasted all over the application, with a quick rename on the property being rendered. Unfortunately this type of duplication creates 2 distinct problems:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Immediately, it offers no way of styling required fields differently (like adding an asterisk or bolding labels) &lt;/li&gt;

  &lt;li&gt;It becomes very time consuming to handle a business request like “Please move the tooltip icon before the textboxes instead of after” &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To solve this, I use a very simple HtmlFormHelper called FullFieldEditor, which renders the exact same HTML described above, but allows me to easily re-style it in a single place. &lt;/p&gt;

&lt;p&gt;The entire View in the screenshot above consists of the following:&lt;/p&gt;

&lt;pre class="brush: xhtml; toolbar: false"&gt;&amp;lt;form action="" method="post"&amp;gt;
    &amp;lt;div class="two-column"&amp;gt;
    
        &amp;lt;div class="field-group"&amp;gt;
            @Html.FullFieldEditor(m =&amp;gt; m.Id)
            @Html.FullFieldEditor(m =&amp;gt; m.Name)
            @Html.FullFieldEditor(m =&amp;gt; m.Price)
            @Html.FullFieldEditor(m =&amp;gt; m.Description)
        &amp;lt;/div&amp;gt;
        
        &amp;lt;div class="field-group"&amp;gt;
            @Html.FullFieldEditor(m =&amp;gt; m.SalePrice)
            @Html.FullFieldEditor(m =&amp;gt; m.FeaturedDescription)
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    
    &amp;lt;div class="clear-fix"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;input type="submit" value="Save"/&amp;gt;
&amp;lt;/form&amp;gt;&lt;/pre&gt;

&lt;h3&gt;Source Code&lt;/h3&gt;

&lt;p&gt;Rather than pasting the full source here, I will be publishing it along with a sample project at &lt;a href="http://mvcgrabbag.codeplex.com"&gt;http://mvcgrabbag.codeplex.com&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;&lt;a title="HtmlFormHelper.cs" href="http://mvcgrabbag.codeplex.com/SourceControl/changeset/view/dee469477184#MvcGrabBag.Web%2fHelpers%2fHtmlFormHelper.cs"&gt;View the full HtmlFormHelper.cs&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:62dbc48a-4cbf-45a0-9163-e8a35a83038f" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/aspnet+mvc" rel="tag"&gt;aspnet mvc&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/103.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2012/01/10/tidy-up-mvc-forms-with-a-simple-htmlformhelper.aspx</guid>
            <pubDate>Tue, 10 Jan 2012 16:12:53 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2012/01/10/tidy-up-mvc-forms-with-a-simple-htmlformhelper.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/103.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Want to be a great architect? Then you&amp;rsquo;ll need to be a great salesman</title>
            <link>http://www.matthidinger.com/archive/2011/12/16/want-to-be-a-great-architect-then-yoursquoll-need-to.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Want-to-be-a-great-architect-be-a-great-_860E/vincefromshamwow_2.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 5px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="vincefromshamwow" border="0" alt="vincefromshamwow" align="right" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Want-to-be-a-great-architect-be-a-great-_860E/vincefromshamwow_thumb.jpg" width="292" height="299" /&gt;&lt;/a&gt;The title is slightly tongue-in-cheek, but I do believe selling is a crucial aspect of being an ‘architect.’ And I don’t mean selling to customers.&lt;/p&gt;  &lt;h2&gt;But first, a backstory&lt;/h2&gt;  &lt;p&gt;A long time ago, at a client far, far away… they were making a big push to SOA. My project at the time was calling a few methods from a referenced assembly, but the client’s architect said I must re-write it using their new WCF endpoint instead. I had my reservations about this change because the services so far were not known to be stable nor discoverable. Now I am certainly no expert at applying SOA, but I do appreciate that it consists of more than simply exposing everything through web services. &lt;/p&gt;  &lt;p&gt;In my mind, before even &lt;em&gt;attempting&lt;/em&gt; to impose an SOA mandate across an enterprise you must establish some baseline infrastructure:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;A &lt;strong&gt;central service registry &lt;/strong&gt;that lists all available services and their endpoints for various configurations (Integration, QA, Prod) &lt;/li&gt;    &lt;li&gt;A &lt;strong&gt;heartbeat service &lt;/strong&gt;monitoring each endpoint so developers don’t waste time relying on a specific service that isn’t available &lt;/li&gt;    &lt;li&gt;An enforced protocol that all &lt;strong&gt;developers must list any new services on the registry &lt;/strong&gt;and ensure that heartbeats are setup before signing off &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Of course this list is not exhaustive nor even proposed solutions – but they are a few concerns I had during my re-write. The endpoint I was given was under active development and highly unstable; while the referenced assembly I used was rock solid and had existed for years. A lot of time and money were wasted throughout this process. While I can absolutely appreciate the need for standardization, this felt a lot like putting the cart before the horse: the necessary baseline components to make this SOA transition even remotely efficient had not been established. As I was starting to raise these concerns up the chain, I got…&lt;/p&gt;  &lt;h4&gt;The No-Time Justification&lt;/h4&gt;  &lt;p&gt;[While this story is purely anecdotal I want to be perfectly clear that the subsequent dialog is hearsay, although we’ve all no doubt been in similar situations.] &lt;/p&gt;  &lt;p&gt;I started discussing these concerns with a coworker, and he assured me that the architect is aware of the problems. So the story goes, &lt;strong&gt;he was not given the time nor resources to have his plan fully executed&lt;/strong&gt;. Of course I can appreciate that sometimes there really is no time, but converting an enterprise to SOA should not be some snap decision made without careful consideration. &lt;/p&gt;  &lt;p&gt;One could argue that the wasted effort these teams were suffering is the fault of management not allocating the proper resources, &lt;strong&gt;but perhaps some of the fault lies on not effectively selling the importance of this plan to management.&lt;/strong&gt;&lt;/p&gt;  &lt;h2&gt;Sell your plan&lt;/h2&gt;  &lt;p&gt;In my mind being an architect (or team lead, or technical lead, or whatever your title may be) is not only about coming up with a plan, but being able to sell that plan to peers and as well as superiors. &lt;/p&gt;  &lt;h4&gt;Sell your plan to management&lt;/h4&gt;  &lt;p&gt;As in the anecdote above, the time will come when you may need extra time or resources to execute your plan. This means preparing for a certain kind of debate: a targeted discussion with people concerned with budgets and finances, not curly braces and semi-colons. This means preparing a cost/benefit analysis if applicable: &lt;strong&gt;doing this will save us X time or money, failing to do so will cost us X over Y months until corrected&lt;/strong&gt;. You must be able to articulate clearly that this is not some grandiose gold-plating pie-in-the-sky need. If it’s important and will reduce developer friction while saving the company money then be prepared to argue that effectively. &lt;/p&gt;  &lt;h4&gt;Sell your plan to the team&lt;/h4&gt;  &lt;p&gt;It’s equally important to get your team on board. Don’t be an &lt;a href="http://igloocoder.com/archive/2009/04/01/ivory-tower-architect.aspx" target="_blank"&gt;Ivory Tower Architect&lt;/a&gt;. You are still a part of the team (or many teams). Don’t just swoop into meetings, impose your will, and avoid implementing the architecture you’ve laid out. Let your team contribute to the discussion and decisions; you are not infallible. This means being able to address concerns directly and intelligently, &lt;strong&gt;especially when they don’t align with your beliefs.&lt;/strong&gt; This means proving that you have considered alternatives and are prepared to have a rational debate on them. This also means having at least cursory knowledge of a number of technologies, patterns, strategies, and platforms. &lt;/p&gt;  &lt;p&gt;I understand at the end of the day work needs to get done and us technologists can debate for weeks on something as simple as Hungarian notation, so you’ll still need to use your best judgment when a topic should be put to rest and the team needs to move on.&lt;/p&gt;  &lt;h4&gt;Sell your plan in terms your audience can understand&lt;/h4&gt;  &lt;p&gt;Did you notice the huge differences between the two types of meetings above? It’s important to prepare the correct type of material tailored for the audience at hand. &lt;/p&gt;  &lt;p&gt;Which brings me to…&lt;/p&gt;  &lt;h2&gt;My advice: Public Speaking&lt;/h2&gt;  &lt;p&gt;I can say without a doubt the largest contributors to my professional growth have come from blogging and speaking. If you’re up for it, I highly recommend giving it a shot because…&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;It builds confidence by putting your material and yourself out there.&lt;/strong&gt; It’s no secret that being confident in what you’re selling makes it exponentially easier. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;It forces you to truly prepare and attempt to master subject material. &lt;/strong&gt;Hopefully this also means diving into alternative solutions, to ensure that you have indeed made the best possible decision at the time. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;It forces you to answer questions on the spot, in front of an audience. &lt;/strong&gt;These are the very same types of questions you’ll get from your team and your management. “Because I say so” isn’t going to fly during a talk, and it shouldn’t fly in a meeting at work. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Since I’m absolutely no expert at public speaking, if it’s something you’re interested in then you should definitely check out this TekPub production: &lt;/p&gt;  &lt;h4&gt;&lt;a title="http://tekpub.com/hanselman" href="http://tekpub.com/hanselman"&gt;The Art of Speaking: Scott Hanselman&lt;/a&gt;&lt;/h4&gt;  &lt;h2&gt;Summary&lt;/h2&gt;  &lt;p&gt;I don’t often write opinion pieces on this blog, mostly because I am still learning every day, and will probably look back on this post a year from now and think these are absurd suggestions. In any event, the following Five Whys blog has some pretty helpful advice, and the book Code Leader I read a few years ago had some nice insight for an aspiring tech lead like myself.&lt;/p&gt;  &lt;p&gt;Blog: &lt;a title="http://5whys.com/" href="http://5whys.com/"&gt;Five Whys - Team Leadership&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Book: &lt;a title="http://www.amazon.com/Code-Leader-Processes-Successful-Programmer/dp/0470259248" href="http://www.amazon.com/Code-Leader-Processes-Successful-Programmer/dp/0470259248"&gt;Code Leader: Using People, Tools, and Processes to Build Successful Software&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:5307f5d3-95f3-40cb-815d-5f32fd8f167c" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/opinions" rel="tag"&gt;opinions&lt;/a&gt;,&lt;a href="http://technorati.com/tags/speaking" rel="tag"&gt;speaking&lt;/a&gt;,&lt;a href="http://technorati.com/tags/career" rel="tag"&gt;career&lt;/a&gt;,&lt;a href="http://technorati.com/tags/architecture" rel="tag"&gt;architecture&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/101.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/12/16/want-to-be-a-great-architect-then-yoursquoll-need-to.aspx</guid>
            <pubDate>Fri, 16 Dec 2011 20:25:46 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/12/16/want-to-be-a-great-architect-then-yoursquoll-need-to.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/101.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Tweaking Subtext with Hero Shots next to each post</title>
            <link>http://www.matthidinger.com/archive/2011/12/12/tweaking-subtext-with-hero-shots-next-to-each-post.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Modify_8E10/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 5px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Modify_8E10/image_thumb_1.png" width="339" height="300" /&gt;&lt;/a&gt;This past weekend I decided to upgrade my Subtext blog to VS 2010 so I could finally rid my machine of VS 2008. After some small hiccups it was ready to rock, and thankfully the deployment to my server was entirely painless with WebDeploy.&lt;/p&gt;  &lt;p&gt;So being in VS 2010 and having fully tested my deployment process it seemed like a good time to make a tweak to my Skin that I’ve been wanting to try for a while: showing “Hero Shots” next to each post. &lt;/p&gt;  &lt;h2&gt;Hero shots?&lt;/h2&gt;  &lt;p&gt;I’m not really sure what they should be called, I just know I’ve heard the term hero shot a lot this year and it seemed to fit, but call it whatever you want &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Modify_8E10/wlEmoticon-winkingsmile_2.png" /&gt;&lt;/p&gt;  &lt;p&gt;The idea is pretty simple: when viewing a list of posts (the home page, a specific tag, the archives) I want to show an image that helps illustrate the topic and allow for easier scanning with the eye. &lt;/p&gt;  &lt;p&gt;As for implementation I wanted to allow some basic configuration of the hero shot from within Live Writer (or whatever you use to author posts). It goes something like this:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Find an &amp;lt;img id=”hero” /&amp;gt; within each post and if found, float it inline with the PostText &lt;/li&gt;    &lt;li&gt;If no images have that ID, then grab the first &amp;lt;img/&amp;gt; and float it inline with the PostText &lt;/li&gt;    &lt;li&gt;If I want to entirely disable a Hero Shot for a post then I just add a &amp;lt;div id=”no-hero” /&amp;gt; into the post body &lt;/li&gt; &lt;/ol&gt;  &lt;h2&gt;Cool, what’s the tweak?&lt;/h2&gt;  &lt;p&gt;First I used NuGet to get HtmlAgilityPack – the absolute best way to work with an HTML string.&lt;/p&gt;  &lt;h4&gt;Install-Package HtmlAgilityPack&lt;/h4&gt;  &lt;p&gt;With that installed the change to Subtext was actually really simple. Within EntryList.cs I found where it was binding the Post Text and added the BindHeroShot() method seen below. BindHeroShot encapsulates that logic described above. The code below will respect Skins which do not use the PostImage, so this change should not affect any themes without a PostImage control declared.&lt;/p&gt;  &lt;h4&gt;Subtext.Web\UI\Controls\EntryList.cs&lt;/h4&gt;  &lt;pre class="brush: c-sharp; toolbar: false; highlight: 3"&gt;private void BindPostText(RepeaterItemEventArgs e, Entry entry)
{
    BindHeroShot(e, entry);

    var postText = (Literal)e.Item.FindControl("PostText");

    if(DescriptionOnly)
    {
        postText.Text = entry.HasDescription
                ? string.Format(CultureInfo.InvariantCulture, "&amp;lt;p&amp;gt;{0}&amp;lt;/p&amp;gt;", entry.Description)
                : ShowTruncatedBody(entry, 150);
    }
    else
    {
        postText.Text = entry.HasDescription ? entry.Description : entry.Body;
    }
}


/// &amp;lt;summary&amp;gt;
///  Get the first image in a post to use as the "Hero Shot" on the list of entries
/// &amp;lt;/summary&amp;gt;
private static void BindHeroShot(RepeaterItemEventArgs e, Entry entry)
{
    var postImage = e.Item.FindControl("PostImage") as System.Web.UI.WebControls.Image;
    if (postImage != null)
    {
        postImage.Visible = false;

        var html = new HtmlDocument();
        html.LoadHtml(entry.Body);

        var noHero = html.DocumentNode.SelectSingleNode("//div[@id='no-hero']");
        if (noHero != null)
            return;

        var img = html.DocumentNode.SelectSingleNode("//img[@id='hero']")
                  ?? html.DocumentNode.SelectSingleNode("//img");
                
        if (img != null)
        {
            postImage.Visible = true;
            postImage.ImageUrl = HttpUtility.HtmlDecode(img.Attributes["src"].Value);
        }
    }
}&lt;/pre&gt;

&lt;p&gt;That’s actually all that had to be changed in Subtext. The rest of the changes take place in your current Skin. &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h4&gt;Subtext.Web\Skins\{YourSkin}\EntryList.ascx&lt;/h4&gt;

&lt;p&gt;Below is the Repeater which shows each Post, the only thing I added to it was an &lt;strong&gt;&amp;lt;asp:Image ID=”PostImage”/&amp;gt;&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="brush: xhtml; toolbar: false; highlight: [9]"&gt;&amp;lt;asp:Repeater runat="server" ID="Entries" OnItemCreated="PostCreated"&amp;gt;
    &amp;lt;ItemTemplate&amp;gt;
        &amp;lt;div class="post"&amp;gt;
            &amp;lt;div class="title"&amp;gt;
                &amp;lt;asp:HyperLink runat="server" ID="TitleUrl" /&amp;gt;
                &amp;lt;asp:HyperLink runat="server" ID="editLink" /&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="body"&amp;gt;
                &amp;lt;asp:Image runat="server" ID="PostImage" CssClass="post-hero-image" /&amp;gt;
                &amp;lt;asp:Literal runat="server" ID="PostText" /&amp;gt;
                &amp;lt;div class="clear"&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/ItemTemplate&amp;gt;
&amp;lt;/asp:Repeater&amp;gt;&lt;/pre&gt;

&lt;h4&gt;Subtext.Web\Skins\{YourSkin}\style.css&lt;/h4&gt;

&lt;p&gt;Naturally I gave the PostImage a CSS Class so I could style it. I chose to float it right and give it max height and widths so it doesn’t take up the entire post. You can of course tweak this any way you like – this part is entirely in your skin. Put the image wherever and style it how you like.&lt;/p&gt;

&lt;pre class="brush: css; toolbar: false"&gt;.post-hero-image
{
    float: right;
    margin: 0 0 6px 10px;
    max-height: 200px;
    max-width: 400px;
}&lt;/pre&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;All in all pretty small tweaks and I actually like how it turned out. I think images next to the posts make it a lot easier to scan topics as I’m scrolling down the page. If you agree and are using Subtext then hopefully this post will make it easy to add to your blog! &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:6ee8fe3a-f247-40dd-9518-d7702bedb28c" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/subtext" rel="tag"&gt;subtext&lt;/a&gt;,&lt;a href="http://technorati.com/tags/open+source" rel="tag"&gt;open source&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/100.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/12/12/tweaking-subtext-with-hero-shots-next-to-each-post.aspx</guid>
            <pubDate>Mon, 12 Dec 2011 17:02:17 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/12/12/tweaking-subtext-with-hero-shots-next-to-each-post.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/100.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Transform your LINQ queries into Excel/PDF reports with DoddleReport 1.2</title>
            <link>http://www.matthidinger.com/archive/2011/12/07/Transform-your-LINQ-queries-into-ExcelPDF-reports-with-DoddleReport-1.aspx</link>
            <description>&lt;blockquote&gt;   &lt;p&gt;DoddleReport generates tabular reports from any IEnumerable datasource. Out of the box it can render reports to Excel, PDF, HTML, and CSV – fully pluggable of course. I created the project to provide reporting output over the LINQ queries we had already written for an application, but maybe you can find other uses for it. &lt;/p&gt; &lt;/blockquote&gt;  &lt;h2&gt;So what does it generate?&lt;/h2&gt;  &lt;p&gt;&lt;em&gt;The following samples are generated live in real-time (notice the data will change every time you open the report)&lt;/em&gt;&lt;/p&gt;  &lt;table style="border-collapse: collapse" border="0" cellspacing="0" cellpadding="2" width="800"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="399"&gt;         &lt;h3&gt;Excel Report (OpenXML)&lt;/h3&gt;          &lt;ul&gt;           &lt;li&gt;Creates a native Excel file using OpenXML &lt;/li&gt;            &lt;li&gt;Requires the DoddleReport.OpenXml package &lt;/li&gt;            &lt;li&gt;&lt;a href="http://doddle.matthidinger.com/Reporting/home/productreport.xlsx" target="_blank"&gt;&lt;strong&gt;See it live!&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt;         &lt;/ul&gt;       &lt;/td&gt;        &lt;td valign="top" width="399"&gt;         &lt;h3&gt;Excel Report (HTML)&lt;/h3&gt;          &lt;ul&gt;           &lt;li&gt;Creates an Excel file using HTML (downside being an Excel security prompt when opening the report) &lt;/li&gt;            &lt;li&gt;Automatic Sticky/Frozen Headers stay at the top when scrolling through the data &lt;/li&gt;            &lt;li&gt;&lt;strong&gt;&lt;a href="http://doddle.matthidinger.com/Reporting/home/productreport.xls" target="_blank"&gt;See it live!&lt;/a&gt;&lt;/strong&gt; &lt;/li&gt;         &lt;/ul&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="399"&gt;         &lt;p&gt;&lt;a href="http://download.codeplex.com/download?ProjectName=doddlereport&amp;amp;DownloadId=204392"&gt;&lt;img style="border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="doddlexlsreport" border="0" alt="doddlexlsreport" src="http://download.codeplex.com/download?ProjectName=doddlereport&amp;amp;DownloadId=204393" width="300" height="211" /&gt;&lt;/a&gt;             &lt;br /&gt;            &lt;br /&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="399"&gt;         &lt;p&gt;&lt;a href="http://download.codeplex.com/download?ProjectName=doddlereport&amp;amp;DownloadId=204392"&gt;&lt;img style="border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="doddlexlsreport" border="0" alt="doddlexlsreport" src="http://download.codeplex.com/download?ProjectName=doddlereport&amp;amp;DownloadId=204393" width="300" height="211" /&gt;&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="399"&gt;         &lt;h3&gt;PDF Report (iTextSharp)&lt;/h3&gt;          &lt;ul&gt;           &lt;li&gt;Automatically repeats title and column headers numbers on every page &lt;/li&gt;            &lt;li&gt;Requires the DoddleReport.iTextSharp package &lt;/li&gt;            &lt;li&gt;&lt;a href="http://doddle.matthidinger.com/Reporting/home/productreport.pdf" target="_blank"&gt;&lt;strong&gt;See it live!&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt;         &lt;/ul&gt;          &lt;h3 /&gt;       &lt;/td&gt;        &lt;td valign="top" width="399"&gt;         &lt;h3&gt;PDF Report (ABCpdf)&lt;/h3&gt;          &lt;ul&gt;           &lt;li&gt;Automatically repeats title, column headers, and page numbers on every page &lt;/li&gt;            &lt;li&gt;Requires the DoddleReport.AbcPdf package &lt;/li&gt;            &lt;li&gt;&lt;em&gt;Requires an &lt;/em&gt;&lt;a href="http://www.websupergoo.com/products.htm#pd" target="_blank"&gt;&lt;em&gt;ABCpdf license&lt;/em&gt;&lt;/a&gt; &lt;/li&gt;            &lt;li&gt;&lt;a href="http://doddle.matthidinger.com/Reporting/abcpdf/productreport.pdf" target="_blank"&gt;&lt;strong&gt;See it live!&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt;         &lt;/ul&gt;          &lt;h3 /&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="399"&gt;         &lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/563d45072b2e_86C1/image_thumb%5B8%5D_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image_thumb[8]" border="0" alt="image_thumb[8]" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/563d45072b2e_86C1/image_thumb%5B8%5D_thumb.png" width="256" height="300" /&gt;&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="399"&gt;&lt;a href="http://download.codeplex.com/download?ProjectName=doddlereport&amp;amp;DownloadId=204396"&gt;&lt;img style="border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="doddlepdfreport" border="0" alt="doddlepdfreport" src="http://download.codeplex.com/download?ProjectName=doddlereport&amp;amp;DownloadId=204397" width="300" height="295" /&gt;&lt;/a&gt; &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="399"&gt;         &lt;h3&gt;CSV/Delimited&lt;/h3&gt;          &lt;ul&gt;           &lt;li&gt;Use any kind of delimiter you want &lt;/li&gt;            &lt;li&gt;&lt;a href="http://doddle.matthidinger.com/Reporting/home/productreport.txt" target="_blank"&gt;&lt;strong&gt;See it live!&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt;         &lt;/ul&gt;       &lt;/td&gt;        &lt;td valign="top" width="399"&gt;         &lt;h3&gt;HTML Report&lt;/h3&gt;          &lt;ul&gt;           &lt;li&gt;Good old HTML report &lt;/li&gt;            &lt;li&gt;&lt;a href="http://doddle.matthidinger.com/Reporting/home/productreport.html" target="_blank"&gt;&lt;strong&gt;See it live!&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt;         &lt;/ul&gt;          &lt;h3 /&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="399"&gt;         &lt;p&gt;&lt;a href="http://download.codeplex.com/download?ProjectName=doddlereport&amp;amp;DownloadId=204394"&gt;&lt;img style="border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="doddleTxtReport" border="0" alt="doddleTxtReport" src="http://download.codeplex.com/download?ProjectName=doddlereport&amp;amp;DownloadId=204395" width="300" height="190" /&gt;&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="399"&gt;&lt;a href="http://download.codeplex.com/download?ProjectName=doddlereport&amp;amp;DownloadId=204398"&gt;&lt;img style="border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="doddleHtmlReport" border="0" alt="doddleHtmlReport" src="http://download.codeplex.com/download?ProjectName=doddlereport&amp;amp;DownloadId=204399" width="300" height="236" /&gt;&lt;/a&gt; &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;h2&gt;Get Started!&lt;/h2&gt;  &lt;h3&gt;New to DoddleReport?&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;The project lives at CodePlex: &lt;a title="http://doddlereport.codeplex.com/" href="http://doddlereport.codeplex.com/" target="_blank"&gt;&lt;strong&gt;http://doddlereport.codeplex.com/&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Look at the &lt;a href="http://doddlereport.codeplex.com/wikipage?title=Building%20your%20first%20report" target="_blank"&gt;&lt;strong&gt;Building Your First Report&lt;/strong&gt;&lt;/a&gt; page &lt;/li&gt;    &lt;li&gt;If you’re using ASP.NET make sure to read the &lt;a href="http://doddlereport.codeplex.com/wikipage?title=Web%20Reporting" target="_blank"&gt;&lt;strong&gt;Web Reporting&lt;/strong&gt;&lt;/a&gt; section&lt;/li&gt;    &lt;li&gt;Review the &lt;a href="http://doddlereport.codeplex.com/wikipage?title=Check%20out%20the%20sample%20project" target="_blank"&gt;&lt;strong&gt;sample project&lt;/strong&gt;&lt;/a&gt; in the solution&lt;/li&gt;    &lt;li&gt;Check out the &lt;a href="http://doddlereport.codeplex.com/documentation" target="_blank"&gt;&lt;strong&gt;full documentation&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; &lt;/strong&gt;for advanced customization and configuration&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Get it!&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;The preferred install method is NuGet &lt;/li&gt;    &lt;li&gt;…but the compiled Binaries can be found under &lt;a href="http://doddlereport.codeplex.com/releases/view/77983" target="_blank"&gt;&lt;strong&gt;Downloads&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;…or just get &lt;a href="http://doddlereport.codeplex.com/SourceControl/list/changesets" target="_blank"&gt;&lt;strong&gt;the latest source&lt;/strong&gt;&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;NuGet Packages&lt;/h3&gt;  &lt;p&gt;DoddleReport has been split into multiple packages to support more users’ needs. See their Descriptions within NuGet for more on the differences.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Install-Package DoddleReport&lt;/b&gt; &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Install-Package DoddleReport.Web&lt;/b&gt; &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Install-Package DoddleReport.iTextSharp&lt;/b&gt; &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Install-Package DoddleReport.AbcPdf&lt;/b&gt; &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Install-Package DoddleReport.OpenXml&lt;/b&gt; &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Install-Package DoddleReport.Dynamic&lt;/b&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/563d45072b2e_86C1/image_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/563d45072b2e_86C1/image_thumb.png" width="625" height="480" /&gt;&lt;/a&gt;&lt;/h3&gt;  &lt;h2&gt;New in v1.2&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;NEW WRITER: &lt;/strong&gt;A new &lt;strong&gt;OpenXML ExcelReportWriter&lt;/strong&gt; found in the DoddleReport.OpenXml package, courtesy of Louis-Philippe Perras &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;NEW WRITER: &lt;/strong&gt;A new &lt;strong&gt;iTextSharp PDF&lt;/strong&gt; writer can be found in the DoddleReport.iTextSharp package, courtesy of Louis-Philippe Perras (thanks again!) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Breaking change&lt;/strong&gt;: The root namespace changed from &lt;strong&gt;Doddle.Reporting&lt;/strong&gt; to just &lt;strong&gt;DoddleReport&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Breaking change&lt;/strong&gt;: The Default Orientation for reports is now &lt;strong&gt;Portrait&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;All Web references moved to separate project to allow for .NET Client Profile support for WinForms/WPF &lt;/li&gt;    &lt;li&gt;Added “myReport.RenderHints.BooleansAsYesNo = true” to write &lt;strong&gt;Yes&lt;/strong&gt;/&lt;strong&gt;No &lt;/strong&gt;on the reports for boolean fields &lt;/li&gt;    &lt;li&gt;Added custom FileName support for web reporting as requested in Discussions &lt;/li&gt;    &lt;li&gt;Added MVC Areas support by calling areaRegistrationContext.MapReportingRoute(); &lt;/li&gt;    &lt;li&gt;Various Bug fixes and enhancements as reported in the Discussion forum and Issue Tracker &lt;/li&gt; &lt;/ul&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:debc233f-4cb7-49e6-9ff6-c6fbeb00a874" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/doddle" rel="tag"&gt;doddle&lt;/a&gt;,&lt;a href="http://technorati.com/tags/open+source" rel="tag"&gt;open source&lt;/a&gt;,&lt;a href="http://technorati.com/tags/reporting" rel="tag"&gt;reporting&lt;/a&gt;,&lt;a href="http://technorati.com/tags/nuget" rel="tag"&gt;nuget&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/99.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/12/07/Transform-your-LINQ-queries-into-ExcelPDF-reports-with-DoddleReport-1.aspx</guid>
            <pubDate>Wed, 07 Dec 2011 15:59:00 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/12/07/Transform-your-LINQ-queries-into-ExcelPDF-reports-with-DoddleReport-1.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/99.aspx</wfw:commentRss>
        </item>
        <item>
            <title>RealWorldWPDev Part 6: Page Navigation and passing Complex State</title>
            <link>http://www.matthidinger.com/archive/2011/12/04/RealWorldWPDev-Part-6-Page-Navigation-and-passing-Complex-State.aspx</link>
            <description>&lt;div class="update"&gt;   &lt;h3&gt;Series Introduction and Outline&lt;/h3&gt;    &lt;p&gt;This series is going to walk through building a polished, functioning Windows Phone app from start to finish. The app is called Realworld Stocks and the &lt;a href="http://realworldwpdev.codeplex.com/" target="_blank"&gt;full source code will be available on CodePlex&lt;/a&gt; as the series progresses. I’ll be using Mercurial to encourage forking and maybe even pull requests from developers who want to contribute their own real-world solutions.&lt;/p&gt;    &lt;h1&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx"&gt;View the Series Introduction and Outline&lt;/a&gt;&lt;/h1&gt; &lt;/div&gt;  &lt;h2&gt;Navigation Basics&lt;/h2&gt;  &lt;p&gt;Even though this series assumes a basic understanding of Windows Phone development I want to briefly touch on the basics of page navigation. Windows Phone apps follow a basic stateless navigation paradigm very similar to that of a web app. Each page in the app is represented by a URL ending with .xaml. &lt;/p&gt;  &lt;h3&gt;How to Navigate to a new Page (the bad way)&lt;/h3&gt;  &lt;p&gt;The simplest way to navigate would be to drop in a Button, add a Click handler for the button, and use the following sample code in your code-behind.&lt;/p&gt;  &lt;pre class="brush: c-sharp; toolbar: false"&gt;NavigationService.Navigate(new Uri("/Views/Home.xaml"));
NavigationService.Navigate(new Uri("/Views/ProductDetails.xaml?ProductID=5&amp;amp;ProductName=HTC%20Titan"));&lt;/pre&gt;

&lt;p&gt;As you can see, if you need to pass parameters to the page you’re navigating to, you use query string values, again exactly how you would write a web application. &lt;/p&gt;

&lt;h3&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/b44afa443a77_8012/SNAGHTML1dfd0d9f.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="SNAGHTML1dfd0d9f" border="0" alt="SNAGHTML1dfd0d9f" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/b44afa443a77_8012/SNAGHTML1dfd0d9f_thumb.png" width="592" height="480" /&gt;&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;In the first image above we have a ListBox of Stock Symbols. When the user clicks on the MSFT item, we want to navigate to the StockDetailsView.xaml, and tell it which Symbol was clicked on. What we are looking to achieve is something along these lines.&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;NavigationService.Navigate(new Uri("/Views/StockDetailsView.xaml?Symbol=MSFT"));&lt;/pre&gt;

&lt;h3&gt;Accessing QueryString params (the bad way)&lt;/h3&gt;

&lt;p&gt;Now we are on our new page and need to access the QueryString. So if we open up code-behind for StockDetailsView.xaml.cs we could&lt;em&gt; &lt;/em&gt;override &lt;strong&gt;OnNavigatedTo&lt;/strong&gt;, and access the &lt;strong&gt;NavigationContext.QueryString&lt;/strong&gt; dictionary to pull out the params that were passed in. &lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public partial class StockDetailsView : PhoneApplicationPage
{
    public StockDetailsView()
    {
        InitializeComponent();
    }

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        var symbol = NavigationContext.QueryString["Symbol"];
    }
}&lt;/pre&gt;

&lt;p&gt;Ick. Lots of strings in this scenario, both for navigating to a new URI, and also for pulling query string parameters out. &lt;/p&gt;

&lt;p&gt;Strings can prove troublesome for a few reasons: &lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;They are very susceptible to typo’s &lt;/li&gt;

  &lt;li&gt;They offer no refactoring/renaming support at compile-time. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thankfully, there’s a better way…&lt;/p&gt;

&lt;h2&gt;Navigating with Caliburn &lt;/h2&gt;

&lt;p&gt;As I mentioned in a previous post, one of the reasons I love Caliburn is that it provides &lt;em&gt;just enough&lt;/em&gt; infrastructure to let me develop faster, but not so overbearing that I’m boxed into a corner. One of these infrastructure benefits is navigation on both sides of the equation: navigating to a new page, and pulling out query string params on the new page.&lt;/p&gt;

&lt;h3&gt;Navigating with HyperlinkButton and an ActionMessage&lt;/h3&gt;

&lt;p&gt;In the screenshot above we can see a ListBox showing a list of Stocks. And with this ListBox we naturally have a DataTemplate describing how to render each item. But the really important piece here is that when a specific item is Tapped, we want to load the StockDetails view for that item.&lt;/p&gt;

&lt;h4&gt;HomeWatchListView.xaml&lt;/h4&gt;

&lt;p&gt;Within HomeWatchListView.xaml we have defined the following DataTemplate, which has a &lt;strong&gt;HyperlinkButton&lt;/strong&gt; with something special – &lt;strong&gt;cal:Message.Attach=”LoadSymbol($dataContext)”&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="brush: xhtml; toolbar: false"&gt;&amp;lt;DataTemplate x:Key="WatchListItemTemplate"&amp;gt;
	&amp;lt;HyperlinkButton cal:Message.Attach="LoadSymbol($dataContext)"&amp;gt;
		&amp;lt;Grid&amp;gt;                
	             &amp;lt;TextBlock Text="{Binding Symbol}"/&amp;gt;
	             &amp;lt;TextBlock Text="{Binding Company}"/&amp;gt;
		&amp;lt;/Grid&amp;gt;
	&amp;lt;/HyperlinkButton&amp;gt;
&amp;lt;/DataTemplate&amp;gt;&lt;/pre&gt;

&lt;p&gt;At first this may look pretty weird. It looks like it’s calling a method named &lt;strong&gt;LoadSymbol()&lt;/strong&gt; with some kind of token being passed as &lt;strong&gt;$dataContext&lt;/strong&gt; – and that’s exactly what it is.&lt;/p&gt;

&lt;h4&gt;HomeViewModel.cs&lt;/h4&gt;

&lt;p&gt;Now, in our HomeViewModel we can see exactly where this method is defined. And it does in fact take in a method parameter of type StockSnapshot. Since this is exactly what our ListBox on the view was bound to, were able to use the $dataContext param which represents a single StockSnapshot in the list – specifically, the one that was Tapped.&lt;/p&gt;

&lt;p&gt;This give us the added benefit of writing navigation login in our ViewModel and not in our View. ViewModels are more easily testable than Views and can be reused if necessary.&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class HomeViewModel : Screen
{
    // ... snip ...

    public void LoadSymbol(StockSnapshot snapshot)
    {
    	// TODO: Navigate!
    }
}&lt;/pre&gt;

&lt;h3&gt;How to Navigate to a new Page (the good way)&lt;/h3&gt;

&lt;p&gt;Caliburn has an &lt;strong&gt;INavigationService&lt;/strong&gt; that we use in our ViewModel. It offers 2 major pieces of functionality (and a lot more – see the summary section below!):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Building a URI for us using &lt;strong&gt;_navigationSerice.UriFor&amp;lt;T&amp;gt;()&lt;/strong&gt; – &lt;strong&gt;Look ma’,&lt;/strong&gt; &lt;strong&gt;no strings!&lt;/strong&gt; &lt;/li&gt;

  &lt;li&gt;Take the generated URI and Navigate to a new page &lt;/li&gt;
&lt;/ol&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public void LoadSymbol(StockSnapshot snapshot)
{
    var uri = _navigation.UriFor&amp;lt;StockDetailsViewModel&amp;gt;()
        .WithParam(m =&amp;gt; m.Symbol, snapshot.Symbol)
        .BuildUri();

    // BuildUri() returns the following URI
    // /Views/StockDetails/StockDetailsView.xaml?Symbol=MSFT

    _navigation.UriFor&amp;lt;StockDetailsViewModel&amp;gt;()
        .WithParam(m =&amp;gt; m.Symbol, snapshot.Symbol)
        .Navigate();
}&lt;/pre&gt;

&lt;h3&gt;Accessing QueryString params (the good way)&lt;/h3&gt;

&lt;p&gt;Now that we have navigated to StockDetailsView.xaml we need to figure out which Symbol to load – which was passed in via query string. Another great piece of infrastructure is that when a Page is Initialized Caliburn will examine the Page’s QueryString for you. It will look for properties on the ViewModel that match the QueryString parameters and inject them automatically, performing the necessary type coercion (for example, if you ViewModel had a property of type Int.)&lt;/p&gt;

&lt;p&gt;That is a long way of saying this: &lt;strong&gt;On your ViewModel, create a property whose name matches a QueryString parameter and it will be injected for you automatically.&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class StockDetailsViewModel : Screen
{
    private string _symbol;

    // This property will be populated automatically because 
    // the incoming querystring has a param named ?Symbol=X
    public string Symbol
    {
        get { return _symbol; }
        set
        {
            _symbol = value;
            NotifyOfPropertyChange(() =&amp;gt; Symbol);
        }
    }
}&lt;/pre&gt;

&lt;p&gt;Awesome! No more strings! We are now able build a URI using a strongly typed model with full refactor/rename supporting, &lt;strong&gt;and &lt;/strong&gt;able to pull out the query string parameter on the new page without every accessing the Query String directly. I personally find this to be amazingly time saving and allows for very rapid refactoring and enhancements as the app progresses.&lt;/p&gt;

&lt;h2&gt;Passing complex State between Pages&lt;/h2&gt;

&lt;p&gt;Now there is one final piece to our puzzle. Passing around basic query string primitives is fine, but what if you already have a fully populated complex object model and want to pass that to the next page? This is where things can get a bit muddy.&lt;/p&gt;

&lt;p&gt;For this scenario I typically &lt;strong&gt;combine&lt;/strong&gt; query strings with a singleton data dump called &lt;strong&gt;GlobalData&lt;/strong&gt;. Usually I will create a basic dictionary inside of GlobalData, where I will store the object based on some key, and then pull the object out of GlobalData by using that same key – the key is what I pass around using QueryStrings. The 3 classes working together are outlined below.&lt;/p&gt;

&lt;h4&gt;GlobalData / SnapshotCache&lt;/h4&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class SnapshotCache : Dictionary&amp;lt;string, StockSnapshot&amp;gt;
{
    public StockSnapshot GetFromCache(string key)
    {
        if (ContainsKey(key))
            return this[key];

        return null;
    }
}

public class GlobalData : NotifyObject
{
    private GlobalData()
    {
            
    }

    private static GlobalData _current;
    public static GlobalData Current
    {
        get
        {
            if (_current == null)
                _current = new GlobalData();

            return _current;
        }
        set { _current = value; }
    }

    private SnapshotCache _cachedStops;
    public SnapshotCache Snapshots
    {
        get
        {
            if (_cachedStops == null)
                _cachedStops = new SnapshotCache();

            return _cachedStops;
        }
    }
}&lt;/pre&gt;

&lt;h4&gt;Before navigating to a new page, store the object into GlobalData…&lt;/h4&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class HomeViewModel : Screen
{
    public void LoadSymbol(StockSnapshot snapshot)
    {
        GlobalData.Current.Snapshots[snapshot.Symbol] = snapshot;

        _navigation.UriFor&amp;lt;StockDetailsViewModel&amp;gt;()
             .WithParam(m =&amp;gt; m.Symbol, snapshot.Symbol)
             .Navigate();
    }
}&lt;/pre&gt;

&lt;h4&gt;…on the new page, pull the object out of GlobalData&lt;/h4&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class StockDetailsViewModel : Screen
{
    private string _symbol;
    public string Symbol
    {
        get { return _symbol; }
        set
        {
            _symbol = value;
            NotifyOfPropertyChange(() =&amp;gt; Symbol);
        }
    }

    public StockSnapshot Snapshot
    {
        get { return GlobalData.Current.Snapshots[Symbol]; }
    }
}&lt;/pre&gt;

&lt;h2&gt;Summary and further reading&lt;/h2&gt;

&lt;p&gt;This tutorial covered quite a bit but hopefully didn’t throw too much at you. Page navigation is one of the biggest topics that devs ask me when building their first app, and I highly recommend using Caliburn’s excellent infrastructure to make the task a lot easier. &lt;/p&gt;

&lt;p&gt;If you want to dive more into using CM with Windows Phone please check out the following pages:&lt;/p&gt;

&lt;p&gt;&lt;a title="http://caliburnmicro.codeplex.com/wikipage?title=Working%20with%20Windows%20Phone%207%20v1.1&amp;amp;referringTitle=Documentation" href="http://caliburnmicro.codeplex.com/wikipage?title=Working%20with%20Windows%20Phone%207%20v1.1&amp;amp;referringTitle=Documentation"&gt;Caliburn Docs: Working with Windows Phone&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a title="http://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Actions&amp;amp;referringTitle=Documentation" href="http://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Actions&amp;amp;referringTitle=Documentation"&gt;Caliburn Docs: All About Actions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div class="update"&gt;
  &lt;h3&gt;Want some more RealWorldWPDev?&lt;/h3&gt;

  &lt;h1&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx"&gt;View the Series Introduction and Outline&lt;/a&gt;&lt;/h1&gt;
&lt;/div&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:8b676f4c-7440-4a26-87f8-e77db79776dd" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/realworldwpdev" rel="tag"&gt;realworldwpdev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/98.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/12/04/RealWorldWPDev-Part-6-Page-Navigation-and-passing-Complex-State.aspx</guid>
            <pubDate>Mon, 05 Dec 2011 00:34:02 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/12/04/RealWorldWPDev-Part-6-Page-Navigation-and-passing-Complex-State.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/98.aspx</wfw:commentRss>
        </item>
        <item>
            <title>New job, month off, RealWorldWPDev continues</title>
            <link>http://www.matthidinger.com/archive/2011/12/02/New-job-month-off-RealWorldWPDev-continues.aspx</link>
            <description>&lt;p&gt;As Phil put it recently: &lt;a href="http://haacked.com/archive/2011/11/28/departing-microsoft.aspx" target="_blank"&gt;it’s not every day you write this sort of blog post&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;A few people have been asking me why there haven’t been any updates on &lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx" target="_blank"&gt;RealWorldWPDev&lt;/a&gt; in the last few weeks, and the simple answer is that I was pretty swamped over a particular life decision: changing jobs. They say changing jobs is one of the most stressful things we do in life, and I definitely believe it. &lt;/p&gt;  &lt;p&gt;November 30th marked my last day at Triton-Tek after 4.5 years. It was by far the best job I’ve had to date. I got to work with some really great people, on some awesome projects, and made good friends along the way. It was a really tough decision to leave.&lt;/p&gt;  &lt;h2&gt;What’s Next?&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Changing-Jobs-RealW_133DD/clarity_2.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 5px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clarity" border="0" alt="clarity" align="right" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Changing-Jobs-RealW_133DD/clarity_thumb.jpg" width="300" height="72" /&gt;&lt;/a&gt;But Chicago is a big city with some great companies and great talent. I would be remiss if I didn’t take this opportunity in my late 20s to explore what else is out there. I’m very excited that on January 5th, 2012 I’ll be joining &lt;a href="http://www.claritycon.com/" target="_blank"&gt;Clarity Consulting&lt;/a&gt;. The first time I met some of Clarity’s WP7 team was back in October 2010, where we were both invited by Microsoft to speak at the Chicago Windows Phone launch party. They have worked on some really impressive software over the years, and I very much look forward to joining a group well known for their talent and passion for leading edge technology solutions.&lt;/p&gt;  &lt;h2&gt;A Month off&lt;/h2&gt;  &lt;p&gt;But before all that, I decided to take a month to myself. So I have December off. I’m going to be nerding out. A lot. Many of you have recommended I go on vacation, but with my girlfriend just starting a new job and unable to take time off, she would be pretty bitter if I disappeared somewhere exotic for two weeks. Ultimately, I love coding, and I am honestly very excited to work on code that &lt;strong&gt;I &lt;/strong&gt;want to… for an entire month. &lt;/p&gt;  &lt;p&gt;And it’s actually off to a pretty good start, some of which includes…&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://onionarch.codeplex.com" target="_blank"&gt;Get the code from my Onion Architecture talk on CodePlex&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://doddlereport.codeplex.com/" target="_blank"&gt;Update DoddleReport to v1.1 with some new features and lots of NuGet goodness&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.matthidinger.com/archive/2011/11/27/Writing-a-Fluent-ASP-NET-MVC-Recursive-TreeView-Helper.aspx" target="_blank"&gt;Update one of my most trafficked blog posts with a new API and full source code&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Migrate all my personal projects off TFS and onto Mercurial (I really like Mercurial) &lt;/li&gt;    &lt;li&gt;RealWorldWPDev parts 6-10 &lt;/li&gt;    &lt;li&gt;Publish the CTA Watch update for Mango and some cool new features &lt;/li&gt;    &lt;li&gt;Publish the Transit Directions update for Mango &lt;/li&gt;    &lt;li&gt;Tackle my massive blog backlog &lt;/li&gt;    &lt;li&gt;Tackle it even more. Seriously, it’s a huge backlog. 20 posts? Ack. Prob won’t get to all of them &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Changing-Jobs-RealW_133DD/wlEmoticon-winkingsmile_2.png" /&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I know what you’re thinking: I need time away from the computer. I’ll do that too. I greatly look forward to unwinding back home in Michigan for a week around Christmas!&lt;/p&gt;  &lt;h2&gt;In closing…&lt;/h2&gt;  &lt;p&gt;Thanks again to everyone at Triton-Tek for an awesome near half-decade!&lt;/p&gt;  &lt;p&gt;Thanks to all of you who read my ramblings on here every few weeks!&lt;/p&gt;  &lt;p&gt;Thanks to the Chicago dev Community! Rest assured I will still be fully involved in the local community, probably even more-so.&lt;/p&gt;  &lt;p&gt;And come on Nokia, help us get Windows Phone the market attention it deserves &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Changing-Jobs-RealW_133DD/wlEmoticon-winkingsmile_2.png" /&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:80d11194-a83a-4e99-b01a-c9c2d2822170" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/career" rel="tag"&gt;career&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/97.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/12/02/New-job-month-off-RealWorldWPDev-continues.aspx</guid>
            <pubDate>Sat, 03 Dec 2011 04:52:10 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/12/02/New-job-month-off-RealWorldWPDev-continues.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/97.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Writing a Fluent ASP.NET MVC Recursive TreeView Helper</title>
            <link>http://www.matthidinger.com/archive/2011/11/27/Writing-a-Fluent-ASP-NET-MVC-Recursive-TreeView-Helper.aspx</link>
            <description>&lt;p&gt;This post is an update to my original &lt;a title="http://www.matthidinger.com/archive/2009/02/08/asp.net-mvc-recursive-treeview-helper.aspx" href="http://www.matthidinger.com/archive/2009/02/08/asp.net-mvc-recursive-treeview-helper.aspx"&gt;ASP.NET MVC Recursive TreeView Helper&lt;/a&gt; from almost 3 years ago. Oddly enough it’s still a high-traffic post and has close to 50 comments asking for an update or a complete solution to download. I figured if I was going to do that, I might as well give the API a much-needed facelift and pop it on NuGet.&lt;/p&gt;  &lt;h2&gt;What is it?&lt;/h2&gt;  &lt;h4&gt;Given the following self-referencing hierarchal model…&lt;/h4&gt;  &lt;pre class="brush: c-sharp; toolbar: false"&gt;public class TreeViewLocation
{
    public TreeViewLocation()
    {
        ChildLocations = new HashSet&amp;lt;TreeViewLocation&amp;gt;();
    }

    public int Id { get; set; }
    public string Name { get; set; }

    public virtual int? ParentLocationId { get; set; }
        
    public virtual ICollection&amp;lt;TreeViewLocation&amp;gt; ChildLocations { get; set; }
}&lt;/pre&gt;

&lt;h4&gt;…we want to generate an HTML unordered-list like this&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/d59c757b9eff_CC0C/image_11.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/d59c757b9eff_CC0C/image_thumb_3.png" width="290" height="281" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;what’s the new API look like?&lt;/h2&gt;

&lt;p&gt;First, apologies for mixing syntax highlighters. My default one doesn’t have a great Razor theme yet.&lt;/p&gt;

&lt;p&gt;The following Razor shows the API we will create. It follows a fluent syntax which many developers greatly prefer over the alternative (dozens of overloads!) In the end, it’s easier for us to write, easier to extend in the future, and more discoverable for developers who use it later on. This particular TreeView implementation also takes advantage of Razor’s awesome HelperResult templating delegate (the @&amp;lt;text&amp;gt; syntax seen below).&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: yellow"&gt;@model &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;MvcTreeView.Models.&lt;span style="color: #2b91af"&gt;Location&lt;/span&gt;&amp;gt;
&lt;span style="color: blue"&gt;
&lt;/span&gt;&lt;span style="background: yellow"&gt;@(&lt;/span&gt;Html.TreeView(Model)
    .EmptyContent(&lt;span style="color: #a31515"&gt;"No locations have been defined yet!"&lt;/span&gt;)    
    .Children(m =&amp;gt; m.ChildLocations)
    .HtmlAttributes(&lt;span style="color: blue"&gt;new &lt;/span&gt;{ id = &lt;span style="color: #a31515"&gt;"tree"&lt;/span&gt;})
    .ChildrenHtmlAttributes(&lt;span style="color: blue"&gt;new &lt;/span&gt;{ @class = &lt;span style="color: #a31515"&gt;"subItem"&lt;/span&gt;})
    .ItemText(m =&amp;gt; m.Name)
    .ItemTemplate(
        &lt;span style="background: yellow"&gt;@&amp;lt;text&amp;gt;
&lt;/span&gt;            &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;="#&lt;/span&gt;&lt;span style="background: yellow"&gt;@&lt;/span&gt;&lt;span style="color: blue"&gt;item.Id"&amp;gt;&lt;/span&gt;&lt;span style="background: yellow"&gt;@&lt;/span&gt;item.Name&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;/text&amp;gt;&lt;/span&gt;)
&lt;span style="background: yellow"&gt;)&lt;/span&gt;&lt;/pre&gt;

&lt;h2&gt;How was it written?&lt;/h2&gt;

&lt;h3&gt;Defining a Fluent API&lt;/h3&gt;

&lt;p&gt;Writing a fluent API is typically pretty simple. The key requirement is that each method returns the type of the class, and always terminates with “return this;” The rest of the method body usually just stores some state to a private field, which will eventually be used to render the customized UI.&lt;/p&gt;

&lt;p&gt;For example, to set the ItemText which will display the item label in each &amp;lt;li&amp;gt;, we take the property selector and simply store it into the _displayProperty field, eventually returning the current instance allowing for further methods to be chained together.&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public TreeView&amp;lt;T&amp;gt; ItemText(Func&amp;lt;T, string&amp;gt; selector)
{
    if (selector == null) throw new ArgumentNullException("selector");
    _displayProperty = selector;
    return this;
}&lt;/pre&gt;

&lt;h3&gt;Rendering / IHtmlString&lt;/h3&gt;

&lt;p&gt;Finally, once the developer has customized exactly how the TreeView should be rendered, we need to output the HTML.&lt;/p&gt;

&lt;p&gt;One way to hook into this infrastructure is by implementing both &lt;strong&gt;IHtmlString&lt;/strong&gt; and overriding &lt;strong&gt;ToString()&lt;/strong&gt;. MVC will inspect whether we implement &lt;strong&gt;IHtmlString &lt;/strong&gt;and if so, will call &lt;strong&gt;ToHtmlString()&lt;/strong&gt; to trigger our rendering which is written to view.&lt;/p&gt;

&lt;p&gt;Also notice the &lt;strong&gt;ValidateSettings()&lt;/strong&gt; call – this is necessary in many fluent configurations, since these kinds of APIs lend themselves to invalid configuration on occasion. For example using 2 incompatible methods like ItemText() and ItemTemplate() together – typically you either want to use a simple text display or a full-blowing template display – but it’s impossible to use both. We could throw an exception here alerting the developer that this is an invalid configuration.&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public override string ToString()
{
    ValidateSettings();

    var listItems = _items.ToList();

    var ul = new TagBuilder("ul");
    ul.MergeAttributes(_htmlAttributes);

    // snip...
    return ul.ToString();
}

public string ToHtmlString()
{
    return ToString();
}&lt;/pre&gt;

&lt;h2&gt;Get The Code&lt;/h2&gt;

&lt;p&gt;This helper is very easy to add to your project using NuGet. Alternatively you can still go the manual route and grab the code from CodePlex.&lt;/p&gt;

&lt;h3&gt;NuGet / NuGet Sample Package&lt;/h3&gt;

&lt;p&gt;With this project I decided to include a &lt;a href="http://blog.davidebbo.com/2011/03/take-nuget-to-next-level-with-sample.html" target="_blank"&gt;NuGet Sample Package&lt;/a&gt; which is used to easily demonstrate the usage of the helper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;These are source-only packages. &lt;/strong&gt;By installing this package into your project you will get a raw file in &lt;strong&gt;Helpers\TreeView.cs&lt;/strong&gt; that you can edit or update as you see fit. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/d59c757b9eff_CC0C/image_13.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/d59c757b9eff_CC0C/image_thumb_4.png" width="766" height="89" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The sample project is the same concept, it will add a &lt;strong&gt;TreeViewController&lt;/strong&gt;, and a &lt;strong&gt;TreeView.cshtml &lt;/strong&gt;view which demonstrates the usage of the TreeView helper. Once you’ve tried out the sample and played with it, it’s very easy to uninstall via NuGet to remove the unnecessary files.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/d59c757b9eff_CC0C/image_3.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/d59c757b9eff_CC0C/image_thumb.png" width="763" height="86" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;CodePlex&lt;/h3&gt;

&lt;p&gt;And of course, the full source is available to download on CodePlex.&lt;/p&gt;

&lt;h4&gt;&lt;a title="http://mvctreeview.codeplex.com" href="http://mvctreeview.codeplex.com"&gt;http://mvctreeview.codeplex.com&lt;/a&gt;&lt;/h4&gt;

&lt;h4&gt;&lt;a href="http://mvctreeview.codeplex.com/SourceControl/BrowseLatest"&gt;Browse the latest source code&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4bc85cc1-4663-4e22-a48b-d54518539935" class="wlWriterSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/aspnet+mvc" rel="tag"&gt;aspnet mvc&lt;/a&gt;,&lt;a href="http://technorati.com/tags/fluent" rel="tag"&gt;fluent&lt;/a&gt;,&lt;a href="http://technorati.com/tags/razor" rel="tag"&gt;razor&lt;/a&gt;,&lt;a href="http://technorati.com/tags/nuget" rel="tag"&gt;nuget&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/95.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/11/27/Writing-a-Fluent-ASP-NET-MVC-Recursive-TreeView-Helper.aspx</guid>
            <pubDate>Sun, 27 Nov 2011 19:32:08 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/11/27/Writing-a-Fluent-ASP-NET-MVC-Recursive-TreeView-Helper.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/95.aspx</wfw:commentRss>
        </item>
        <item>
            <title>RealWorldWPDev Part 5: Creating and Consuming Web Services</title>
            <link>http://www.matthidinger.com/archive/2011/11/01/RealWorldWPDev-Part-5-Creating-and-Consuming-Web-Services.aspx</link>
            <description>&lt;div class="update"&gt;   &lt;h3&gt;Series Introduction and Outline&lt;/h3&gt;    &lt;p&gt;This series is going to walk through building a polished, functioning Windows Phone app from start to finish. The app is called Realworld Stocks and the &lt;a href="http://realworldwpdev.codeplex.com/" target="_blank"&gt;full source code will be available on CodePlex&lt;/a&gt; as the series progresses. I’ll be using Mercurial to encourage forking and maybe even pull requests from developers who want to contribute their own real-world solutions.&lt;/p&gt;    &lt;h1&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx"&gt;View the Series Introduction and Outline&lt;/a&gt;&lt;/h1&gt; &lt;/div&gt;  &lt;h2&gt;Choices&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-5-The-Panorama_12221/image_4.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 6px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-5-The-Panorama_12221/image_thumb.png" width="288" height="480" /&gt;&lt;/a&gt;In the Microsoft world we have no shortage of client and server-side HTTP stacks to choose from. Rather than try to cover every possible combination, and to prevent this topic from getting too long-winded, I will keep this part succinct. &lt;/p&gt;  &lt;p&gt;Our first major decisions revolve around the following options:&lt;/p&gt;  &lt;h4&gt;SOAP or REST?&lt;/h4&gt;  &lt;h4&gt;WCF or ASP.NET MVC?&lt;/h4&gt;  &lt;p&gt;Without getting too deep into it, and certainly without suggesting that this is The One True Way, I personally prefer creating REST-based ASP.NET MVC endpoints for the following reasons:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Very simple, flexible routing out of the box &lt;/li&gt;    &lt;li&gt;Returning JSON is as simple as return Json() &lt;/li&gt;    &lt;li&gt;Model binding/casting of incoming request parameters &lt;/li&gt;    &lt;li&gt;Simple ActionFilter attributes add Caching and GZip Compression &lt;/li&gt;    &lt;li&gt;No XML configuration, no code/proxy generation, no service references &lt;/li&gt; &lt;/ol&gt;  &lt;h2&gt;Creating Services&lt;/h2&gt;  &lt;p&gt;Since we’ve decided to go down the path of ASP.NET MVC for this project, I’m going to walk you through creating services using MVC. If you’ve been following along then you already have your Web project setup. If not, please see &lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-2-File-ndashgt-New-Project.aspx"&gt;Part 2: File –&amp;gt; New Project&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Should I create a middle-man service?&lt;/h3&gt;  &lt;p&gt;Many mobile apps communicate with some kind of 3rd party service(s). The decision you need to make is whether the phone should connect directly to this service, or if there are benefits to having the mobile app connect to your middle-man web service, which will subsequently contact the third party service. The decision here definitely depends on your specific needs, but there are very real advantages to creating a middle-man service. A few of the benefits of include:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;API Keys&lt;/strong&gt; &lt;strong&gt;- &lt;/strong&gt;If the third party service requires an API key, storing it on the phone can easily be stolen. If your web server proxies this call for you, it’s much safer being stored there. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Caching – &lt;/strong&gt;Many services will throttle the number of requests you make (using your API key). If you can limit these requests by caching the response on your server, it can greatly improve response times for your users as well as keep your third party service usage lower. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Shaping the Model&lt;/strong&gt; – Many service providers return XML. They may even return a ton of XML that you don’t even care about in your app. If your mobile app contacts your server directly, your server is able to query the third party data and shape it in the most efficient way possible to return to the mobile app, including: Aggregating multiple third-party service calls into one HTTP response to the phone, removing unnecessary elements that the phone app wouldn’t use, and turning the XML into Compressed JSON making it much more compact. &lt;/li&gt; &lt;/ol&gt;  &lt;h2&gt;Enough background, implementation time&lt;/h2&gt;  &lt;p&gt;The following will walk you through a pretty efficient way for creating and consuming services, while enhancing them very easily over time. Of course, to get the full idea of how it works in practice, &lt;a href="http://realworldwp7.codeplex.com/"&gt;make sure you pull down the latest code and check it out.&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;step 1: Define your entities/model in the WP7 project&lt;/h3&gt;  &lt;p&gt;In &lt;strong&gt;RealworldStocks.Client.Core&lt;/strong&gt; I have a &lt;strong&gt;Models&lt;/strong&gt; folder, which include various classes that inherit from &lt;strong&gt;NotifyObject,&lt;/strong&gt; seen below.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-5-The-Panorama_12221/SNAGHTML9d234fa6.png"&gt;&lt;img title="SNAGHTML9d234fa6" border="0" alt="SNAGHTML9d234fa6" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-5-The-Panorama_12221/SNAGHTML9d234fa6_thumb.png" width="900" height="588" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;step 2: “Add as Link” model classes into your Web project&lt;/h3&gt;  &lt;p&gt;Since you want these same classes to be serialized from your service, you will need them in the web project, but want to keep them in sync as you add, remove, or rename properties. To do this, in &lt;strong&gt;RealWorldStocks.Web&lt;/strong&gt;, &lt;strong&gt;right-click in your Models &lt;/strong&gt;folder and select &lt;strong&gt;Add –&amp;gt; Existing Item…&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Then navigate to the &lt;strong&gt;RealWorldStocks.Client.Core\Models&lt;/strong&gt; folder and select the entities you plan on serializing and exposing to your client, &lt;strong&gt;but don’t just press Add!&lt;/strong&gt; Next to the Add button is a drop-down arrow, open it and make sure you click &lt;strong&gt;Add As Link&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-5-The-Panorama_12221/image_6.png"&gt;&lt;img title="image" border="0" alt="image" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-5-The-Panorama_12221/image_thumb_2.png" width="900" height="557" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Notice how the files have little “shortcut” overlays on their icons.&lt;/p&gt;  &lt;h5&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-5-The-Panorama_12221/image_8.png"&gt;&lt;img title="image" border="0" alt="image" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-5-The-Panorama_12221/image_thumb_3.png" width="310" height="513" /&gt;&lt;/a&gt;&lt;/h5&gt;  &lt;h3&gt;step 3: Return your data as JSON from the MVC controller&lt;/h3&gt;  &lt;p&gt;Below is the complete &lt;strong&gt;StocksController&lt;/strong&gt; for exposing Snapshots and getting the latest News articles. The following code covers a number of concepts from the beginning of this post. I encourage you to check out the full source code to get an understanding of how they work under the covers.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;[AllowJsonGet]&lt;/strong&gt; – This attribute works around an MVC 2 security feature that makes you explicitly return JSON from HTTP GET requests &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;[NoCache] &lt;/strong&gt;– The WebClient in WP7 will cache requests for you automatically. This can catch you off guard and cause very subtle bugs if you aren’t careful. This attribute will add the appropriate HTTP cache-control headers to our response telling the app not to cache the returned JSON. If we didn’t have this, every time we requested an update for the MSFT symbol, we would immediately get back the phone-cached previous response without even trying to contact the server. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;[Compress]&lt;/strong&gt; – This attribute checks the incoming Accept-Encoding of the request, and if it supports GZip, will automatically GZip compress the outgoing response. Our Windows Phone app uses the &lt;strong&gt;SharpGIS&lt;/strong&gt;.&lt;strong&gt;GZipWebClient &lt;/strong&gt;to decompress it – discussed below. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;[OutputCache]&lt;/strong&gt; – On The &lt;strong&gt;GetSnapshot &lt;/strong&gt;method below there is an &lt;strong&gt;OutputCache with a Duration of 60&lt;/strong&gt;. This attribute instructs MVC to return a cached version of this response as long as the incoming route parameters are the same – in this case, if the same Symbol is requested. This means that if multiple Realworld Stocks users out there are all request a snapshot of MSFT, our service will cache this for 60 seconds and give them all the same response, rather than hitting Yahoo every single time. &lt;/li&gt; &lt;/ol&gt;  &lt;pre class="brush: c-sharp; toolbar: false"&gt;[AllowJsonGet]
[NoCache]
[Compress]
public class StocksController : Controller
{
    private readonly IStocksService _stocksService;
    private readonly INewsService _newsService;

    public StocksController()
    {
        _stocksService = new YahooStocksService();
        _newsService = new FakeNewsService();
    }

    public ActionResult GetSnapshots(string[] symbols)
    {
        var model = _stocksService.GetSnapshots(symbols);
        return Json(model);
    }

    public ActionResult GetNews(string[] symbols)
    {
        var model = _newsService.GetNews(symbols);
        return Json(model);
    }


    [OutputCache(Duration = 60)]
    public ActionResult GetSnapshot(string symbol)
    {
        return GetSnapshots(new[] { symbol });
    }
}&lt;/pre&gt;

&lt;h4&gt;Test it!&lt;/h4&gt;

&lt;p&gt;If everything goes as planned you should be able to hit this URL in a browser. On my machine hosted under IIS, the URL is:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost/RealWorldStocks.Web/Stocks/GetSnapshots?symbols=MSFT&amp;amp;symbols=NOK"&gt;http://localhost/RealWorldStocks.Web/Stocks/GetSnapshots?symbols=MSFT&amp;amp;symbols=NOK&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;step 4: Creating a robust HttpClient&lt;/h3&gt;

&lt;p&gt;Now that we have our service up there and returning JSON, let’s start consuming it from the app. The following HttpClient handles a number of concerns on our behalf. &lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;GZip Compression using &lt;a href="http://www.sharpgis.net/post/2011/08/28/GZIP-Compressed-Web-Requests-in-WP7-Take-2.aspx" target="_blank"&gt;SharpGIS.GZipWebClient&lt;/a&gt; (can be found on NuGet!) &lt;/li&gt;

  &lt;li&gt;Timeout Support to automatically kill requests that take too long (30 seconds by default) &lt;/li&gt;

  &lt;li&gt;Logging requests and responses in the Debug window &lt;/li&gt;

  &lt;li&gt;Deserializing the JSON into the specific Model type automatically &lt;/li&gt;
&lt;/ol&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public static class HttpClient
{
    public static TimeSpan Timeout = TimeSpan.FromSeconds(30);

    public static void BeginRequest&amp;lt;T&amp;gt;(HttpRequest&amp;lt;T&amp;gt; request, Action&amp;lt;HttpResponse&amp;lt;T&amp;gt;&amp;gt; callback)
    {
        BeginRequest(request.Url, callback);
    }

    public static void BeginRequest&amp;lt;T&amp;gt;(string url, Action&amp;lt;HttpResponse&amp;lt;T&amp;gt;&amp;gt; callback)
    {
        var client = new GZipWebClient();

        var timer = new Timer(state =&amp;gt; client.CancelAsync(), null, Timeout, TimeSpan.FromMilliseconds(-1));
            
        Debug.WriteLine("HTTP Request: {0}", url);
        client.DownloadStringCompleted += (s, e) =&amp;gt; ProcessResponse(callback, e);
        client.DownloadStringAsync(new Uri(url, UriKind.Absolute), timer);
    }

    private static void ProcessResponse&amp;lt;T&amp;gt;(Action&amp;lt;HttpResponse&amp;lt;T&amp;gt;&amp;gt; callback, DownloadStringCompletedEventArgs e)
    {
        var timer = (Timer) e.UserState;
        if (timer != null)
            timer.Dispose();

        try
        {
            if (e.Error == null)
            {
                string json = e.Result.Replace("&amp;amp;amp;", "&amp;amp;");
                Debug.WriteLine("HTTP Response: {0}\r\n", json);
                var model = SerializationHelper.Deserialize&amp;lt;T&amp;gt;(json);

                Deployment.Current.Dispatcher.BeginInvoke(() =&amp;gt; callback(new HttpResponse&amp;lt;T&amp;gt;(model)));
            }
            else
            {
                throw new WebException("Error getting the web service data", e.Error);
            }
        }
        catch (SerializationException ex)
        {
            var httpException = new HttpException("Unable to deserialize the model", ex);
            Debug.WriteLine(ex);
            Deployment.Current.Dispatcher.BeginInvoke(() =&amp;gt; callback(new HttpResponse&amp;lt;T&amp;gt;(httpException)));
        }
        catch (WebException ex)
        {
            var httpException = new HttpException(ex);
            Debug.WriteLine(ex);
            Deployment.Current.Dispatcher.BeginInvoke(() =&amp;gt; callback(new HttpResponse&amp;lt;T&amp;gt;(httpException)));
        }
    }
}&lt;/pre&gt;

&lt;h4&gt;Logging&lt;/h4&gt;

&lt;p&gt;The logging is helpful to see the following in the Debug window as you’re testing the app.&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;INFO: HTTP Request: http://legacy/RealWorldStocks.Web/Stocks/GetSnapshots?symbols=MSFT&amp;amp;symbols=NOK&amp;amp;symbols=AAPL&amp;amp;isTrial=False&amp;amp;clientVersion=1.0.0.0
INFO: HTTP Response: [{"Symbol":"MSFT","Company":"Microsoft Corpora","OpeningPrice":27.08,"LastPrice":27.19,"DaysChange":0.03,"DaysChangePercentFormatted":"+0.11%","DaysChangeFormatted":"+0.03","DaysRangeMin":0,"DaysRangeMax":0,"Volume":56897792,"PreviousClose":27.16}]&lt;/pre&gt;

&lt;h4&gt; &lt;/h4&gt;

&lt;h3&gt;step 5: Create the client-side API for communicating with the server&lt;/h3&gt;

&lt;p&gt;Calling an HTTP endpoint is as simple as declaring the URL along with any query string parameters to customize the request. Since we definitely don’t want to spread this implementation detail all through our code-base, we write a simple abstraction which handles the following:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Declares what type of model is returned from the server by defining the method as HttpRequest&amp;lt;T&amp;gt; where T is what is returned from the server &lt;/li&gt;

  &lt;li&gt;Declares the base URL path for the request, e.g., “Stocks/GetSnapshot” &lt;/li&gt;

  &lt;li&gt;Builds up any query string params that will be sent with the request. &lt;/li&gt;

  &lt;li&gt;Essentially, it builds a string like the following, and automatically parses the JSON into the type of Model we expect from the server: &lt;a href="http://localhost/RealWorldStocks.Web/Stocks/GetSnapshots?symbols=MSFT&amp;amp;symbols=NOK"&gt;http://localhost/RealWorldStocks.Web/Stocks/GetSnapshots?symbols=MSFT&amp;amp;symbols=NOK&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class StocksWebService : HttpService, IStocksWebService
{
    public StocksWebService()
    {
#if DEBUG
        BaseUrl = DynamicLocalhost.ReplaceLocalhost("http://localhost/RealWorldStocks.Web/");
#else
        BaseUrl = "http://services.mydomain.com/v1/";
#endif
    }

    public HttpRequest&amp;lt;StockSnapshot&amp;gt; GetSnapshot(string symbol)
    {
        var queryString = new QueryString
                                {
                                    {"symbol", symbol}
                                };

        return CreateHttpRequest&amp;lt;StockSnapshot&amp;gt;("Stocks/GetSnapshot", queryString);
    }

    public HttpRequest&amp;lt;IEnumerable&amp;lt;StockSnapshot&amp;gt;&amp;gt; GetWatchListSnapshots()
    {
        var queryString = new QueryString();
        queryString.AddMany("symbols", WatchList.Current.Select(m =&amp;gt; m.Symbol));

        return CreateHttpRequest&amp;lt;IEnumerable&amp;lt;StockSnapshot&amp;gt;&amp;gt;("Stocks/GetSnapshots", queryString);
    }

    public HttpRequest&amp;lt;IEnumerable&amp;lt;News&amp;gt;&amp;gt; GetNewsForWatchList()
    {
        var queryString = new QueryString();
        queryString.AddMany("symbols", WatchList.Current.Select(m =&amp;gt; m.Symbol));

        return CreateHttpRequest&amp;lt;IEnumerable&amp;lt;News&amp;gt;&amp;gt;("Stocks/GetNews", queryString);
    }
}&lt;/pre&gt;

&lt;h4&gt;DynamicLocalhost&lt;/h4&gt;

&lt;p&gt;DynamicLocalhost is a NuGet package I wrote to make debugging services on multiple machines with multiple developers easier. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/10/DynamicLocalhost-NuGet-Package-for-Windows-Phone.aspx" target="_blank"&gt;You can read more about the DynamicLocalhost package here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;step 6: Bringing it all together – Orchestrating the request from the ViewModel&lt;/h3&gt;

&lt;p&gt;It seems like a lot of code just to get this far, but most of this stuff is infrastructure that I just copy/paste into all of my projects. Without these infrastructure concerns I am able to just start writing the controller methods, and defining the client-side API for the requests. From there I just start using it from the ViewModel, all in a matter of 5 minutes.&lt;/p&gt;

&lt;h4&gt;Coroutines - Making async sexy since C# 2&lt;/h4&gt;

&lt;p&gt;As a quick aside I wanted to talk about coroutines. One of these amazing things was first introduced to me in Rob Eisenberg’s Build your own MVVM Framework talk from MIX ‘10. It was an excellent talk, and the inspiration for the Caliburn.Micro project.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Coroutine&lt;/strong&gt; is the &lt;strong&gt;UpdateWatchList&lt;/strong&gt; method below.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Show the global BusyIndictator with a friendly loading message &lt;/li&gt;

  &lt;li&gt;Making an &lt;strong&gt;async &lt;/strong&gt;HTTP Request &lt;/li&gt;

  &lt;li&gt;When we get the HTTP Response, check if it had an error, if so show a friendly MessageBox &lt;/li&gt;

  &lt;li&gt;If it returned successfully then we bind the data to our ObservableCollection so the UI will update itself &lt;/li&gt;

  &lt;li&gt;Hide the global BusyIndicator &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;This is actually a lot of stuff going on, and it’s async. Notice how there are no lambdas, no callbacks, no anonymous method delegates? It’s really quite elegant, and has suited me very nicely while I patiently wait for C# 5 and official async compiler support.&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;private IEnumerable&amp;lt;IResult&amp;gt; UpdateWatchList()
{
    BusyIndictator.Show("Loading watch list...");
    var request = _stocksWebService.GetWatchListSnapshots().Execute();
    yield return request;

    if (!request.Response.HasError)
    {
        WatchList.RepopulateObservableCollection(request.Response.Model);
    }
    else
    {
        MessageBox.Show("We had troubles updating your watch list, please try again in a few moments", 
            "Unable to contact server", MessageBoxButton.OK);
    }

    yield return BusyIndictator.HideResult();
}&lt;/pre&gt;

&lt;h3&gt; &lt;/h3&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;That covered a lot of stuff. My hope is that it wasn’t too daunting or overwhelming – a lot of this code really is reusable infrastructure stuff that can just be pasted into any project and used right-away. I would love feedback from people, particularly those who choose a different path, like WCF and Service References.&lt;/p&gt;

&lt;div class="update"&gt;
  &lt;h3&gt;Want some more RealWorldWPDev?&lt;/h3&gt;

  &lt;h1&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx"&gt;View the Series Introduction and Outline&lt;/a&gt;&lt;/h1&gt;
&lt;/div&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:591ab686-ae9d-4297-a986-92b8ef5da8e7" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/realworldwpdev" rel="tag"&gt;realworldwpdev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/94.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/11/01/RealWorldWPDev-Part-5-Creating-and-Consuming-Web-Services.aspx</guid>
            <pubDate>Tue, 01 Nov 2011 06:19:12 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/11/01/RealWorldWPDev-Part-5-Creating-and-Consuming-Web-Services.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/94.aspx</wfw:commentRss>
        </item>
        <item>
            <title>RealWorldWPDev Part 4: The Panorama</title>
            <link>http://www.matthidinger.com/archive/2011/10/21/RealWorldWPDev-Part-4-The-Panorama.aspx</link>
            <description>&lt;div class="update"&gt;   &lt;h3&gt;Series Introduction and Outline&lt;/h3&gt;    &lt;p&gt;This series is going to walk through building a polished, functioning Windows Phone app from start to finish. The app is called Realworld Stocks and the &lt;a href="http://realworldwpdev.codeplex.com/" target="_blank"&gt;full source code will be available on CodePlex&lt;/a&gt; as the series progresses. I’ll be using Mercurial to encourage forking and maybe even pull requests from developers who want to contribute their own real-world solutions.&lt;/p&gt;    &lt;h1&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx"&gt;View the Series Introduction and Outline&lt;/a&gt;&lt;/h1&gt; &lt;/div&gt;  &lt;h2&gt;The windows phone panorama &lt;/h2&gt;  &lt;h2&gt;   &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 6px; padding-right: 0px; display: inline; float: right; padding-top: 0px" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:c50bca65-c214-4f87-be5f-6164a8422c20" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;object width="573" height="429"&gt;&lt;param name="movie" value="http://www.youtube.com/v/svlh2D_zFRw?hl=en&amp;amp;hd=1" /&gt;&lt;embed src="http://www.youtube.com/v/svlh2D_zFRw?hl=en&amp;amp;hd=1" type="application/x-shockwave-flash" width="573" height="429" /&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt; &lt;/h2&gt;  &lt;p&gt;Many apps lend themselves nicely to a Windows Phone Panorama. &lt;a href="http://www.matthidinger.com/articles/projects.aspx" target="_blank"&gt;CTA Watch&lt;/a&gt; looks similar but it’s actually a Pivot with a background image. After going back and forth for a bit with Real-world Stocks I decided that the panorama looked pretty nice and went with it.&lt;/p&gt;  &lt;p&gt;Thanks again &lt;a href="http://twitter.com/templarian" target="_blank"&gt;@Templarian&lt;/a&gt; for the background! Be sure to hit him up if you’re in need of a great designer who actually gets metro!&lt;/p&gt;  &lt;p&gt;This post is going to cover a lot of topics so I will do my best to whet your appetite, but please be sure to &lt;strong&gt;&lt;a href="http://realworldwpdev.codeplex.com/SourceControl/list/changesets" target="_blank"&gt;Download the Code&lt;/a&gt; &lt;/strong&gt;and check out the app for yourself! The code should be pretty easy to follow as you get more familiar with how Caliburn does things.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;h3&gt;What helps make a great experience?&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;Lazy load sections &lt;strong&gt;after&lt;/strong&gt; the user has swiped to them&lt;/li&gt;    &lt;li&gt;Panorama animations take ~0.5 seconds; don’t run your code until the animation is finished to prevent stuttering&lt;/li&gt;    &lt;li&gt;Show a nice BusyIndictator with friendly messages for each panorama section&lt;/li&gt;    &lt;li&gt;Customize the app bar buttons depending on which panorama section is active&lt;/li&gt;    &lt;li&gt;The News section show time relative dates (just now, 2 hours ago, etc) &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Disclaimer&lt;/h3&gt;  &lt;p&gt;This entire series assumes a basic understanding of Silverlight and MVVM. If you aren’t familiar with these topics then I am hopeful that you can still follow along, but you may need to do some further reading outside of this to cover the fundamentals and framework primitives. That said, the following post is going to remain fairly high level and try to let the source code speak for itself. I am intentionally not going to deep-dive into topics that are covered elsewhere. &lt;/p&gt;  &lt;h4&gt;Documentation&lt;/h4&gt;  &lt;p&gt;Caliburn.Micro has great documentation. Check out the following links if you’re looking to deep dive into anything covered here.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://caliburnmicro.codeplex.com/documentation" target="_blank"&gt;Caliburn.Micro Documentation&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://caliburnmicro.codeplex.com/wikipage?title=Working%20with%20Windows%20Phone%207%20v1.1&amp;amp;referringTitle=Documentation" target="_blank"&gt;Working with Windows Phone 7&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;h3&gt;MVVM Recap&lt;/h3&gt;  &lt;p&gt;MVVM is covered everywhere, so all I will say about here is the following – it stands for Model-View-ViewModel.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;ViewModels&lt;/strong&gt; are just regular classes. In Caliburn many of them inherit from &lt;strong&gt;Screen&lt;/strong&gt;. They provide the logic for your View, including what data should be displayed, and what code should execute when actions are taken on the view (like Button clicks) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Views&lt;/strong&gt; are your standard XAML artifacts, like Pages and UserControls. In MVVM they rely heavily on the rich Binding support in XAML/Silverlight to interact with the ViewModel that it is bound to. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Model&lt;/strong&gt; is everything else. &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;The Anatomy of the HomeViewModel&lt;/h3&gt;  &lt;p&gt;Now then, the HomeViewModel is a great starting point.  At the time of the writing you can see the &lt;a href="http://realworldwpdev.codeplex.com/SourceControl/changeset/view/ec2bb5b9a273#src%2fRealWorldStocks.Client.UI%2fViewModels%2fHome%2fHomeViewModel.cs" target="_blank"&gt;full HomeViewModel source.&lt;/a&gt; It’s actually a pretty simple class for doing a whole lot of stuff for us. Let’s dissect this bad boy.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;pre class="brush: c-sharp; toolbar: false"&gt;public class HomeViewModel : Conductor&amp;lt;IScreen&amp;gt;.Collection.OneActive, IRefreshable, IAppBarController
{
    private readonly INavigationService _navigation;

    public HomeViewModel(INavigationService navigation, HomeWatchListViewModel watchList, HomeNewsViewModel news,
                            HomeQuoteViewModel quote)
    {
        _navigation = navigation;
        Items.Add(watchList);
        Items.Add(news);
        Items.Add(quote);
    }
}&lt;/pre&gt;

&lt;h4&gt; &lt;/h4&gt;

&lt;h4&gt;Conductor&lt;/h4&gt;

&lt;p&gt;A Panorama is normally comprised of 3-4 individual panes. Most of the time these panes are completely isolated and have nothing to do with each other; aside from being housed within the same container. If you actually think about it like that, then you can come up with some highly maintainable and extensible designs. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Rather than creating one giant HomeViewModel that is responsible for controlling every single out of those panes, let’s instead give our HomeViewModel the responsibility it deserves: conducting each of these panes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You’ll notice that HomeViewModel inherits from &lt;strong&gt;Conductor&amp;lt;IScreen&amp;gt;&lt;/strong&gt;. This provides some great infrastructure for us right out of the box. First up, it exposes a property from the base class of time &lt;strong&gt;IObservableCollectio&amp;lt;IScreen&amp;gt; &lt;/strong&gt;called &lt;strong&gt;Items.&lt;/strong&gt; In the code above, we are using this Items collection to add our Children View Models. It also handled Activation of our child items, telling them what to Initialize themselves – this lends itself amazingly to lazy loading the panorama panes, discussed at the end of this post.&lt;/p&gt;

&lt;h4&gt;How is this used in HomeView.xaml?&lt;/h4&gt;

&lt;p&gt;So we have a HomeViewModel, with an &lt;strong&gt;Items &lt;/strong&gt;property that now contains 3 &lt;strong&gt;other&lt;/strong&gt; ViewModels. How exactly is this used in our view? In 2 ways:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The Panorama control inherits from &lt;strong&gt;ItemsControl, &lt;/strong&gt;which means it supports binding to collections just like a &lt;strong&gt;ListBox &lt;/strong&gt;does. In the end, since our “Items” are just ViewModels themselves, they are in turn rendered as Views in the Panorama. This concept is the basis of known as building &lt;strong&gt;Composite Views&lt;/strong&gt;. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;No ItemsSource=”{Binding Items}”??&lt;/strong&gt; You may notice there is no explicit binding in the XAML below – Caliburn is a &lt;em&gt;Convention over Configuration &lt;/em&gt;framework (if you want it to be!). This means it will by default use its &lt;strong&gt;x:Name&lt;/strong&gt; and look for a property on the ViewModel that it can bind itself to. &lt;em&gt;If you prefer to explicitly bind your Views then please do so! The conventions are entirely optional.&lt;/em&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;pre class="brush: xhtml; toolbar: false"&gt;&amp;lt;controls:Panorama x:Name="Items" Title="{StaticResource AppNameUpper}"&amp;gt;
    &amp;lt;controls:Panorama.HeaderTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;TextBlock Text="{Binding DisplayName}" /&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/controls:Panorama.HeaderTemplate&amp;gt;
&amp;lt;/controls:Panorama&amp;gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h4&gt;IOC / Constructor Injection&lt;/h4&gt;

&lt;p&gt;Now you might be wondering, in the HomeView I just created a constructor that takes 4 parameters, &lt;strong&gt;INavigationService&lt;/strong&gt;, &lt;strong&gt;HomeWatchListViewModel&lt;/strong&gt;, &lt;strong&gt;HomeNewsViewModel&lt;/strong&gt;, and &lt;strong&gt;HomeQuotesViewModel&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;When our HomeView.xaml is loaded, what is creating our HomeViewModel for us, and more importantly, how did it know how to pass these parameters to our constructor?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This concept is known as Inversion of Control. Our HomeViewModel relies on other classes to complete it’s job, but rather than being responsible for creating these dependencies itself, it externalizes that responsibility and simply declares &lt;em&gt;‘hey, I need these things! Framework, you give them to me!’&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you create new ViewModels and other services, you just need to register them in your &lt;strong&gt;AppBootstrapper&lt;/strong&gt;. A snippet can be seen below. Once these ViewModels are registered in the Bootstrapper, Caliburn will take care of the rest. &lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class AppBootstrapper : PhoneBootstrapper
{
    private PhoneContainer _container;

    protected override void Configure()
    {
        LogManager.GetLog = type =&amp;gt; new DebugLog();

        _container = new PhoneContainer(RootFrame);
        _container.RegisterPhoneServices();

        _container.Singleton&amp;lt;IStocksWebService, StocksWebService&amp;gt;();


        _container.Singleton&amp;lt;HomeViewModel&amp;gt;();
        _container.Singleton&amp;lt;HomeNewsViewModel&amp;gt;();
        _container.Singleton&amp;lt;HomeWatchListViewModel&amp;gt;();
        _container.Singleton&amp;lt;HomeQuoteViewModel&amp;gt;();
    }
}&lt;/pre&gt;

&lt;h3&gt;Let’s Talk Polish&lt;/h3&gt;

&lt;p&gt;The following concepts were used to create the full Panorama experience seen in the YouTube video. You may need to watch it more than once to notice the subtle attention to detail. &lt;/p&gt;

&lt;h4&gt;BusyIndicator&lt;/h4&gt;

&lt;p&gt;Mango improved panoramas in many ways. For one, the System Tray now has an Opacity property, so you can finally show the tray in a full screen panorama and it still looks great. Another big improvement is the native &lt;strong&gt;ProgressIndicator &lt;/strong&gt;experience. It’s built into the &lt;strong&gt;SystemTray&lt;/strong&gt; and interacts excellently to the rest of the tray, like hiding the loading message when the user taps it to see the clock. It also has some great out of the box animations.&lt;/p&gt;

&lt;p&gt;For our app I wanted a global hook into the ProgressIndicator from my ViewModels. To do so, I created a simple &lt;strong&gt;BusyIndicator.Show() &lt;/strong&gt;method which hooks right into the System Tray. You can use this API directly from your ViewModel in a very simple fashion. &lt;/p&gt;

&lt;p&gt;I will be going more into the BusyIndicator in a future post.&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public void RefreshData()
{
    BusyIndictator.Show("Loading watch list...");
    ThreadPool.QueueUserWorkItem(callback =&amp;gt;
    {
        Coroutine.BeginExecute(UpdateWatchList().GetEnumerator());
    });
}&lt;/pre&gt;

&lt;h4&gt;IRefreshable&lt;/h4&gt;

&lt;p&gt;Refreshing  data is very common in these types of apps. Acknowledging this I decided to create a simple &lt;strong&gt;IRefreshable&lt;/strong&gt; interface, which in our Conductor’s case, simply delegates along to the &lt;strong&gt;ActiveItem&lt;/strong&gt; (the currently active panorama pane ViewModel) and says &lt;em&gt;“Hey, do you know how to refresh data? If so, please proceed to do!” &lt;/em&gt;&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public void RefreshData()
{
    var refreshableChild = ActiveItem as IRefreshable;
    if (refreshableChild != null)
        refreshableChild.RefreshData();
}&lt;/pre&gt;

&lt;p&gt;Then, in the &lt;strong&gt;HomeWatchListViewModel&lt;/strong&gt; for example, it also implements &lt;strong&gt;IRefreshable&lt;/strong&gt;, and proceeds to refresh the current Watch List. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is another example of compositing pieces together to write really extensible code as our app progresses.&lt;/em&gt;&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public class HomeWatchListViewModel : Screen, IRefreshable
{
    public void RefreshData()
    {
        BusyIndictator.Show("Loading watch list...");
        ThreadPool.QueueUserWorkItem(callback =&amp;gt;
        {
            Coroutine.BeginExecute(UpdateWatchList().GetEnumerator());
        });
    }
}&lt;/pre&gt;

&lt;h4&gt;Polishing up the AppBar&lt;/h4&gt;

&lt;p&gt;If you look closely at the video, you will notice some careful consideration we needed on our home screen. Each swipe of the panorama changes the &lt;strong&gt;ApplicationBar&lt;/strong&gt; in some way.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Watch List shows 2 app bar buttons: Add and Refresh &lt;/li&gt;

  &lt;li&gt;News shows only 1 app bar button: Refresh &lt;/li&gt;

  &lt;li&gt;Lookup shows 0 app bar buttons, and it set it’s Mode to Minimized &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In order to achieve this I created a simple &lt;strong&gt;IAppBarController&lt;/strong&gt; interface and an &lt;strong&gt;AppBarHelper&lt;/strong&gt; class. To try and keep this post from getting too long I will be dedicating an entire article to this topic soon. In the mean time, please see the code if you want to see how it works!&lt;/p&gt;

&lt;h4&gt;WatermarkedTextbox and PriceChangeArrow&lt;/h4&gt;

&lt;p&gt;Again a keen eye may have noticed 2 other niceties on the home screen:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;PriceChangeArrow&lt;/strong&gt; – the price change arrow (showing positive or negative gains) had a little animation when the Watch List loaded. It’s a little thing but I think goes a long way to making the app feel polished and enjoyable. I will be blogging exactly how to create such a control in the future. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;WatermarkedTextBox&lt;/strong&gt; – this control I found from an open source Silverlight project and improved it a bit for Mango. I will be blogging in more detail about this control in the future. &lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;Lazy Loading the Panorama Panes and Keeping the Animations Fluid!&lt;/h4&gt;

&lt;p&gt;This is perhaps the most important part of the home screen, so I’m not entirely sure why I left it ‘til the end. In any event, high framerates are very important, and maintaining a nice fluid user experience throughout the app is crucial to getting those coveted 5-star rating.&lt;/p&gt;

&lt;p&gt;Caliburn Screens have a few important methods that you will want to override to make your app do something.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;OnInitialize&lt;/strong&gt; – Override this method to add logic which should execute only the first time that the screen is activated. After initialization is complete, IsInitialized will be true. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;OnActivate&lt;/strong&gt; – Override this method to add logic which should execute every time the screen is activated. After activation is complete, IsActive will be true. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;OnDeactivate&lt;/strong&gt; – Override this method to add custom logic which should be executed whenever the screen is deactivated or closed. The bool property will indicated if the deactivation is actually a close. After deactivation is complete, IsActive will be false. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;OnViewLoaded&lt;/strong&gt; – Since Screen implements IViewAware, it takes this as an opportunity to let you know when your view’s Loaded event is fired. Use this if you are following a SupervisingController or PassiveView style and you need to work with the view. This is also a place to put view model logic which may be dependent on the presence of a view even though you may not be working with the view directly. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="http://caliburnmicro.codeplex.com/wikipage?title=Screens%2c%20Conductors%20and%20Composition&amp;amp;referringTitle=Documentation" target="_blank"&gt;Read more about Screens, Conductors, and Composition&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition to the above events, a while ago I came up with &lt;strong&gt;OnViewReady&lt;/strong&gt; and submitted the patch to Rob. The idea is simple: fire after &lt;strong&gt;OnViewLoaded&lt;/strong&gt;, but also after the first &lt;strong&gt;LayoutUpdated&lt;/strong&gt;; meaning the base UI is rendered, so feel free to start doing hogging CPU! By waiting until &lt;strong&gt;OnViewReady &lt;/strong&gt;you make sure that your code doesn’t start running and burning precious CPU cycles while the platform is trying to finish starting up (and animating things into view, like the panorama).&lt;/p&gt;

&lt;h4&gt;Workaround to OnViewReady&lt;/h4&gt;

&lt;p&gt;At the time of this writing, in the 1.2 NuGet package, I could not get it to behave correctly, so instead opted for a slightly uglier workaround. Essentially this creates a background thread, and then sleeps for 1 second in that thread, before starting to work. 1 second should be plenty of time for any base loading and animations to complete.&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;protected override void OnInitialize()
{
    RefreshData();
}

public void RefreshData()
{
    BusyIndictator.Show("Loading watch list...");

    // TODO: Move this to OnViewReady in CM 1.3
    // For now sleep for a bit to let the panorama load smoothly
    ThreadPool.QueueUserWorkItem(callback =&amp;gt;
    {
        Thread.Sleep(1000);
        Coroutine.BeginExecute(UpdateWatchList().GetEnumerator());
    });
}&lt;/pre&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;Kudos if you followed all of that! This one took me a little while to write and contains a lot of stuff, but it also leaves the door open for &lt;strong&gt;a whole lot more &lt;/strong&gt;to talk about in the future!&lt;/p&gt;

&lt;p&gt;Please post any questions you have here, and again, please pull down the code and follow along as we go. Feedback is greatly appreciated!&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div class="update"&gt;
  &lt;h3&gt;Want some more RealWorldWPDev?&lt;/h3&gt;

  &lt;h1&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx"&gt;View the Series Introduction and Outline&lt;/a&gt;&lt;/h1&gt;
&lt;/div&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:419f8836-4729-4b9b-9cdb-a7a685671777" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/realworldwpdev" rel="tag"&gt;realworldwpdev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/93.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/10/21/RealWorldWPDev-Part-4-The-Panorama.aspx</guid>
            <pubDate>Fri, 21 Oct 2011 06:33:15 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/10/21/RealWorldWPDev-Part-4-The-Panorama.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/93.aspx</wfw:commentRss>
        </item>
        <item>
            <title>RealWorldWPDev Part 3: Caliburn.Micro and Application Infrastructure</title>
            <link>http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-3-Caliburn-Micro-and-Application-Infrastructure.aspx</link>
            <description>&lt;div class="update"&gt;   &lt;h3&gt;Series Introduction and Outline&lt;/h3&gt;    &lt;p&gt;This series is going to walk through building a polished, functioning Windows Phone app from start to finish. The app is called Realworld Stocks and the &lt;a href="http://realworldwpdev.codeplex.com/" target="_blank"&gt;full source code will be available on CodePlex&lt;/a&gt; as the series progresses. I’ll be using Mercurial to encourage forking and maybe even pull requests from developers who want to contribute their own real-world solutions.&lt;/p&gt;    &lt;h1&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx"&gt;View the Series Introduction and Outline&lt;/a&gt;&lt;/h1&gt; &lt;/div&gt;  &lt;h2&gt;Caliburn.Micro&lt;/h2&gt;  &lt;p&gt;Many Windows Phone Applications use a lightweight MVVM framework for basic infrastructure services. Realworld Stocks is going to use Caliburn.Micro. I have had great success with Caliburn.Micro in my previous Windows Phone and Silverlight apps. CM was created by &lt;a href="http://twitter.com/eisenbergeffect" target="_blank"&gt;Rob Eisenberg&lt;/a&gt; and is under active development and has a great community and following.&lt;/p&gt;  &lt;p&gt;This article is going to walk through a lot of Caliburn.Micro setup, but for the full documentation please see the &lt;a href="http://caliburnmicro.codeplex.com/documentation" target="_blank"&gt;official project documentation&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Installing Caliburn.Micro from NuGet&lt;/h3&gt;  &lt;p&gt;If you’ve been following along then you already have NuGet installed. If not, please see &lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-2-File-ndashgt-New-Project.aspx" target="_blank"&gt;Part 2: File –&amp;gt; New Project&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Caliburn.Micro needs to be installed into both the &lt;strong&gt;RealWorldStocks.Client.Core&lt;/strong&gt; and the &lt;strong&gt;RealWorldStocks.Client.UI&lt;/strong&gt; projects.&lt;/p&gt;  &lt;h4&gt;From the Package Manager Console&lt;/h4&gt;  &lt;p&gt;To get Caliburn.Micro you can open up the Package Manager console and type the following, &lt;em&gt;but make sure you select the right Default Project. &lt;strong&gt;You must install CM into both .Core and .UI projects!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/a6c05f249a11_E881/image_6.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/a6c05f249a11_E881/image_thumb_2.png" width="767" height="91" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;From the Manage NuGet Packages UI&lt;/h4&gt;  &lt;p&gt;Alternatively you can right-click on both Projects from the Solution Explorer and select “Manage NuGet Packages…”, then click the Online pane and search for Caliburn.Micro. &lt;strong&gt;&lt;em&gt;You must install CM into both .Core and .UI projects!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/a6c05f249a11_E881/image_thumb%5B19%5D_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" id="hero" title="image_thumb[19]" border="0" alt="image_thumb[19]" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/a6c05f249a11_E881/image_thumb%5B19%5D_thumb.png" width="686" height="369" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;h3&gt;Finishing Caliburn Setup&lt;/h3&gt;  &lt;p&gt;Once Caliburn.Micro finishes installing it should open up a web page with instructions to finish the configuration. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;&lt;a href="http://caliburnmicro.codeplex.com/wikipage?title=Nuget&amp;amp;referringTitle=Documentation" target="_blank"&gt;Follow the instructions that opened up in Visual Studio&lt;/a&gt;&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;Make sure your &lt;strong&gt;App.xaml&lt;/strong&gt; and &lt;strong&gt;App.xaml.cs&lt;/strong&gt; are cleared out from the instructions above! &lt;/li&gt;    &lt;li&gt;Delete &lt;strong&gt;MainPage.xaml &lt;/strong&gt;&lt;/li&gt;    &lt;li&gt;In &lt;strong&gt;RealworldStocks.Client.UI&lt;/strong&gt;, create a new folder called &lt;strong&gt;Framework&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;Delete &lt;strong&gt;AppBootstrapper.cs &lt;/strong&gt;&lt;/li&gt;    &lt;li&gt;Create a new &lt;strong&gt;AppBootstrapper.cs&lt;/strong&gt; file in the &lt;strong&gt;Framework &lt;/strong&gt;folder &lt;/li&gt;    &lt;li&gt;Paste the following code into &lt;strong&gt;AppBoostrapper.cs&lt;/strong&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;pre class="brush: c-sharp; toolbar: false"&gt;using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using Caliburn.Micro;
using Microsoft.Phone.Controls;
using RealWorldStocks.Client.UI.ViewModels.Home;

namespace RealWorldStocks.Client.UI.Framework
{
	public class AppBootstrapper : PhoneBootstrapper
	{
        PhoneContainer _container;

        protected override void Configure()
        {
            _container = new PhoneContainer(RootFrame);

            _container.RegisterPhoneServices();
            _container.Singleton&amp;lt;HomeViewModel&amp;gt;();
        }

        protected override void OnUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (Debugger.IsAttached)
            {
                Debugger.Break();
                e.Handled = true;
            }
            else
            {
                MessageBox.Show("An unexpected error occured, sorry about the troubles.", "Oops...", MessageBoxButton.OK);
                e.Handled = true;
            }

            base.OnUnhandledException(sender, e);
        }

        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;h4&gt; &lt;/h4&gt;

&lt;p&gt;8. Since we moved the &lt;strong&gt;AppBoostrapper&lt;/strong&gt; into the &lt;strong&gt;RealWorldStocks.Client.UI.Framework&lt;/strong&gt; namespace we need to update our &lt;strong&gt;App.xaml&lt;/strong&gt;. Paste the following into your &lt;strong&gt;App.xaml&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="brush: xhtml; toolbar: false"&gt;&amp;lt;Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:Framework="clr-namespace:RealWorldStocks.Client.UI.Framework"
             x:Class="RealWorldStocks.Client.UI.App"&amp;gt;
    &amp;lt;Application.Resources&amp;gt;
        &amp;lt;ResourceDictionary&amp;gt;
            &amp;lt;ResourceDictionary.MergedDictionaries&amp;gt;
                &amp;lt;ResourceDictionary Source="Assets/Constants.xaml"/&amp;gt;
                &amp;lt;ResourceDictionary Source="Assets/Styles.xaml"/&amp;gt;
                &amp;lt;ResourceDictionary Source="Assets/Converters.xaml"/&amp;gt;
            &amp;lt;/ResourceDictionary.MergedDictionaries&amp;gt;
            
            &amp;lt;Framework:AppBootstrapper x:Key="bootstrapper" /&amp;gt;
        &amp;lt;/ResourceDictionary&amp;gt;
    &amp;lt;/Application.Resources&amp;gt;
&amp;lt;/Application&amp;gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;Working around a small NuGet bug&lt;/h3&gt;

&lt;p&gt;At the time of this writing there appears to be a bug in the NuGet package which thinks my project is a Silverlight project (instead of Windows Phone). &lt;/p&gt;

&lt;p&gt;If the NuGet package created a ShellViewModel.cs in your project, then you will need to take the following steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Delete ShellViewModel.cs &lt;/li&gt;

  &lt;li&gt;Delete IShell.cs &lt;/li&gt;

  &lt;li&gt;Delete ShellView.xaml &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Application Infrastructure&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/a6c05f249a11_E881/image_4.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/a6c05f249a11_E881/image_thumb_1.png" width="293" height="636" /&gt;&lt;/a&gt;The final pieces of our infrastructure include the following:&lt;/p&gt;

&lt;h3&gt;Value Converters&lt;/h3&gt;

&lt;p&gt;I have a set of IValueConverters that I have used on all of my Windows Phone projects. They can be viewed from the &lt;a href="http://realworldwpdev.codeplex.com/SourceControl/list/changesets" target="_blank"&gt;CodePlex source code&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Assets&lt;/h3&gt;

&lt;p&gt;Assets are a set of ResourceDictionaries that contain the resources used throughout the application. They can be viewed from the &lt;a href="http://realworldwpdev.codeplex.com/SourceControl/list/changesets" target="_blank"&gt;CodePlex source code&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Constants.xaml&lt;/h4&gt;
Defines variables like “AppName” so it can be used on pages 

&lt;br /&gt;&amp;lt;TextBlock Text=”{StaticResource AppName}” /&amp;gt; 

&lt;h4&gt;Converters.xaml&lt;/h4&gt;

&lt;p&gt;Defines the set of converters used in our project&lt;/p&gt;

&lt;h4&gt;Styles.xaml&lt;/h4&gt;

&lt;p&gt;Defines a set of reusable styles&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;ViewModels&lt;/h3&gt;

&lt;p&gt;ViewModels define the logic for all of our views. They take advantage of XAML’s great binding mechanisms and Caliburn’s ActionMessages to control how our views behave. Later in the series we will deep dive into Views and ViewModels. &lt;/p&gt;

&lt;p&gt;To get started, make sure you have a &lt;strong&gt;ViewModels &lt;/strong&gt;folder, then right-click and select &lt;strong&gt;New Item…&lt;/strong&gt;, add a &lt;strong&gt;Class&lt;/strong&gt; file called &lt;strong&gt;HomeViewModel.cs 
    &lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;HomeViewModel &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;Screen
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public &lt;/span&gt;HomeViewModel()
    {
        DisplayName = &lt;span style="color: #a31515"&gt;"Home"&lt;/span&gt;;
    }   
}&lt;/pre&gt;

&lt;h3&gt;Views&lt;/h3&gt;

&lt;p&gt;Views are your .xaml Pages and UserControls. Later in the series we will deep dive into Views and ViewModels. &lt;/p&gt;

&lt;p&gt;To get started, make sure you have a &lt;strong&gt;Views&lt;/strong&gt; folder, then right-click and select &lt;strong&gt;New Item…&lt;/strong&gt;, add a &lt;strong&gt;Windows Phone Portrait Page &lt;/strong&gt;called &lt;strong&gt;HomeView.xaml&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;WMAppManifest.xml&lt;/h3&gt;

&lt;p&gt;Lastly, you need to update the WMAppManifest to tell it what page should load when the app is launched. &lt;/p&gt;

&lt;p&gt;Open &lt;strong&gt;WMAppManifest.xml&lt;/strong&gt; and set the &lt;strong&gt;NavigationPage&lt;/strong&gt; to your primary page&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;DefaultTask &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;_default&lt;/span&gt;" &lt;span style="color: red"&gt;NavigationPage&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;Views/HomeView.xaml&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;Run it!&lt;/h2&gt;

&lt;p&gt;Now we’re getting somewhere. We have the majority of our application infrastructure in place and have our first View and ViewModel. If you press F5 now it should launch right into the HomeView! &lt;/p&gt;

&lt;h4&gt;Problems?&lt;/h4&gt;

&lt;p&gt;If the app exits immediately after launching check the following:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;WPAppManifest NavigationPage points at a .xaml file that actually exists &lt;/li&gt;

  &lt;li&gt;Make sure you App.xaml.cs has nothing but InitializeComponent() and App.xaml only has the Bootstrapper in it. &lt;a href="http://caliburnmicro.codeplex.com/wikipage?title=Nuget&amp;amp;referringTitle=Documentation" target="_blank"&gt;See the Caliburn.Micro documentation for more&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;Check the namespaces in your ViewModels and Views and make sure ViewModels and Views namespaces match up &lt;/li&gt;

  &lt;li&gt;For further Caliburn troubleshooting check the &lt;a href="http://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Conventions&amp;amp;referringTitle=Documentation" target="_blank"&gt;Caliburn.Micro documentation&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;div class="update"&gt;
  &lt;h3&gt;Want some more RealWorldWPDev?&lt;/h3&gt;

  &lt;h1&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx"&gt;View the Series Introduction and Outline&lt;/a&gt;&lt;/h1&gt;
&lt;/div&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:d60ee7e9-fa8f-42fd-9e39-9719b33d4ae3" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/realworldwpdev" rel="tag"&gt;realworldwpdev&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/91.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-3-Caliburn-Micro-and-Application-Infrastructure.aspx</guid>
            <pubDate>Sun, 16 Oct 2011 23:27:13 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-3-Caliburn-Micro-and-Application-Infrastructure.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/91.aspx</wfw:commentRss>
        </item>
        <item>
            <title>RealWorldWPDev Part 2: File &amp;ndash;&amp;gt; New Project</title>
            <link>http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-2-File-ndashgt-New-Project.aspx</link>
            <description>&lt;div class="update"&gt;   &lt;h3&gt;Series Introduction and Outline&lt;/h3&gt;    &lt;p&gt;This series is going to walk through building a polished, functioning Windows Phone app from start to finish. The app is called Realworld Stocks and the &lt;a href="http://realworldwpdev.codeplex.com/" target="_blank"&gt;full source code will be available on CodePlex&lt;/a&gt; as the series progresses. I’ll be using Mercurial to encourage forking and maybe even pull requests from developers who want to contribute their own real-world solutions.&lt;/p&gt;    &lt;h1&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx"&gt;View the Series Introduction and Outline&lt;/a&gt;&lt;/h1&gt; &lt;/div&gt;  &lt;h2&gt;Before you begin, install NuGet!&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://nuget.org" target="_blank"&gt;NuGet&lt;/a&gt; is a Visual Studio extension that makes it easy to install and update open source libraries and tools in Visual Studio. It can be installed directly from within Visual Studio and only takes a minute.&lt;/p&gt;  &lt;p&gt;In Visual Studio: Tools –&amp;gt; Extension Manager and find NuGet&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Real-world-Windows-Phone-File--New-Proje_11135/image_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Real-world-Windows-Phone-File--New-Proje_11135/image_thumb.png" width="670" height="408" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt; &lt;/h2&gt;  &lt;h2&gt;Defining our Solution Structure&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Real-world-Windows-Phone-File--New-Proje_11135/image_12.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Real-world-Windows-Phone-File--New-Proje_11135/image_thumb_5.png" width="274" height="652" /&gt;&lt;/a&gt;For our solution we are going to create 3 Client-side projects and 1 Server-side project. These projects are described below. The Solution Explorer to the right should help give you a sense of how our solution will start to develop, but for now, let’s just get the basics running.&lt;/p&gt;  &lt;h3&gt;Creating the Windows Phone Projects&lt;/h3&gt;  &lt;h4&gt;RealWorldStocks.Client.Core&lt;/h4&gt;  &lt;p&gt;&lt;em&gt;&lt;strong&gt;Windows Phone Class Library&lt;/strong&gt;&lt;/em&gt; &lt;/p&gt;  &lt;p&gt;This project contains all of our core (non-UI) client-side functionality: Data Models, Helpers, HTTP Web Service clients, etc &lt;/p&gt;  &lt;h4&gt; &lt;/h4&gt;  &lt;h4&gt;RealWorldStocks.Client.UI &lt;/h4&gt;  &lt;p&gt;&lt;em&gt;&lt;strong&gt;Windows Phone Application&lt;/strong&gt;&lt;/em&gt; &lt;/p&gt;  &lt;p&gt;&lt;em&gt;References RealWorldStocks.Client.Core&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;This project holds all UI-specific functionality for our application: Assets, Styles, ViewModels, Views (Pages and UserControls), etc&lt;/p&gt;  &lt;h4&gt; &lt;/h4&gt;  &lt;h4&gt;RealWorldStocks.Client.BackgroundAgent&lt;/h4&gt;  &lt;p&gt;&lt;em&gt;&lt;strong&gt;Windows Phone Scheduled Task Agent&lt;/strong&gt;&lt;/em&gt; &lt;/p&gt;  &lt;p&gt;&lt;em&gt;References RealWorldStocks.Client.Core&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;The periodic task project that will eventually update our Live Tiles in the background every 30 minutes&lt;/p&gt;  &lt;h3&gt; &lt;/h3&gt;  &lt;h3&gt;Creating the Backend Services&lt;/h3&gt;  &lt;h4&gt;RealWorldStocks.Web&lt;/h4&gt;  &lt;p&gt;&lt;em&gt;&lt;strong&gt;ASP.NET MVC 2 Application&lt;/strong&gt;&lt;/em&gt; &lt;/p&gt;  &lt;p&gt;This project exposes our server side endpoints. I chose MVC for service simplicity; it’s very easy to create HTTP GET Routes with query string model binding and returning JSON out of the box. &lt;/p&gt;  &lt;h3&gt; &lt;/h3&gt;  &lt;h2&gt;Run it!&lt;/h2&gt;  &lt;p&gt;At this point we can F5 our project and marvel at our progress! In the next part we will start giving it some signs of life.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;div class="update"&gt;   &lt;h3&gt;Want some more RealWorldWPDev?&lt;/h3&gt;    &lt;h1&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx"&gt;View the Series Introduction and Outline&lt;/a&gt;&lt;/h1&gt; &lt;/div&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:84877480-aaf1-4678-8e56-80a2944850b3" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/realworldwpdev" rel="tag"&gt;realworldwpdev&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/90.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-2-File-ndashgt-New-Project.aspx</guid>
            <pubDate>Sun, 16 Oct 2011 21:56:41 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-2-File-ndashgt-New-Project.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/90.aspx</wfw:commentRss>
        </item>
        <item>
            <title>RealWorldWPDev Part 1: Introduction and Outline</title>
            <link>http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx</link>
            <description>&lt;div class="update"&gt;   &lt;h3&gt;Series Introduction and Outline&lt;/h3&gt;    &lt;p&gt;This series is going to walk through building a polished, functioning Windows Phone app from start to finish. The app is called Realworld Stocks and the &lt;a href="http://realworldwpdev.codeplex.com/" target="_blank"&gt;full source code will be available on CodePlex&lt;/a&gt; as the series progresses. I’ll be using Mercurial to encourage forking and maybe even pull requests from developers who want to contribute their own real-world solutions.&lt;/p&gt; &lt;/div&gt;  &lt;h2&gt;Realworld Stocks&lt;/h2&gt;  &lt;p&gt;The app we are creating is called Realworld Stocks, and this is what it looks like as of today. It’s not much yet, but hey, we’re only a few days in! Hopefully as the series progresses we’ll end up with a pretty nice looking stocks app ready for marketplace submission.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-0_C07A/image29.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-0_C07A/image29_thumb.png" width="200" height="381" /&gt;&lt;/a&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-0_C07A/image45.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-0_C07A/image45_thumb.png" width="200" height="381" /&gt;&lt;/a&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-0_C07A/image53.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-0_C07A/image53_thumb.png" width="200" height="381" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h2&gt;Series Outline&lt;/h2&gt;  &lt;p&gt;The following is a rough outline for how I expect this series to progress. Some parts will probably be added or removed (or broken out into smaller pieces). I will try really hard to write at least one post per week, so keep the pressure on if I start slacking!&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx"&gt;Introduction and Outline (this post)&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-2-File-ndashgt-New-Project.aspx"&gt;File –&amp;gt; New Project&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-3-Caliburn-Micro-and-Application-Infrastructure.aspx"&gt;Caliburn.Micro and Application Infrastructure&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.matthidinger.com/archive/2011/10/21/RealWorldWPDev-Part-4-The-Panorama.aspx"&gt;The Panorama&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.matthidinger.com/archive/2011/11/01/RealWorldWPDev-Part-5-Creating-and-Consuming-Web-Services.aspx" target="_blank"&gt;Creating and Consuming HTTP Web Services&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.matthidinger.com/archive/2011/12/04/RealWorldWPDev-Part-6-Page-Navigation-and-passing-Complex-State.aspx"&gt;Page Navigation and Passing Complex State&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;State Management with ApplicationSettings and GlobalData &lt;/li&gt;    &lt;li&gt;Versioning Application settings when users upgrade &lt;/li&gt;    &lt;li&gt;Properly supporting Trial Mode &lt;/li&gt;    &lt;li&gt;Creating Multiple Live Tiles &lt;/li&gt;    &lt;li&gt;Updating tiles with Background Agents &lt;/li&gt;    &lt;li&gt;Creating reusable Blend Behaviors &lt;/li&gt;    &lt;li&gt;Polishing the User Input Experience &lt;/li&gt;    &lt;li&gt;Creating an Announcements/News Page &lt;/li&gt;    &lt;li&gt;Caching frequent images automatically into isolated storage &lt;/li&gt;    &lt;li&gt;Submitting your App &lt;/li&gt;    &lt;li&gt;Creating the global BusyIndictator &lt;em&gt;(new topic!)&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;Creating re-usable and themable Controls &lt;em&gt;(new topic!)&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;Controlling the AppBar from the ViewModel &lt;em&gt;(new topic!)&lt;/em&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Extended Topics&lt;/h3&gt;  &lt;p&gt;The following parts will not apply to every app but are still worth posting about – most likely as an extended part of this series.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Adding some serious polish with Telerik RadControls for Windows Phone &lt;/li&gt;    &lt;li&gt;Persisting certain models into a database on the server using EF 4.1 Code-first &lt;/li&gt;    &lt;li&gt;Updating the current location with a Caliburn.Micro UploadLocationResult &lt;/li&gt;    &lt;li&gt;MVVM Visual State Management &lt;/li&gt;    &lt;li&gt;Theming your image resources using OpacityMask (bad) or convert to a Path with a Brush (good) &lt;/li&gt; &lt;/ol&gt;  &lt;h2&gt;Get the Source Code&lt;/h2&gt;  &lt;h4&gt;The full source code for this app will be be continuously updated on CodePlex at &lt;a title="http://realworldwpdev.codeplex.com" href="http://realworldwpdev.codeplex.com"&gt;&lt;font size="4"&gt;http://realworldwpdev.codeplex.com&lt;/font&gt;&lt;/a&gt;&lt;/h4&gt;  &lt;p&gt;There are 3 ways to get the source – the ideal way to keep updating as the app progresses would be to use TortoiseHg.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://realworldwpdev.codeplex.com/SourceControl/list/changesets"&gt;Browse the Source at CodePlex&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://realworldwpdev.codeplex.com/SourceControl/list/changesets"&gt;Download the latest Source&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Use TortoiseHg to pull down and update to the latest source automatically &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Mercurial with TortoiseHg&lt;/h3&gt;  &lt;p&gt;At first a new source control product may seem like a burden, but TortoiseHg is a great product, extremely easy to pull from a repository, and if you feel like it, a great time to learn about DVCS.&lt;/p&gt;  &lt;p&gt;For a great video tutorial on using Mercurial with CodePlex check out this &lt;a href="http://tekpub.com/view/dotnet-oss/7" target="_blank"&gt;free Tekpub Production: Mercurial With Codeplex!&lt;/a&gt; The TortoiseHg UI in the video is slightly out of date now, but should still give you a great starting point!&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://tortoisehg.bitbucket.org/"&gt;Download TortoiseHg&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;In Windows Explorer, create a new folder where you want to download the source to &lt;/li&gt;    &lt;li&gt;Right click in the window, from TortoiseHg select &lt;strong&gt;Clone…&lt;/strong&gt;       &lt;p&gt; &lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-0_C07A/SNAGHTML223cc484.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="SNAGHTML223cc484" border="0" alt="SNAGHTML223cc484" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-0_C07A/SNAGHTML223cc484_thumb.png" width="414" height="418" /&gt;&lt;/a&gt;&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;Type the following Source &lt;strong&gt;https://hg01.codeplex.com/realworldwpdev&lt;/strong&gt;&lt;strong&gt; &lt;/strong&gt;and press &lt;strong&gt;Clone&lt;/strong&gt;       &lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-0_C07A/image_4.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 7px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/RealWorldWPDev-Part-0_C07A/image_thumb_1.png" width="672" height="189" /&gt;&lt;/a&gt;&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;That’s it &lt;/li&gt; &lt;/ol&gt;  &lt;h4&gt; &lt;/h4&gt;  &lt;h2&gt;Special Thanks&lt;/h2&gt;  &lt;p&gt;The following people have contributed either directly or indirectly to this app and I’d like to offer a very special thanks to them!&lt;/p&gt;  &lt;p&gt;Thanks &lt;a href="http://twitter.com/templarian" target="_blank"&gt;@Templarian&lt;/a&gt; for the &lt;a href="http://templarian.com/project_windows_phone_icons/" target="_blank"&gt;iconography&lt;/a&gt;!&lt;/p&gt;  &lt;p&gt;Thanks &lt;a href="http://twitter.com/jeffwilcox" target="_blank"&gt;@JeffWilcox&lt;/a&gt; for the &lt;a href="http://www.jeff.wilcox.name/2011/04/focus-theme/" target="_blank"&gt;Samsung Focus Skin&lt;/a&gt;!&lt;/p&gt;  &lt;p&gt;Thanks &lt;a href="http://twitter.com/magnusvw"&gt;@magnusvw&lt;/a&gt; for connecting the backend to the Yahoo Finance API!&lt;/p&gt;  &lt;p&gt;I hope everyone enjoys this series! Feedback always welcome!&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:56e24e96-0123-4ad2-9f42-d048a6bc595e" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/realworldwpdev" rel="tag"&gt;realworldwpdev&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/89.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx</guid>
            <pubDate>Sun, 16 Oct 2011 20:45:49 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/10/16/RealWorldWPDev-Part-1-Introduction-and-Outline.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/89.aspx</wfw:commentRss>
        </item>
        <item>
            <title>DynamicLocalhost NuGet Package for Windows Phone</title>
            <link>http://www.matthidinger.com/archive/2011/10/10/DynamicLocalhost-NuGet-Package-for-Windows-Phone.aspx</link>
            <description>&lt;h2&gt;Why?&lt;/h2&gt;  &lt;h3&gt;Because I should be able to Get Latest and F5!&lt;/h3&gt;  &lt;p&gt;I think simplicity is a crucial measure of success in all software. I think being able to pull down the source code onto any developer machine and F5 is an important goal to strive for. Removing manual processes and streamlining the development workflow can yield huge productivity gains – especially when onboarding new developers. I believe databases should be provisioned and seeded automatically, all 3rd party libraries should be readily available in the repo, and any manual steps that must be memorized or documented should be avoided at all costs.&lt;/p&gt;  &lt;h3&gt;But this hasn’t been easy on a Windows Phone device&lt;/h3&gt;  &lt;p&gt;The aforementioned goals have been easily achievable in all of my projects except Windows Phone apps. A key component to this workflow is the magical variable known as &lt;strong&gt;localhost&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;When I F5 one of my MVC apps the project launches a browser to &lt;strong&gt;&lt;a href="http://localhost/MyProject"&gt;http://localhost/MyProject&lt;/a&gt;&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;When I F5 one of my Windows Phone apps in the emulator, it connects to my local IIS server at &lt;strong&gt;&lt;a href="http://localhost/MyProject"&gt;http://localhost/MyProject&lt;/a&gt;&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;When I F5 one of my Winodws Phone apps on a real device, things go awry. Localhost on the phone does not point to my development box, naturally, it points back to itself. Thus the predicament.&lt;/p&gt;  &lt;h3&gt;Let’s spike out a theory&lt;/h3&gt;  &lt;p&gt;Last night I had an idea, and decided to spike it out. What if I could store the URL to my Local IIS web services in a simple .txt file inside the XAP package? Then I could read this file during AppLaunch and store it for later. This part was easy, now for the magic. What if I could come up with a PreBuild step in Visual Studio, which could modify said .txt file during compile, and replace it’s contents with the Environment.MachineName? After a little fumbling around with a new Console Project, I had it working.&lt;/p&gt;  &lt;h3&gt;NuGet, PowerShell, meet DynamicLocalhost&lt;/h3&gt;  &lt;p&gt;I’ve been a long-time fan of NuGet. I have seen some amazingly creative things done with it beyond just simple library dumps. &lt;a href="http://blog.stevensanderson.com/2011/01/13/scaffold-your-aspnet-mvc-3-project-with-the-mvcscaffolding-package/"&gt;People much smarter than me&lt;/a&gt; are using PowerShell to create impressive scaffolding frameworks. Inspired, I cracked open my Windows PowerShell and MSBuild books and got to work. &lt;/p&gt;  &lt;p&gt;I ended up building the following:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;No assembly dependencies, only a single source file and a single .txt file get added to your project &lt;/li&gt;    &lt;li&gt;Created a MSBuild Task which will process the LocalHostname.txt file and fill it with the Environment.MachineName &lt;/li&gt;    &lt;li&gt;Modify the .csproj file to add my custom BeforeBuild target, which executes the Task above on each compile, thus ensuring the text file always has the correct machine name &lt;/li&gt; &lt;/ol&gt;  &lt;h2&gt;Ok that’s great, but how do I use it?&lt;/h2&gt;  &lt;p&gt;First you have to install the package. Make sure NuGet is installed.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/DynamicLocalhost_132CE/image_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/DynamicLocalhost_132CE/image_thumb.png" width="759" height="82" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The rest is up to you, to use the DynamicLocalhost class however you see fit. &lt;/p&gt;  &lt;p&gt;For me, in my WP7 projects I create a static ApplicationSettings class to use throughout the app. The comments below hopefully explain how it works. The only source code you ever check in says “localhost” – and will be dynamically replaced at compile-time to the actual developer’s machine name. This means that you are free to check in everything, get latest anytime you want, and never have to worry about someone accidently checking in their real machine’s URL, hampering your workflow.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;pre class="brush: c-sharp; toolbar: false"&gt;public static class ApplicationSettings
{
    public static string WebServiceBaseUrl { get; private set; }

    static ApplicationSettings()
    {
#if DEBUG
        // Compiling this app on MY machine, WebServiceBaseUrl will become: http://MATT-PC/RealWorldWP7.Web/
        // The returned URL will be automatically determined on each compile
        // Therefore no issues checking it in and getting latest on any developer machine
        WebServiceBaseUrl = DynamicLocalhost.ReplaceLocalhost("http://localhost/RealWorldWP7.Web/");
#else
        WebServiceBaseUrl = "http://services.mydomain.com/v1/";
#endif
    }
}&lt;/pre&gt;

&lt;h2&gt;Source Code, Feedback, Forking!&lt;/h2&gt;

&lt;p&gt;I would really, really love feedback on this. I scoured the internet trying to see if something similar already existed and turned up with nothing. If you find it useful, or have any suggestions, please be sure to let me know! &lt;/p&gt;

&lt;p&gt;I’m also very new at PowerShell and would not be surprised if I wrote some of the worst .ps1 scripts ever. Any input by PowerShell guru’s would be most welcome.&lt;/p&gt;

&lt;h2&gt;&lt;a href="http://dynamiclocalhost.codeplex.com/SourceControl/list/changesets" target="_blank"&gt;Get the Source!&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;It’s using Mercurial, so fork it, and be sure to send me pull requests if you write something awesome!&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a01eb169-0237-47f7-bf9a-08055b204648" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/open+source" rel="tag"&gt;open source&lt;/a&gt;,&lt;a href="http://technorati.com/tags/community" rel="tag"&gt;community&lt;/a&gt;,&lt;a href="http://technorati.com/tags/nuget" rel="tag"&gt;nuget&lt;/a&gt;,&lt;a href="http://technorati.com/tags/PowerShell" rel="tag"&gt;PowerShell&lt;/a&gt;,&lt;a href="http://technorati.com/tags/msbuild" rel="tag"&gt;msbuild&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/87.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/10/10/DynamicLocalhost-NuGet-Package-for-Windows-Phone.aspx</guid>
            <pubDate>Tue, 11 Oct 2011 04:18:19 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/10/10/DynamicLocalhost-NuGet-Package-for-Windows-Phone.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/87.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Windows Phone Development MVP</title>
            <link>http://www.matthidinger.com/archive/2011/10/01/Windows-Phone-Development-MVP.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Windows-Phone-Development-MVP_9396/mvp-vertical_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 0px 5px 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="mvp-vertical" border="0" alt="mvp-vertical" align="right" src="http://www.matthidinger.com/images/www_matthidinger_com/Windows-Live-Writer/Windows-Phone-Development-MVP_9396/mvp-vertical_thumb.png" width="150" height="235" /&gt;&lt;/a&gt;This morning I received a Microsoft MVP award for Windows Phone Development. I’m really honored to be part of a community that really values knowledge sharing and continuous professional growth such as this. Over the past few years I’ve come to greatly respect and appreciate the vast amount of personal time that many people in the development community (both MVPs and non-MVPs) contribute to help drive our profession forward.&lt;/p&gt;  &lt;p&gt;I’d also like to offer a very special thanks to the entire Windows Phone Dev community for helping to expand this great platform into the consumer reach that it deserves. There is still a ways to go, but after the impressive world-wide launch of Mango across dozens of countries, carriers, and OEMs &lt;strong&gt;on a single day&lt;/strong&gt; I think we can all agree that Microsoft is taking this seriously. I’m personally really excited to be in on the ground floor this platform!&lt;/p&gt;  &lt;h3&gt;Chicago Community&lt;/h3&gt;  &lt;p&gt;And of course to anyone in Chicagoland who is at least slightly curious about Windows Phone development, don’t miss our &lt;a href="http://www.meetup.com/Chicago-Windows-Phone-Developers/" target="_blank"&gt;Chicago Windows Phone Developer group&lt;/a&gt; meetings on the first Thursday of every month at 200 S Wacker.&lt;/p&gt;  &lt;h3&gt;Thanks!&lt;/h3&gt;  &lt;p&gt;Thanks again to the entire development community for investing so much of your personal time to speaking, training, blogging, and critiquing the tools and platforms we use every day!&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4d6f80fb-8d4c-46fe-b823-7d47c0fb7fb0" class="class"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/wp7" rel="tag"&gt;wp7&lt;/a&gt;,&lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/mvp" rel="tag"&gt;mvp&lt;/a&gt;,&lt;a href="http://technorati.com/tags/community" rel="tag"&gt;community&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/86.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/10/01/Windows-Phone-Development-MVP.aspx</guid>
            <pubDate>Sat, 01 Oct 2011 15:29:00 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/10/01/Windows-Phone-Development-MVP.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/86.aspx</wfw:commentRss>
        </item>
        <item>
            <title>An inheritance-aware ModelBinderProvider in MVC 3</title>
            <link>http://www.matthidinger.com/archive/2011/08/16/An-inheritance-aware-ModelBinderProvider-in-MVC-3.aspx</link>
            <description>&lt;p&gt;The default Model Binder in ASP.NET MVC works fine for most cases. Most of you have probably registered custom binders with it plenty of times.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:d672801d-03fc-4fe0-80f2-7cb9bbab23c5" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;ModelBinders.Binders.Add(typeof(ILoadProvider), new LoadProviderModelBinder());&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The issue is that that it’s limited to binding the &lt;strong&gt;exact type&lt;/strong&gt; you add to its dictionary. The ILoadProvider registered above will invoke my LoadProviderModelBinder &lt;strong&gt;as long as the controller action parameter is of type ILoadProvider&lt;/strong&gt;. But what if you have a type that derives from ILoadProvider and still want your custom binding to occur? &lt;/p&gt;

&lt;p&gt;Thankfully this is very simple in ASP.NET MVC 3. It comes with a new extensibility point, &lt;strong&gt;IModelBinderProvider&lt;/strong&gt;, and works just like the other providers. &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:38fbbbcb-9a7f-4d4b-8e5d-e44d4cc90f36" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;public interface IModelBinderProvider
{
    IModelBinder GetBinder(Type modelType);
}&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;InheritanceAwareModelBinderProvider&lt;/h3&gt;

&lt;p&gt;With this interface, we are able to create a very simple InheritanceAwareModelBinderProvider&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:04474b39-3443-4a30-876c-b9f942e4c95c" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;/// &amp;lt;summary&amp;gt;
/// Adds inheritance support when registering model binders. 
/// Any model binders added here will be invoked if the Type being bound inherits from the type registered.
/// &amp;lt;/summary&amp;gt;
public class InheritanceAwareModelBinderProvider : Dictionary&amp;lt;Type, IModelBinder&amp;gt;, IModelBinderProvider
{
    public IModelBinder GetBinder(Type modelType)
    {
        var binders = from binder in this
                        where binder.Key.IsAssignableFrom(modelType)
                        select binder.Value;

        return binders.FirstOrDefault();
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Usage&lt;/h3&gt;

&lt;p&gt;Register the Model Binder Provider just as you normally would register Model Binders. For example, in Global.asax&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:d41307cc-42ca-45ea-ba08-ac49d17b8aec" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;var binderProvider = new InheritanceAwareModelBinderProvider
                            {
                                { typeof (ILoadProvider), new LoadProviderModelBinder() }
                            };

ModelBinderProviders.BinderProviders.Add(binderProvider);&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Given the example above, if I’m binding to a type that that &lt;strong&gt;inherits from ILoadProvider &lt;/strong&gt;my LoadProviderModelBinder will still handle the binding.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:1a94c33f-db06-4b45-99cc-74b28a589587" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/aspnet+mvc" rel="tag"&gt;aspnet mvc&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/85.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/08/16/An-inheritance-aware-ModelBinderProvider-in-MVC-3.aspx</guid>
            <pubDate>Tue, 16 Aug 2011 17:07:06 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/08/16/An-inheritance-aware-ModelBinderProvider-in-MVC-3.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/85.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Windows Phone Unleashed @ TechWeek Chicago</title>
            <link>http://www.matthidinger.com/archive/2011/07/22/Windows-Phone-Unleashed-TechWeek-Chicago.aspx</link>
            <description>&lt;h3&gt;TechWeek Chicago&lt;/h3&gt;  &lt;p&gt;Starting today and running through next Friday, July 29th is TechWeek Chicago. TechWeek is a week of conference, expo and events with over 2,000 entrepreneurs, business leaders, and innovators, 4 days of conference sessions, over 150 international speakers, 4 days of an expo hall with over 100 exhibitors, 35 competing tech startups, and over 30 independent off-site events. TechWeek connects the newest web and mobile technologies to thousands of Chicago business, academic, community, art, and media professionals- all within one week. For more information about TechWeek, check out &lt;a href="http://www.techweek.com"&gt;http://www.techweek.com&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Windows Phone Unleashed&lt;/h3&gt;  &lt;p&gt;During TechWeek Chicago, Microsoft is hosting &lt;a href="http://windowsphonetechweek.eventbrite.com"&gt;Windows Phone Unleashed @ TechWeek&lt;/a&gt;. This will be an incredible evening getting hands-on with Windows Phone and you will have the opportunity to work with the Windows Phone and Windows Azure experts to help get your app ideas of the ground. More details for this event is below.&lt;/p&gt;  &lt;p&gt;There are a limited number of tickets, so RSVP ASAP!    &lt;br /&gt;&lt;a href="http://windowsphonetechweek.eventbrite.com"&gt;http://windowsphonetechweek.eventbrite.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Don’t miss this opportunity to get hands on with Windows Phone and the new features coming in Windows Phone “Mango”. Get help developing apps from the Windows Phone experts! This is a “hands-on” Hackathon where you will learn how to build, scale and publish your Windows Phone apps from the Windows Phone and Windows Azure experts. If you are a beginner or even an expert Windows Phone developer, you should not miss this event. &lt;/p&gt;    &lt;p&gt;We will have short sessions on how to get started creating apps for the Windows Phone. And sessions on how to make serious $$$ building Windows Phone apps. Bring your laptop and we will provide all of the necessary tools needed to build your apps. This five hour event will bring together experts and developers with the purpose of developing WP7 apps. &lt;/p&gt;    &lt;p&gt;Bring your ideas! Present them to your peers and WIN! Top app ideas will be voted on with an opportunity to WIN FREE Marketplace registration and more! We will also show participants who manage to create a Windows Phone app how they can be entered to win a new Windows Phone!&lt;/p&gt;    &lt;p&gt;If you are a student, this is an event you can’t afford to miss! We will show you multiple ways to get FREE Unlocked Samsung Focus Windows Phones, FREE Xbox 360 games, FREE Visual Studio 2010 Professional, FREE Windows Phone Marketplace accounts and FREE Gift Cards.&lt;/p&gt; &lt;/blockquote&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:682960c6-9b84-4522-ba42-7167e2c91149" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/wp7" rel="tag"&gt;wp7&lt;/a&gt;,&lt;a href="http://technorati.com/tags/wp7dev" rel="tag"&gt;wp7dev&lt;/a&gt;,&lt;a href="http://technorati.com/tags/community" rel="tag"&gt;community&lt;/a&gt;,&lt;a href="http://technorati.com/tags/presentations" rel="tag"&gt;presentations&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/82.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2011/07/22/Windows-Phone-Unleashed-TechWeek-Chicago.aspx</guid>
            <pubDate>Fri, 22 Jul 2011 20:50:20 GMT</pubDate>
            <comments>http://www.matthidinger.com/archive/2011/07/22/Windows-Phone-Unleashed-TechWeek-Chicago.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/82.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>