<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">
    <channel>
        <title>K. Scott Allen</title>
        <link>http://odetocode.com/Blogs/scott/Default.aspx</link>
        <description>Experiments In Writing</description>
        <language>en-US</language>
        <copyright>K. Scott Allen</copyright>
        <generator>Subtext Version 2.2.0.0</generator>
        <image>
            <title>K. Scott Allen</title>
            <url>http://odetocode.com/Blogs/images/RSS2Image.gif</url>
            <link>http://odetocode.com/Blogs/scott/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/OdeToCode" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="odetocode" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
            <title>Premack&amp;rsquo;s Principle Applied To Software</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/02/12/premackrsquos-principle-applied-to-software.aspx</link>
            <description>&lt;p&gt;Wikipedia lays out &lt;a href="http://www.psych.upenn.edu/~premack/About.html" target="_blank"&gt;David Premack’s&lt;/a&gt; principle in laymen’s terms:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Premack's_principle" target="_blank"&gt;Premack's Principle&lt;/a&gt; suggests that if a student wants to perform a given activity, the student will perform a less desirable activity to get at the more desirable activity.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Many people grow up under a rigorous application of the principle. Parents around the world tell kids to “finish your homework before you play outside”, and “finish your vegetables* before you eat desert”.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.flickr.com/photos/st3f4n/3937069430/" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="fruitsandveggies" border="0" alt="fruitsandveggies" src="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/PremacksPrincipleandSoftwareDevelopment_DEF5/fruitsandveggies_3.jpg" width="404" height="271" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Did you ever wonder if the “no pain, no gain” line of thought drilled into us since grade school allows for a high level of friction in software? Users are willing to accept pain, and creators subliminally dish it out. &lt;/p&gt;  &lt;p&gt;This is my theory: we allow business software to have high levels of friction because employees are predisposed to slog through undesirable activities inside software to get a job “done”, or just get paid (a highly desirable activity). Thus, with limited resources, &lt;strong&gt;business will always favor features over usability&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;What do you think?&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;*&lt;/strong&gt; The discerning reader will notice that the Imperial Stormtroopers featured in the picture are bearing fruit - not vegetables. However, section 4 of the artistic license granted to me as the owner of this blog includes a clause that allows pictures of Imperial Stormtrooper action figures to appear in any post, even when it risks creating cognitive dissonance. Pictures of Jar Jar Binks are still strictly prohibited. &lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1049.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=3M2RezqfQMs:TUjTRuSLDio:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=3M2RezqfQMs:TUjTRuSLDio:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=3M2RezqfQMs:TUjTRuSLDio:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=3M2RezqfQMs:TUjTRuSLDio:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=3M2RezqfQMs:TUjTRuSLDio:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=3M2RezqfQMs:TUjTRuSLDio:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/02/12/premackrsquos-principle-applied-to-software.aspx</guid>
            <pubDate>Fri, 12 Feb 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/02/12/premackrsquos-principle-applied-to-software.aspx#feedback</comments>
            <slash:comments>8</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1049.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1049.aspx</trackback:ping>
        </item>
        <item>
            <title>What&amp;rsquo;s Wrong With This Code #24</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/02/10/whatrsquos-wrong-with-this-code-24.aspx</link>
            <description>&lt;p&gt;Sometimes the simplest solution introduces a bug. &lt;/p&gt;  &lt;p&gt;Let’s say there is a ListBox in WPF (or Silverlight) displaying bowlers* and their bowling scores: &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;ListBox &lt;/span&gt;&lt;span style="color: red"&gt;ItemsSource&lt;/span&gt;&lt;span style="color: blue"&gt;="{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Bowlers&lt;/span&gt;&lt;span style="color: blue"&gt;}" &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
     &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox.ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
         &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
             &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;StackPanel &lt;/span&gt;&lt;span style="color: red"&gt;Orientation&lt;/span&gt;&lt;span style="color: blue"&gt;="Horizontal"&amp;gt;
                 &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;="{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;}"/&amp;gt;
                 &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;="{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Score&lt;/span&gt;&lt;span style="color: blue"&gt;}"/&amp;gt;
             &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;StackPanel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;                             
         &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
     &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox.ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
 &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Behind the scenes, a view model includes a Bowlers property for the binding to work. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Bowler&lt;/span&gt;&amp;gt; Bowlers 
{ 
    &lt;span style="color: blue"&gt;get
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;return &lt;/span&gt;_bowlers;
    }
    &lt;span style="color: blue"&gt;set
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: blue"&gt;value &lt;/span&gt;!= _bowlers)
        {
            _bowlers = &lt;span style="color: blue"&gt;value&lt;/span&gt;.ToObservable();
            &lt;span style="color: green"&gt;// ... Raise property changed event
&lt;/span&gt;        }
    }
}&lt;/pre&gt;

&lt;p&gt;The property uses a ToObservable extension method that works in either Silverlight or WPF. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public static class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ObservableExtensions
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ObservableCollection&lt;/span&gt;&amp;lt;T&amp;gt; ToObservable&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;T&amp;gt; items)
    {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;collection = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ObservableCollection&lt;/span&gt;&amp;lt;T&amp;gt;();
        &lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;item &lt;span style="color: blue"&gt;in &lt;/span&gt;items)
        {
            collection.Add(item);
        }
        &lt;span style="color: blue"&gt;return &lt;/span&gt;collection;
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;So far everything is working. Bowlers appear on the screen, and as new bowlers get added to the collection …&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;_bowlers.Add(newBowler);&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;… they magically appear in the display. &lt;/p&gt;

&lt;h3&gt;The Change&lt;/h3&gt;

&lt;p&gt;Now someone wants the bowlers list sorted with the highest score appearing at the top of the list. Sounds like a simple change to the Bowlers property:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Bowler&lt;/span&gt;&amp;gt; Bowlers 
{ 
    &lt;span style="color: blue"&gt;get
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;return &lt;/span&gt;_bowlers&lt;strong&gt;.OrderByDescending(bowler =&amp;gt; bowler.Score);&lt;/strong&gt;
    }
    &lt;span style="color: blue"&gt;set
    &lt;/span&gt;{
        &lt;span style="color: green"&gt;// same as before ...
&lt;/span&gt;    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;At first glace, the new code works and the bowlers appear in sorted order, but something is wrong! What will break?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hint:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bowlers added with _bowlers.Add(…) never appear in the display. Why is that?&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;* Of the &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Bowler_(ten-pin)" target="_blank"&gt;&lt;em&gt;ten pin&lt;/em&gt;&lt;/a&gt;&lt;em&gt; variety - not the &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Bowler_(cricket)" target="_blank"&gt;&lt;em&gt;spinning kind&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. &lt;/em&gt;&lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1048.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=XqVfz3iGJlA:GsWLyA1majg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=XqVfz3iGJlA:GsWLyA1majg:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=XqVfz3iGJlA:GsWLyA1majg:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=XqVfz3iGJlA:GsWLyA1majg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=XqVfz3iGJlA:GsWLyA1majg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=XqVfz3iGJlA:GsWLyA1majg:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/02/10/whatrsquos-wrong-with-this-code-24.aspx</guid>
            <pubDate>Thu, 11 Feb 2010 02:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/02/10/whatrsquos-wrong-with-this-code-24.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1048.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1048.aspx</trackback:ping>
        </item>
        <item>
            <title>Upcoming Events</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/02/08/upcoming-events.aspx</link>
            <description>&lt;p&gt;Here are some events I’ll be speaking at over the next couple months:&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://www.devteach.com/Index.aspx" target="_blank"&gt;DevTeach&lt;/a&gt; &lt;/h3&gt;  &lt;p&gt;&lt;strong&gt;Toronto / Mississauga March 8-12&lt;/strong&gt;. DevTeach stands for Developers Teaching. It’s a conference done by developers for developers. This annual event offers the elements of an international conference and the elements of a community event. Sessions include both presentation material and, whenever possible, hands-on training. We like to describe this event as the Developers Festival. Find out who should attend at &lt;a href="http://www.devteach.com/WhoShouldAttend.aspx#Who"&gt;this link&lt;/a&gt;. Check out the &lt;a href="http://www.devteach.com/WhoShouldAttend.aspx"&gt;top ten ways&lt;/a&gt; to convince your boss to let you go this event. DevTeach is about becoming one of the best developer by getting training from the &lt;a href="http://www.devteach.com/Speaker.aspx"&gt;best in the industry&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://www.scandevconf.se/2010/conference/" target="_blank"&gt;Scandinavian Developer Conference&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;&lt;strong&gt;Göteborg, Sweden March 16-17&lt;/strong&gt;. Whether you are someone learning development in Java, .NET or IBM i or you are an experienced user of these technologies for 10 years or more, there are lot of great information to be shared with everyone.&lt;/p&gt;  &lt;p&gt;In addition to technical sessions, we will also have tracks with presentations about the Development Process and Methodology: Agile Methodology, Test Driven Development, System Engineering, Architecture, Project Management, Best practices, "Agile in the Organization". We will also have tracks about hot topics like Cloud Computing, Testing, Web Development and Mobile Solutions. At the Conference there will also be a track of Emerging Technologies presented in cooperation with ThoughtWorks ( &lt;a href="http://www.thoughtworks.com/"&gt;www.thoughtworks.com&lt;/a&gt; )&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://www.devdays.nl/Default.aspx?pid=68&amp;amp;lang=en" target="_blank"&gt;DevDays 2010&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;&lt;strong&gt;DevDays is being held at World Forum in Den Haag March 30-31.&lt;/strong&gt; DevDays 2010: the biggest Microsoft event in the Netherlands for software development and software architecture. Every year, thousands of professionals visit DevDays to get completely up-to-date with all recent developments in their area of expertise in two days.&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://www.devconnections.com/" target="_blank"&gt;DevConnections&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;&lt;strong&gt;Las Vegas April 12-14 2010. &lt;/strong&gt;Developers from around the world will gather at the world famous Bellagio, for the Microsoft Visual Studio Conference &amp;amp; Expo, ASP.NET &amp;amp; Silverlight Conference &amp;amp; Expo and SQL Server Conference &amp;amp; Expo. You can be a part of this exciting event while you enjoy one of the most stunning hotels on the Las Vegas Strip at a great conference rate!&lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1047.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=1JaVYgjkngg:VxqtCJdzgS8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=1JaVYgjkngg:VxqtCJdzgS8:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=1JaVYgjkngg:VxqtCJdzgS8:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=1JaVYgjkngg:VxqtCJdzgS8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=1JaVYgjkngg:VxqtCJdzgS8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=1JaVYgjkngg:VxqtCJdzgS8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/02/08/upcoming-events.aspx</guid>
            <pubDate>Mon, 08 Feb 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/02/08/upcoming-events.aspx#feedback</comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1047.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1047.aspx</trackback:ping>
        </item>
        <item>
            <title>Thoughts on an MVVM Rant</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/02/02/thoughts-on-an-mvvm-rant.aspx</link>
            <description>&lt;p&gt;I stumbled across “&lt;a href="http://forums.silverlight.net/forums/p/159237/356897.aspx#356897"&gt;A vent abount MVVM Development&lt;/a&gt;” thanks to a tweet from @&lt;a href="http://twitter.com/peterbromberg"&gt;peterbromberg&lt;/a&gt;. Excerpt:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;What really irritates me is that I am forced to waste so much time on how to try and figure out how a complex User Interface will work together with a suitable "ViewModel" all for the sake of being more "testable".  I could cobble together a pretty darn good application and still be able to split up the work among User Interface and code-behind developers.  I think adopting a non-industry standard, seemingly "best practices" ideology just because it seems 'cool' and it's "there" is the wrong approach to application development&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;a href="http://www.flickr.com/photos/novembering/123651421/" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="MVVM Rockstar" border="0" alt="MVVM Rockstar" align="right" src="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/ThoughtsonanMVVMRant_143/rockstar_3.jpg" width="184" height="244" /&gt;&lt;/a&gt; Ah, MVVM! MVVM is the rock star who packs the house at every XAML event. It’s in books, blog posts, and podcasts. You can’t swing a dead laptop without hitting someone who is spouting about the virtues of model-view-viewmodel. With so much hype, there’s bound to be backlash. &lt;/p&gt;  &lt;p&gt;Does MVVM deserve the hype? &lt;/p&gt;  &lt;p&gt;Short answer – no.&lt;/p&gt;  &lt;h3&gt;An Alternative?&lt;/h3&gt;  &lt;p&gt;You’ve got a complex UI with lots of rules, and you reject the MVVM best practice crap the whiteboarding architect is jamming down your throat. You’re gonna be … &lt;strong&gt;pragmatic!&lt;/strong&gt;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;SaveButton_Click(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;RoutedEventArgs &lt;/span&gt;e)
{
   &lt;span style="color: blue"&gt;if&lt;/span&gt;(ThisIsValid)
   {
       &lt;span style="color: blue"&gt;if &lt;/span&gt;(ThatIsValid)
       {
           IsDragging = &lt;span style="color: blue"&gt;false&lt;/span&gt;;
        
           &lt;span style="color: blue"&gt;if &lt;/span&gt;(DraftCheckBox.IsChecked.HasValue &amp;amp;&amp;amp;
               DraftCheckBox.IsChecked == &lt;span style="color: blue"&gt;true &lt;/span&gt;&amp;amp;&amp;amp;
               ItemList.SelectedItem != &lt;span style="color: blue"&gt;null&lt;/span&gt;)
           {
               DragDropTarget.Children.Clear();
               SaveSomethingToWebServiceAsDraft();
           }
           &lt;span style="color: blue"&gt;else
           &lt;/span&gt;{
               DoSomethingElse();
               EmptyAllControls();
           }
       }
   }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Managing a complex UI by jamming code into event handlers results in something spectacular – as does throwing a bucket of water on a raging grease fire. Afterwards the fundamental problem of complexity (or fire) still exists – and it’s even worse than before! &lt;/p&gt;

&lt;h3&gt;Doesn’t MVVM Take Care of Complexity?&lt;/h3&gt;

&lt;p&gt;I’d argue that MVVM doesn’t solve the complexity problem by itself. Neither does SOA or object databases or tomorrow's next big thing. They all help - but they don’t make complex requirements disappear. At some point you have to roll up your sleeves and work on a design that manages the complexity at an acceptable level for your team, your skill level, your business, and your environment. Experience plays a key role here because it’s all been done before. Breaking complex things into simple, composable pieces requires practice with abstraction techniques and knowing where to apply the right amount of encapsulation. &lt;/p&gt;

&lt;p&gt;One drawback to the MVVM hype is how the hype drives people to one solution for every problem. The truth is there are lots of tricks to managing a complex UI, and some of them are dead simple and have built-in tooling support. Here is a sample:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;User controls and custom controls&lt;/li&gt;

  &lt;li&gt;Behaviors (underutilized, IMHO)&lt;/li&gt;

  &lt;li&gt;Triggers and visual states&lt;/li&gt;

  &lt;li&gt;Events and event aggregators&lt;/li&gt;
&lt;/ul&gt;

&lt;p /&gt;

&lt;p /&gt;

&lt;p&gt;The trick is to pick the right tool for the job.  &lt;/p&gt;

&lt;h3&gt;So What Can MVVM Do For Me?&lt;/h3&gt;

&lt;p&gt;I think MVVM &lt;em&gt;does &lt;/em&gt;help to manage complexity and and produce maintainable code. I’ve had success with MVVM. Like every separated presentation pattern it divides the varied concerns of a user interface. You can’t dismiss the MV* type patterns as pie in the sky architecture –they’ve served the industry well for decades. &lt;/p&gt;

&lt;p&gt;What makes MVVM different? Why is it shiny and new? I think it’s because MVVM’s raison d'être is data binding.  It’s easy to dismiss MVVM as just another UI pattern, but binding does give MVVM a slightly different flavor (a bit salty at times, but that’s just because of the static typing). If you’ve already been using a separated presentation pattern, it’s the data binding capabilities you need to understand and leverage. Data binding is quite powerful in WPF and Silverlight. You can perform amazing feats with little effort and without sacrificing encapsulation. Giving up on data binding is giving up on many of the advantages in the platform. &lt;/p&gt;

&lt;p&gt;Proper use of MVVM also gives you a testable chunk of code. I think it’s strange that the MVVM rant dismisses the work needed to make a complex UI testable. I’d think a complex UI would need more testing than a simple UI. &lt;/p&gt;

&lt;p&gt;On the other hand, I did just read “&lt;a href="http://arstechnica.com/business/news/2010/01/how-a-stray-mouse-click-choked-the-nyse-cost-a-bank-150k.ars" target="_blank"&gt;How a stray mouse click choked the NYSE &amp;amp; cost a bank $150K&lt;/a&gt;”, so I might not be thinking clearly.&lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1045.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=xfpQR6076A4:Qx9wtD0-mlQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=xfpQR6076A4:Qx9wtD0-mlQ:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=xfpQR6076A4:Qx9wtD0-mlQ:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=xfpQR6076A4:Qx9wtD0-mlQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=xfpQR6076A4:Qx9wtD0-mlQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=xfpQR6076A4:Qx9wtD0-mlQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/02/02/thoughts-on-an-mvvm-rant.aspx</guid>
            <pubDate>Tue, 02 Feb 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/02/02/thoughts-on-an-mvvm-rant.aspx#feedback</comments>
            <slash:comments>11</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1045.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1045.aspx</trackback:ping>
        </item>
        <item>
            <title>Wrapping about Collections</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/01/31/wrapping-about-collections.aspx</link>
            <description>&lt;p&gt;Mark Needham’s “&lt;a href="http://www.markhneedham.com/blog/"&gt;Thoughts On Software Development&lt;/a&gt;” is a great collection of blog posts. Last year Mark wrote “&lt;a href="http://www.markhneedham.com/blog/2009/10/23/coding-the-primitive-obsession/"&gt;Coding: The primitive obsession&lt;/a&gt;”, and challenged the idea that the &lt;a href="http://grabbagoft.blogspot.com/2007/12/dealing-with-primitive-obsession.html"&gt;primitive obsession&lt;/a&gt; anti-pattern is just about overusing low level data types like string and int. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The most frequent offender seems to be the creation of collections of things which we then query to find specific items elsewhere in the code. More often that not we'll also perform some custom logic on that particular item.&lt;/p&gt;    &lt;p&gt;At its most extreme we might extract each of the items in a collection and make use of them separately. This somewhat defeats the purpose of the collection.&lt;/p&gt;    &lt;p&gt;When this happens it often seems to me that what we actually have is a series of attributes of an object rather than a collection.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Mark goes on to describe how wrapping a collection can often create a more useful abstraction, then points to his debate in &lt;a href="http://www.markhneedham.com/blog/2009/07/24/wrapping-collections-inheritance-vs-composition/"&gt;Wrapping collections: Inheritance vs Composition&lt;/a&gt;. It’s a good read. &lt;/p&gt;  &lt;p&gt;I’ve been wrapping collections a bit myself lately, and it’s not too hard to create a custom collection that is both feature rich and descriptive of the problem it solves using composition. For example, let’s say you need to keep a collection of Stamp objects and support INotifyCollectionChanged. &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;StampCollection &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Stamp&lt;/span&gt;&amp;gt;, 
                               &lt;span style="color: #2b91af"&gt;INotifyCollectionChanged
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public &lt;/span&gt;StampCollection()
    {
        _items = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ObservableCollection&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Stamp&lt;/span&gt;&amp;gt;();
        _items.CollectionChanged += ItemsCollectionChanged;
    }

    &lt;span style="color: blue"&gt;public void &lt;/span&gt;AddStamp(&lt;span style="color: #2b91af"&gt;Stamp &lt;/span&gt;newStamp)
    {
        &lt;span style="color: green"&gt;/* logic */

        &lt;/span&gt;_items.Add(newStamp);
    }

    &lt;span style="color: blue"&gt;public void &lt;/span&gt;RemoveStamp(&lt;span style="color: #2b91af"&gt;Stamp &lt;/span&gt;stamp)
    {
        &lt;span style="color: green"&gt;/* logic */

        &lt;/span&gt;_items.Remove(stamp);
    }

    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Stamp&lt;/span&gt;&amp;gt; GetEnumerator()
    {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;_items.OrderBy(stamp =&amp;gt; stamp.Something)
                     .GetEnumerator();
    }

    &lt;span style="color: #2b91af"&gt;IEnumerator IEnumerable&lt;/span&gt;.GetEnumerator()
    {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;GetEnumerator();
    }

    &lt;span style="color: blue"&gt;public event &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NotifyCollectionChangedEventHandler 
        &lt;/span&gt;CollectionChanged = &lt;span style="color: blue"&gt;delegate &lt;/span&gt;{ };

    &lt;span style="color: blue"&gt;void &lt;/span&gt;ItemsCollectionChanged(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, 
                                &lt;span style="color: #2b91af"&gt;NotifyCollectionChangedEventArgs &lt;/span&gt;e)
    {
        CollectionChanged(&lt;span style="color: blue"&gt;this&lt;/span&gt;, e);
    }

    &lt;span style="color: blue"&gt;readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ObservableCollection&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Stamp&lt;/span&gt;&amp;gt; _items;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Yes, it’s a bit of code, but it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Gives you complete control over the surface area of the API compared to inheriting from ObservableCollection&amp;lt;T&amp;gt; or List&amp;lt;T&amp;gt;&lt;/li&gt;

  &lt;li&gt;Allows precise control over adding and removing objects (validation, perhaps updating fields). &lt;/li&gt;

  &lt;li&gt;Becomes a more descriptive part of the domain&lt;/li&gt;

  &lt;li&gt;Is not to be confused with a &lt;a href="http://www.youtube.com/watch?v=3o_6qlmKW94"&gt;rap collection&lt;/a&gt;. &lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1044.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=8z7CxnaAkk0:KBrcJIyeWeU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=8z7CxnaAkk0:KBrcJIyeWeU:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=8z7CxnaAkk0:KBrcJIyeWeU:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=8z7CxnaAkk0:KBrcJIyeWeU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=8z7CxnaAkk0:KBrcJIyeWeU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=8z7CxnaAkk0:KBrcJIyeWeU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/01/31/wrapping-about-collections.aspx</guid>
            <pubDate>Mon, 01 Feb 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/01/31/wrapping-about-collections.aspx#feedback</comments>
            <slash:comments>8</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1044.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1044.aspx</trackback:ping>
        </item>
        <item>
            <title>KISS Your ASP.NET MVC Routes</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/01/25/kiss-your-asp-net-mvc-routes.aspx</link>
            <description>&lt;p&gt;A little bit of thinking and compromise can remove unnecessary complexity from the routes in an MVC application. &lt;/p&gt;  &lt;p&gt;For example:&lt;/p&gt;  &lt;p&gt;Morgan’s web site has authenticated users,and Morgan decides the URLs for managing users should look like &lt;em&gt;/morgan/detail&lt;/em&gt;. Morgan adds the following code to register the route:&lt;/p&gt;  &lt;pre class="code"&gt;routes.MapRoute(
    &lt;span style="color: #a31515"&gt;"User"&lt;/span&gt;,
    &lt;span style="color: #a31515"&gt;"{username}/{action}"&lt;/span&gt;,
    &lt;span style="color: blue"&gt;new &lt;/span&gt;{ controller =&lt;span style="color: #a31515"&gt;"User"&lt;/span&gt;, action=&lt;span style="color: #a31515"&gt;"Index" &lt;/span&gt;}
);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Morgan runs some tests and it looks like there is a problem. The User controller is getting requests for &lt;em&gt;/home/index&lt;/em&gt;. Oops, that request should have gone to the Home controller. Fortunately, Morgan knows there is all sorts of whizz-bang features you can add to a route, so Morgan creates a route constraint: &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;UserRouteConstraint &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;IRouteConstraint
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public bool &lt;/span&gt;Match(&lt;span style="color: #2b91af"&gt;HttpContextBase &lt;/span&gt;httpContext, 
                      &lt;span style="color: #2b91af"&gt;Route &lt;/span&gt;route, &lt;span style="color: blue"&gt;string &lt;/span&gt;parameterName, 
                      &lt;span style="color: #2b91af"&gt;RouteValueDictionary &lt;/span&gt;values, 
                      &lt;span style="color: #2b91af"&gt;RouteDirection &lt;/span&gt;routeDirection)
    {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;username = values[&lt;span style="color: #a31515"&gt;"username"&lt;/span&gt;] &lt;span style="color: blue"&gt;as string&lt;/span&gt;;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;IsCurrentUser(username);
    }

    &lt;span style="color: blue"&gt;private bool &lt;/span&gt;IsCurrentUser(&lt;span style="color: blue"&gt;string &lt;/span&gt;username)
    {
        &lt;span style="color: green"&gt;// ... look up the user
    &lt;/span&gt;}
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The constraint prevents the User route from gobbing requests to other controllers. It only allows requests to reach the User controller when the username exists in the application. &lt;/p&gt;

&lt;p&gt; Morgan tweaks the route registration code to include the constraint:&lt;/p&gt;

&lt;pre class="code"&gt;routes.MapRoute(
    &lt;span style="color: #a31515"&gt;"User"&lt;/span&gt;,
    &lt;span style="color: #a31515"&gt;"{username}/{action}"&lt;/span&gt;,
    &lt;span style="color: blue"&gt;new &lt;/span&gt;{ controller =&lt;span style="color: #a31515"&gt;"User"&lt;/span&gt;, action=&lt;span style="color: #a31515"&gt;"Index"&lt;/span&gt;},
&lt;strong&gt;    &lt;span style="color: blue"&gt;new &lt;/span&gt;{ user = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UserRouteConstraint&lt;/span&gt;()&lt;/strong&gt; }
);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Morgan runs some tests and everything works!&lt;/p&gt;

&lt;p&gt;Well …&lt;/p&gt;

&lt;p&gt;Everything works until a user registers with the name “home”. Morgan goes off to tweak the code again...&lt;/p&gt;

&lt;h3&gt;STOP!&lt;/h3&gt;

&lt;p&gt;As a rule of thumb I try to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Never use advanced routing features like constraints&lt;/li&gt;

  &lt;li&gt;Always stick to a URL like {controller}/{action}/{id} or {controller}/{id}/{action}&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes you have to go break those rules, but let’s look at Morgan’s case. If Morgan was happy with a URL like /user/index/morgan, then Morgan wouldn’t need to register any additional routes. The default routing entry in a new MVC application would happily invoke the index action of the User controller and pass along the username as the id parameter. Morgan could also go with /user/morgan and use a simple route entry like this:&lt;/p&gt;

&lt;pre class="code"&gt;routes.MapRoute(
    &lt;span style="color: #a31515"&gt;"User"&lt;/span&gt;,
    &lt;span style="color: #a31515"&gt;"User/{username}/{action}"&lt;/span&gt;,
    &lt;span style="color: blue"&gt;new &lt;/span&gt;{ controller =&lt;span style="color: #a31515"&gt;"User"&lt;/span&gt;, action=&lt;span style="color: #a31515"&gt;"Index"&lt;/span&gt;, username=&lt;span style="color: #a31515"&gt;"*"&lt;/span&gt;}
);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;No constraints required! &lt;/p&gt;

&lt;p&gt;The KISS principle (&lt;em&gt;keep it simple stupid&lt;/em&gt;) is a good design principle for routes. You’ll have fewer moving parts, consistent URL structures, and make the code easier to maintain.&lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1043.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=rZcV0nGx1T0:6oZis3B6bI0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=rZcV0nGx1T0:6oZis3B6bI0:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=rZcV0nGx1T0:6oZis3B6bI0:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=rZcV0nGx1T0:6oZis3B6bI0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=rZcV0nGx1T0:6oZis3B6bI0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=rZcV0nGx1T0:6oZis3B6bI0:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/01/25/kiss-your-asp-net-mvc-routes.aspx</guid>
            <pubDate>Mon, 25 Jan 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/01/25/kiss-your-asp-net-mvc-routes.aspx#feedback</comments>
            <slash:comments>13</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1043.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1043.aspx</trackback:ping>
        </item>
        <item>
            <title>Silverlight and ASP.NET MVC Don&amp;rsquo;t Serve the Same Master</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/01/18/silverlight-and-asp-net-mvc-donrsquot-serve-the-same-master.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/pulihora/255322178/" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="contrast" border="0" alt="contrast" align="right" src="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/Silverlight.NETMVCDontServetheSameMaster_1294B/contrast_3.jpg" width="244" height="164" /&gt;&lt;/a&gt; I’m flipping between MVC and Silverlight projects when a startling contrast starts to emerge. It’s not the obvious contrast between stateful and stateless. It’s a subtler contrast in design. &lt;/p&gt;  &lt;p&gt;If you poke around in a new MVC project, one of the first pieces of code you’ll run across is the code to register the default route. It’s in global.asax.cs, and looks like this:&lt;/p&gt;  &lt;pre class="code"&gt;routes.MapRoute(
    &lt;span style="color: #a31515"&gt;"Default"&lt;/span&gt;,                                            
    &lt;span style="color: #a31515"&gt;"{controller}/{action}/{id}"&lt;/span&gt;,                         
    &lt;span style="color: blue"&gt;new &lt;/span&gt;{ controller = &lt;span style="color: #a31515"&gt;"Home"&lt;/span&gt;, action = &lt;span style="color: #a31515"&gt;"Index"&lt;/span&gt;, id = &lt;span style="color: #a31515"&gt;"" &lt;/span&gt;}
);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This snippet relies on some of the recent features added to C# – extension methods and anonymously typed objects. It obviously draws some inspiration from &lt;a href="http://guides.rubyonrails.org/routing.html"&gt;Ruby on Rails&lt;/a&gt;, which builds on top of the dynamic, malleable Ruby language. &lt;/p&gt;

&lt;p&gt;Compare that code to the code you’ll see when you open up just about any Silverlight control.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/Silverlight.NETMVCDontServetheSameMaster_1294B/silverlight_2.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="silverlight code" border="0" alt="silverlight code" src="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/Silverlight.NETMVCDontServetheSameMaster_1294B/silverlight_thumb.png" width="202" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Well, you don’t actually see much code because the code is swept underneath a carpet of regions. This happens quite often in Silverlight, and I think it’s because developers are embarrassed to write lines and lines and lines of code to define a single simple property. It’s the elegance of RPG combined with the verbosity of COBOL. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public bool &lt;/span&gt;IsDropDownOpen
{
    &lt;span style="color: blue"&gt;get &lt;/span&gt;{ &lt;span style="color: blue"&gt;return &lt;/span&gt;(&lt;span style="color: blue"&gt;bool&lt;/span&gt;)GetValue(IsDropDownOpenProperty); }
    &lt;span style="color: blue"&gt;set &lt;/span&gt;{ SetValue(IsDropDownOpenProperty, &lt;span style="color: blue"&gt;value&lt;/span&gt;); }
}

&lt;span style="color: blue"&gt;public static readonly &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DependencyProperty &lt;/span&gt;IsDropDownOpenProperty =
    &lt;span style="color: #2b91af"&gt;DependencyProperty&lt;/span&gt;.Register(
        &lt;span style="color: #a31515"&gt;"IsDropDownOpen"&lt;/span&gt;,
        &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;bool&lt;/span&gt;),
        &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Foo&lt;/span&gt;),
        &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;PropertyMetadata&lt;/span&gt;(&lt;span style="color: blue"&gt;false&lt;/span&gt;, OnIsDropDownOpenPropertyChanged));&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;I realize IsDropDownOpen isn’t &lt;em&gt;just&lt;/em&gt; a simple property. It’s a dependency property, and dependency properties hold many great and magical powers. Data binding in Silverlight (and WPF), for example, is wonderfully feature rich and easy, but it comes with a price.&lt;strong&gt; Instead of writing one line of code …&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public bool &lt;/span&gt;IsDropDownOpen { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;… &lt;strong&gt;we need twelve!&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The contrast isn’t in the number of lines of code, however. The contrast is in &lt;em&gt;who&lt;/em&gt; the frameworks were designed to serve. &lt;/p&gt;

&lt;h3&gt;MVC is for Developers – Silverlight is for Tools&lt;/h3&gt;

&lt;p&gt;The MVC framework is designed for developers who write code. This fact is obvious in the API design and how the team fights for programmer friendly features like the new &lt;a href="http://haacked.com/archive/2009/09/25/html-encoding-code-nuggets.aspx" target="_blank"&gt;HTML encoding block syntax&lt;/a&gt;. The MapRoute code we saw earlier is just one example of many. The MVC framework took inspiration from platforms that are popular today because they favor &lt;a href="http://en.wikipedia.org/wiki/Convention_over_configuration" target="_blank"&gt;convention over configuration&lt;/a&gt; and &lt;a href="http://blog.thinkrelevance.com/2008/4/1/ending-legacy-code-in-our-lifetime" target="_blank"&gt;essence over ceremony&lt;/a&gt;. These are fancy terms for keeping things &lt;strong&gt;simple and readable&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Silverlight is designed for tooling. Visual Studio, Expression Blend, and other XAML, code, and art editors. I’m not saying we get rid of the tools. We &lt;em&gt;need&lt;/em&gt; the tools for the feedback and capabilities they provide when building effects, animations, and irregularly shaped objects. But, it seems the developer’s life gets more difficult with the addition of every feature.&lt;/p&gt;

&lt;h3&gt;The Next 5 Years&lt;/h3&gt;

&lt;p&gt; I’d be surprised if another language doesn’t come along to become the de facto standard for the code behind XAML files. A language that is just as friendly to programmers as it is to XAML. A language that makes writing code for System.Windows fun, simple, and readable.  Maybe it will look like … &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;depprop bool &lt;/span&gt;IsDropDownOpen { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;… but smarter people then me can figure out the syntax. I just know there has to be something better. &lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1042.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=sYc4wnE9Dco:H6kgdILji1k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=sYc4wnE9Dco:H6kgdILji1k:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=sYc4wnE9Dco:H6kgdILji1k:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=sYc4wnE9Dco:H6kgdILji1k:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=sYc4wnE9Dco:H6kgdILji1k:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=sYc4wnE9Dco:H6kgdILji1k:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/01/18/silverlight-and-asp-net-mvc-donrsquot-serve-the-same-master.aspx</guid>
            <pubDate>Tue, 19 Jan 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/01/18/silverlight-and-asp-net-mvc-donrsquot-serve-the-same-master.aspx#feedback</comments>
            <slash:comments>12</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1042.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1042.aspx</trackback:ping>
        </item>
        <item>
            <title>Drop-down Lists and ASP.NET MVC</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/01/18/drop-down-lists-and-asp-net-mvc.aspx</link>
            <description>&lt;p&gt;Working with drop-down lists in ASP.NET MVC has some confusing aspects, so let’s look at an example. &lt;/p&gt;  &lt;p&gt;Imagine the goal is to edit a song (not the music and lyrics of a song – just the boring data pieces). Each song is associated with an album, and each song has a title and track number. With this description, you can imagine an edit view using the following code:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;Html.DropDownList(&lt;span style="color: #a31515"&gt;"AlbumId"&lt;/span&gt;, Model.Albums)&lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;  ...
&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;Html.TextBox(&lt;span style="color: #a31515"&gt;"Title"&lt;/span&gt;, Model.Title) &lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;   ...
&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;Html.TextBox(&lt;span style="color: #a31515"&gt;"TrackNumber"&lt;/span&gt;, Model.TrackNumber) &lt;span style="background: #ffee62"&gt;%&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The Html.DropDownList helper method likes to work with SelectListItem objects, so a view model you can pair with this view looks like the following:&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;EditSongViewModel
&lt;/span&gt;{        
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;Title { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }                
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;TrackNumber { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;&amp;gt; Albums { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Some people don’t like to use SelectListItem types in their view models. Instead, they’ll convert to them in the view. I think it’s entirely reasonable to use SelectListItem in a view model, because the view model is supposed to make the view easier to write. Having the view model perfectly aligned with the needs of the view means you need to think less (and write less code) when creating the view. &lt;/p&gt;

&lt;h3&gt;Creating SelectListItems&lt;/h3&gt;

&lt;p&gt;There are a couple approaches you can take when creating a sequence of SelectListItem objects. I think the cleanest approach is to have an extension method that knows how to take a collection of objects in your software (like Album objects), and map them into SelectListItem objects. &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;&amp;gt; ToSelectListItems(
              &lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Album&lt;/span&gt;&amp;gt; albums, &lt;span style="color: blue"&gt;int &lt;/span&gt;selectedId)
{
    &lt;span style="color: blue"&gt;return 
        &lt;/span&gt;albums.OrderBy(album =&amp;gt; album.Name)
              .Select(album =&amp;gt; 
                  &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectListItem
                  &lt;/span&gt;{
                    Selected = (album.ID == selectedId),
                    Text = album.Name,
                    Value = album.ID.ToString()
                   });
}&lt;/pre&gt;

&lt;p&gt;You can use the method like this:&lt;/p&gt;

&lt;pre class="code"&gt;model.Albums = _repository.FindAllAlbums().ToSelectItems(selectedId);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;That code works, because Html.DropDownList will happily work with IEnumerable of SelectListItem. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The class you need to be careful with is the SelectList class.&lt;/strong&gt; I’ve seen quite a few people make the mistake of wrapping their SelectListItem objects in a SelectList without setting the DataTextField and DataValueField properties. This does &lt;strong&gt;not&lt;/strong&gt; work:&lt;/p&gt;

&lt;pre class="code"&gt;model.Albums = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectList&lt;/span&gt;(
                _repository.FindAllAlbums().ToSelectListItems(1)
                );&lt;/pre&gt;

&lt;p&gt;You’d think the SelectList class would know how to work with a collection of SelectListItem objects - but it doesn’t. The following doesn’t work either (the drop-down list will display “System.Web.Mvc.SelectListItem” for every entry):&lt;/p&gt;

&lt;pre class="code"&gt;model.Albums = 
    &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectList&lt;/span&gt;(_repository.FindAllAlbums()
                              .ToSelectItems(selectedID));&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The SelectList class is really designed to perform the conversion we did earlier (with the extension method), but it uses late binding reflection. The following &lt;strong&gt;would&lt;/strong&gt; work, because we tell the SelectList where to find the text and value fields:&lt;/p&gt;

&lt;pre class="code"&gt;model.Albums = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SelectList&lt;/span&gt;(
                _repository.FindAllAlbums(), &lt;span style="color: #a31515"&gt;"ID"&lt;/span&gt;, &lt;span style="color: #a31515"&gt;"Name"
                &lt;/span&gt;);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;h3&gt;Reading the Selection&lt;/h3&gt;

&lt;p&gt;If you are using the same model to accept input from the edit view during a postback, you might think the default model binder will repopulate the Albums collection with all the album information and set the selected album. Unfortunately - the web doesn’t work this way and the Albums collection will be empty. &lt;/p&gt;

&lt;p&gt;The only album related information the browser will post is the value of the selected item. If you want this value bound to a model, you’ll need to provide an AlbumId property (to match the name we gave the DropDownList in the view - “AlbumId”). &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;EditSongViewModel
&lt;/span&gt;{
&lt;strong&gt;    &lt;span style="color: blue"&gt;public int &lt;/span&gt;AlbumId { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
&lt;/strong&gt;    &lt;span style="color: blue"&gt;public string &lt;/span&gt;Title { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }                
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;TrackNumber { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;SelectListItem&lt;/span&gt;&amp;gt; Albums { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Some people will create two separate view models in this case. One view model is designed to carry information to the view, and will have an Albums property (but no AlbumId property). The second view model is designed to accept user input during postback and will have an AlbumId propery (but no Albums property). This approach adds the overhead of an extra class, but the view models are perfectly aligned with their duties and no properties go unused. You’ll have to decide which approach is best for you. &lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Don’t use a SelectList without telling it the DataTextField and DataValueField properties to use.&lt;/li&gt;

  &lt;li&gt;Don’t expect to see a collection for a drop-down list repopulated on a postback.&lt;/li&gt;

  &lt;li&gt;Extension methods make it easy to create a sequence of SelectListItem objects in strongly-typed code.&lt;/li&gt;

  &lt;li&gt;Html.DropDownList doesn’t &lt;em&gt;require&lt;/em&gt; a SelectList – it’s happy working with any sequence of SelectListItem objects. &lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1041.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=2DeSSGTZV9M:Tp4pYNBJQ9c:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=2DeSSGTZV9M:Tp4pYNBJQ9c:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=2DeSSGTZV9M:Tp4pYNBJQ9c:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=2DeSSGTZV9M:Tp4pYNBJQ9c:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=2DeSSGTZV9M:Tp4pYNBJQ9c:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=2DeSSGTZV9M:Tp4pYNBJQ9c:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/01/18/drop-down-lists-and-asp-net-mvc.aspx</guid>
            <pubDate>Mon, 18 Jan 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/01/18/drop-down-lists-and-asp-net-mvc.aspx#feedback</comments>
            <slash:comments>15</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1041.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1041.aspx</trackback:ping>
        </item>
        <item>
            <title>T4MVC in MSDN Magazine</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/01/13/t4mvc-in-msdn-magazine.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/ee291528.aspx"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="msdn january 2010" border="0" alt="msdn january 2010" align="right" src="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/T4TemplatesforMVCinMSDNMagazine_139EE/msdn_3.jpg" width="188" height="243" /&gt;&lt;/a&gt; The &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee291528.aspx"&gt;January 2010 issue of MSDN Magazine&lt;/a&gt; is online with my article covering T4MVC:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: 16px 'Times New Roman'; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"&gt;&lt;span style="line-height: 18px; font-family: 'Segoe UI', verdana, arial; color: rgb(51,51,51); font-size: 14px" class="Apple-style-span"&gt;Microsoft Visual Studio includes a code generation engine known as T4 (which is short for Text Template Transformation Toolkit). You’ve probably already used T4 templates in Visual Studio without even knowing they were working behind the scenes. In this article I’m going to give you a basic introduction to T4 templates and show you how ASP.NET MVC uses this technology. I’ll also show you how to customize T4 templates to enhance your day-to-day work with the MVC framework&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Thanks go to &lt;a href="http://blogs.msdn.com/davidebb/default.aspx"&gt;David Ebbo&lt;/a&gt; for his help and comments on the article. David continues to improve  T4MVC, for example: &lt;a href="http://blogs.msdn.com/davidebb/archive/2010/01/04/t4mvc-2-6-10-fluent-route-value-api-shorter-way-to-refer-to-action-and-more.aspx"&gt;T4MVC 2.6.10: fluent route value API, shorter way to refer to action, and more&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1040.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=GgMW1T27TeA:rcY5yxnwvN4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=GgMW1T27TeA:rcY5yxnwvN4:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=GgMW1T27TeA:rcY5yxnwvN4:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=GgMW1T27TeA:rcY5yxnwvN4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=GgMW1T27TeA:rcY5yxnwvN4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=GgMW1T27TeA:rcY5yxnwvN4:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/01/13/t4mvc-in-msdn-magazine.aspx</guid>
            <pubDate>Thu, 14 Jan 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/01/13/t4mvc-in-msdn-magazine.aspx#feedback</comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1040.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1040.aspx</trackback:ping>
        </item>
        <item>
            <title>Of Web Browsers and Humanity</title>
            <link>http://odetocode.com/Blogs/scott/archive/2010/01/13/of-web-browsers-and-humanity.aspx</link>
            <description>&lt;p&gt;Douglas Crockford posted an interesting topic for discussion on &lt;a href="http://www.crockford.com/" target="_blank"&gt;his site&lt;/a&gt; (look for the &lt;em&gt;Discussion Topic&lt;/em&gt; section at the bottom of the page):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;If a web browser is defective, causing errors in the display or performance of the page, should the page developer struggle to hide the browser's defects, or should the defects be revealed in hope of creating market pressure to force the browser maker to make good? By which approach is humanity better served?&lt;/p&gt; &lt;/blockquote&gt;  &lt;h3&gt;What I’d Like To Say&lt;/h3&gt;  &lt;p&gt;When I was a kid, I loved &lt;a href="http://en.wikipedia.org/wiki/Mad_libs" target="_blank"&gt;Mad Libs&lt;/a&gt;. And I bet you could come up with a Mad Lib that represents a style of question every web developer asks on a regular basis. I think it would look like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I’m trying to ______ a ______ and it’s fine in ______ and _______, but in ______ it doesn’t _______ing work. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It’s always the same question - you just have to fill in the blanks with 1 CSS property, 1 DOM element, 3 browser versions, and one profanity. Isn’t it insane? Can’t we start a revolution and all make a New Year’s resolution?&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="This year I will not write hacky workaround code for defective browsers" border="0" alt="This year I will not write hacky workaround code for defective browsers" src="http://odetocode.com/Blogs/images/odetocode_com/Blogs/scott/WindowsLiveWriter/cc3e09f16d3c_AE0/resolution_3.jpg" width="304" height="204" /&gt;&lt;/p&gt;  &lt;h3&gt;But …&lt;/h3&gt;  &lt;p&gt;It’s a business decision. I think this is what gets under the collective skin of the web development community more than anything else. We can’t make a resolution to stop! We already told the bosses they’ll spend an extra $10,000 to support &lt;a href="http://www.positioniseverything.net/explorer.html" target="_blank"&gt;IE6&lt;/a&gt;, but they are more than happy with the &lt;em&gt;return on the investment.&lt;/em&gt; So, we sulk back to our offices and grudgingly add some more conditional CSS comments to the site’s style sheet. &lt;/p&gt;  &lt;p&gt;If there is going to be market pressure, it won’t come from developers per se, but from big Internet properties with fanatical followers, like Facebook, Amazon, eBay, and Twitter. They have the power to force users to move, and when users start moving the makers react. &lt;/p&gt;  &lt;p&gt;And yes, I think it is in the best interest of humanity.&lt;/p&gt;&lt;img src="http://odetocode.com/Blogs/scott/aggbug/1039.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=OSzZvgDU7F0:9F0UXB274Ns:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=OSzZvgDU7F0:9F0UXB274Ns:jWeZv7XsJd0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=jWeZv7XsJd0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=OSzZvgDU7F0:9F0UXB274Ns:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=OSzZvgDU7F0:9F0UXB274Ns:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?i=OSzZvgDU7F0:9F0UXB274Ns:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/OdeToCode?a=OSzZvgDU7F0:9F0UXB274Ns:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/OdeToCode?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>K. Scott Allen</dc:creator>
            <guid>http://odetocode.com/Blogs/scott/archive/2010/01/13/of-web-browsers-and-humanity.aspx</guid>
            <pubDate>Wed, 13 Jan 2010 14:12:00 GMT</pubDate>
            <comments>http://odetocode.com/Blogs/scott/archive/2010/01/13/of-web-browsers-and-humanity.aspx#feedback</comments>
            <slash:comments>8</slash:comments>
            <wfw:commentRss>http://odetocode.com/Blogs/scott/comments/commentRss/1039.aspx</wfw:commentRss>
            <trackback:ping>http://odetocode.com/Blogs/scott/services/trackbacks/1039.aspx</trackback:ping>
        </item>
    </channel>
</rss>
