<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jesse Liberty &#187; Patterns</title>
	<atom:link href="http://jesseliberty.com/Tags/patterns/feed/" rel="self" type="application/rss+xml" />
	<link>http://jesseliberty.com</link>
	<description>Code To Live. Live To Code.</description>
	<lastBuildDate>Tue, 31 Jan 2012 17:18:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Yet Another Podcast Show #3 &#8211; John Papa on MVVM and Patterns</title>
		<link>http://jesseliberty.com/2010/09/29/yet-another-podcast-show-3-john-papa-on-mvvm-and-patterns/</link>
		<comments>http://jesseliberty.com/2010/09/29/yet-another-podcast-show-3-john-papa-on-mvvm-and-patterns/#comments</comments>
		<pubDate>Wed, 29 Sep 2010 12:17:39 +0000</pubDate>
		<dc:creator>Jesse Liberty</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Patterns & Skills]]></category>
		<category><![CDATA[Podcast]]></category>
		<category><![CDATA[WindowsPhone]]></category>
		<category><![CDATA[BestPractices]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[YapCast]]></category>

		<guid isPermaLink="false">http://jesseliberty.com/2010/09/29/yet-another-podcast-show-3-john-papa-on-mvvm-and-patterns/</guid>
		<description><![CDATA[Talking with John Papa, Senior Technical Evangelist, about MVVM and Patterns 5 Simple Steps for MVVM Keeping up with the community Top blogs MVVM Light Ward Bell’s photos Grok. Verb: To fully understand.  See Stranger In A Strange Land by &#8230; <a href="http://jesseliberty.com/2010/09/29/yet-another-podcast-show-3-john-papa-on-mvvm-and-patterns/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://jesseliberty.com/wp-content/uploads/2010/10/JohnPapa.jpg"><img style="margin: 10px 0px; display: inline; border-width: 0px;" title="JohnPapa" src="http://jesseliberty.com/wp-content/uploads/2010/10/JohnPapa_thumb.jpg" border="0" alt="JohnPapa" width="91" height="118" align="right" /></a> Talking with John Papa, Senior Technical Evangelist, about MVVM and Patterns</p>
<p><a href="http://www.iteleportmobile.com/" target="_blank"></a></p>
<ul>
<li><a href="http://johnpapa.net/silverlight/5-minute-overview-of-mvvm-in-silverlight/" target="_blank">5 Simple Steps for MVVM</a></li>
<li><a href="http://johnpapa.net/silverlight/leaders-in-silverlight/" target="_blank">Keeping up with the community</a></li>
<li><a href="http://johnpapa.net/silverlight/top-10-silverlight-blogs/" target="_blank">Top blogs</a></li>
<li><a href="http://mvvmlight.codeplex.com/" target="_blank">MVVM Light</a></li>
<li><a href="http://johnpapa.net/silverlight/silverlight-tv-19-hidden-gems-from-mix10-ufc-s-multi-touch-app/" target="_blank">Ward Bell’s photos</a></li>
</ul>
<p><a href="http://en.wikipedia.org/wiki/Grok" target="_blank">Grok</a>. Verb: To fully understand.  See <a href="http://www.amazon.com/Stranger-Strange-Land-Robert-Heinlein/dp/0441788386/ref=tmm_pap_title_popover?ie=UTF8&amp;qid=1286314408&amp;sr=1-1" target="_blank">Stranger In A Strange Land</a> by Robert Heinlein.  1961</p>
<p><a href="http://jesseliberty.com/wp-content/media/Show3.mp3" target="_blank">Listen</a> | Return to <a href="http://jesseliberty.com/podcast" target="_blank">Yet Another Podcast</a></p>
<p>Call in comments:  <strong>1-347-YAP-CAST</strong></p>
<table style="border-bottom-color: white; border-top-color: white; border-right-color: white; border-left-color: white" ;=";" unselectable="on" bottom="bottom" valing:="valing:">
<tbody>
<tr>
<td style="border-bottom-color: white; border-top-color: white; border-right-color: white; border-left-color: white"><a href="http://feeds.feedburner.com/JesseLibertyYapcast"><img style="border-right-width: 0px; margin: 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="rss" border="0" alt="rss" align="right" src="http://jesseliberty.com/wp-content/uploads/2010/10/rss_thumb.jpg" width="29" height="26" /></a> </td>
<td style="border-bottom-color: white; border-top-color: white; border-right-color: white; border-left-color: white"><a href="http://itunes.apple.com/us/podcast/id393751871"><img style="border-right-width: 0px; margin: 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="iTunes" border="0" alt="iTunes" align="right" src="http://jesseliberty.com/wp-content/uploads/2010/10/iTunes_thumb.jpg" width="94" height="31" /></a> </td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://jesseliberty.com/2010/09/29/yet-another-podcast-show-3-john-papa-on-mvvm-and-patterns/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
<enclosure url="http://jesseliberty.com/wp-content/media/Show3.mp3" length="23301481" type="audio/mpeg" />
		</item>
		<item>
		<title>Programmer Superstitions</title>
		<link>http://jesseliberty.com/2010/08/26/one-from-the-vault-programmer-superstitions/</link>
		<comments>http://jesseliberty.com/2010/08/26/one-from-the-vault-programmer-superstitions/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 13:10:49 +0000</pubDate>
		<dc:creator>Jesse Liberty</dc:creator>
				<category><![CDATA[Essentials]]></category>
		<category><![CDATA[Opinion]]></category>
		<category><![CDATA[Patterns & Skills]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Patterns]]></category>

		<guid isPermaLink="false">http://jesseliberty.com/2010/08/26/one-from-the-vault-programmer-superstitions/</guid>
		<description><![CDATA[There are a number of practices that we engage in &#8211;– no, that we cling to, and defend, and teach to others,  – that amount to magical thinking, or at best, rational failure. This is often just fine, no harm &#8230; <a href="http://jesseliberty.com/2010/08/26/one-from-the-vault-programmer-superstitions/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There are a<strong> number of practices that we engage in</strong> &#8211;– no, that we cling to, and defend, and teach to others,  – that amount to <strong>magical thinking,</strong> or at best, rational failure.</p>
<p><a href="http://jesseliberty.com/wp-content/uploads/2010/08/POTION_istock.jpg"><img style="margin: 10px 25px 10px 0px; display: inline; border: 0px;" title="Green poison" src="http://jesseliberty.com/wp-content/uploads/2010/08/POTION_istock_thumb.jpg" border="0" alt="Green poison" width="240" height="166" align="left" /></a></p>
<p>This is often just fine, no harm done (other than to our self-image as rational geeks) but <strong>some of these totemic-rituals are stumbling blocks in our ability to produce reliable software. </strong></p>
<p>From time to time we might want to stop and question our most cherished assumptions to see if we&#8217;ve fallen into any of these traps:</p>
<ul>
<li><strong>Secrecy and Mystery</strong></li>
<li><strong>Ancestor Worship</strong></li>
<li><strong><a href="http://en.wikipedia.org/wiki/Apophenia" target="_blank">Apophenia</a></strong></li>
<li><strong>Argument From Authority</strong></li>
</ul>
<p><span id="more-3274"></span></p>
<h3>Secrecy and Mystery: <strong>Data Hiding</strong></h3>
<p>I’ve been writing in and teaching C++ and C# for twenty years. I know well the iron-clad rule of object -oriented programming that <strong>class data should be hidden</strong> (private) and accessed through either a property (C#) or an accessor function (C++). Thus:</p>
<pre class="brush: csharp;">public class Employee
{
    private string name;
    public string Name
    {
       get { return name;}
       set { name = value;}
    }
}
</pre>
<p><strong>There are good reasons for this rule.</strong> Data hiding makes for a better decoupling of classes, and allows the programmer to intercept the access of private data and apply rules or other processing. It is possible, for example, to check whether the client accessing a value has the correct permissions to see or modify that value, and also to massage the data in appropriate ways.</p>
<p><strong>But look closely</strong> at the example shown above: it is not unusual. The backing data is stored as a private local variable, and full access is provided with a get and a set accessor, neither of which do anything but return or set the value. That is,<strong> the accessors add no immediate value at all</strong>. The typing penalty is solved with automatic properties,</p>
<pre class="brush: csharp;">public class Employee
{

    public string Name
    {
       get; set;
    }
}
</pre>
<p>But to some degree this just hides the problem.  After all, why not write</p>
<pre class="brush: csharp;">public class Employee
{
    public string Name;
}
</pre>
<p>Don&#8217;t panic when you see this; consider that there is little difference from the automatic property and it is a heck of a lot more straight forward.</p>
<p><a href="http://images2.wikia.nocookie.net/__cb20060220185544/psychology/images/thumb/4/47/Asch_experiment.png/270px-Asch_experiment.png"><img style="margin: 0px; display: inline; border: 0px;" title="270px-Asch_experiment" src="http://jesseliberty.com/wp-content/uploads/2010/08/270pxAsch_experiment.png" border="0" alt="270px-Asch_experiment" width="240" height="196" align="left" /></a> The last, desperate excuse, as you will find in many computer books, including my own (I add with some chagrin), is that making the backing variable private (or using automatic variables, and changing them when needed) allows you to change how you store the data without breaking any client of your Employee class. You could, for example, decide some time in the future to retrieve the name from a database.</p>
<p>The rational  part of me suspects that the number of person hours wasted, both by all the hocus pocus of properties  is swamped by any possible benefit. And, yet, I can’t quite bring myself to eschew the properties.</p>
<p>The problem is that can&#8217;t justify my reluctance rationally. Either this is a superstition, or more likely, it is the <strong><a href="http://psychology.wikia.com/wiki/Asch_conformity_experiments" target="_blank">Asch conformity effect</a></strong>, in which students were shown three lines,  one distinctly longer than the other, but confederates of the experimenter in the audience insisted that the shorter was longer.<strong> If three confederates or more made the false assumption, the subjects were likely to go along more than a third of the time(!) </strong></p>
<p><strong>Ancestor Worship</strong></p>
<p>Let’s take an example where we are not only being irrational, but also making our lives harder and our code more expensive to write and to maintain.</p>
<p>You may want to sit down for this one, but I’m going to dare to ask: <strong>why do we insist that C-derived languages</strong> (such as C#) <strong>continue to be case sensitive</strong>?  Other than paying homage to Kernighan and Ritchie I believe I can safely say after 20+ years of writing in C, C++ and C# that <strong>the disadvantages of case sensitivity swamp the advantages</strong>.</p>
<p>The only clear advantage I have ever found is the ability to have make the name of a property be the PascalCase version of the camelCase name of the backing variable</p>
<pre class="brush: csharp;">private int age;
public int Age { get { //... } set { //.... } }
</pre>
<p><strong>In exchange for that convenience, we enjoy hours of debugging, trying to find where we inadvertently introduced a new variable or method name because of a misplaced shift-key.</strong></p>
<p>And even in the best case, the argument is obsolete,  as the convention now is to use an underscore</p>
<pre class="brush: csharp;">private int _age;
public int Age { get { //... } set { //.... } }
</pre>
<p>Has any bright graduate student done research on the cost/benefit of case sensitivity? Is there any rational reason that in 2010 C# continues this &#8216;“tradition”&#8217; that was established 30+ ago? Or might it be a lingering fear of showing disrespect to the icons of our industry; the mighty heroes who created the C family, defeated Troy and bequeathed us the scriptures by which we live?</p>
<p><em>Or Maybe Not…</em></p>
<p>There is an argument that case sensitivity makes more sense with some human languages other than English, and may even make sense as an optimization for some data structures, such as hash tables. Such arguments, however, speak to the need for an optimizing compiler to handle the issue; there is no reason for the language to do so.</p>
<p>C++ programmers like to suffer anyway, so this just feeds the beast.</p>
<p><strong>Ancestor Worship II</strong></p>
<p>Here’s another example of latent ancestor worship (or at least of very old habits dying hard). <strong>There is a wonderful myth that American standard rail road tracks are the width they are</strong> (4 feet, 8.5 inches) because that is the way they built them in England, which the English did because that is the way they were gauged by the first tramways, which in turn was done because that is the width of wagon wheels created to fit in the wheel ruts in old English roads that were <strong>in turn dug by by Imperial Roman Chariots.</strong></p>
<p>The myth has <strong>tremendous lasting power</strong> (you can find it all over the net) <strong>because it feels right</strong> (<em>expectation bias</em>?) . We do that kind of thing a lot; we build the streets of Boston on old cow paths; we unconsciously follow old patterns, even when  those patterns no longer make sense or are necessary.</p>
<p>How many times have you seen (or written) code like this:</p>
<pre class="brush: csharp;">for ( int i = 0; i &lt; innerArrayLength; i++ )
{
    for ( int j = 0; j &lt; outerArrayLength; j++ )
    {
        myArray[i][j] = i * j;
    }
}</pre>
<p><strong>Why are the counter variables i and j</strong>?  Old cow paths. It turns out that in Fortran (remember Fortran? Remember Eisenhower?) the integer variables were the letters I through N (which comes from an even older tradition of mathematicians using i to n as subscripts for integers), and, well, we just got into the habit. This one is fairly harmless, a ritualized and vestigial part of the programming mind that we’re surprisingly reluctant to let go of.</p>
<h3>Pattern Recognition</h3>
<p>One of the most powerful forms of magical thinking is <strong>Apophenia: seeing patterns or connections in random data</strong>. The tendency towards Apophenia is probably hardwired into the human brain; it is the price we pay for the very advantageous  human ability of pattern recognition (an adaptive part of our intelligence that helps us know when to run and when to hunt) but it can also lead us astray (arguably it is the basis of our belief in many pseudo-sciences).</p>
<p><strong>Apophenia</strong> is certainly pervasive in consulting. A classic example was the tendency to study “&#8217;excellence&#8217;” in successful companies in the 1980s; trying to extract those apparent essential elements that lead to success.</p>
<p>Unfortunately, not only was it far more complex and difficult for other companies to reproduce success following these patterns, even the iconic companies themselves felt the worm turn over time. They kept repeating their patterns, but the outcomes were different. What went wrong?</p>
<p>It was not clear that <strong>the patterns of &#8216;“excellence”&#8217; we were “seeing” in successful companies</strong> (great customer service, their caring attention to employees and attention to details) were as easily connected with success as we had thought. Correlation is not always causation, as we so often learn (<em><a href="http://en.wikipedia.org/wiki/Post_hoc_ergo_propter_hoc">post hoc ergo propter hoc</a></em>).</p>
<p><strong>Argument From Authority</strong></p>
<p><strong>Argument from Authority</strong>, to disagree with <a href="http://www.samueljohnson.com/refuge.html">Samuel Johnson</a>, <strong>is</strong> <strong>the true last refuge of scoundrels. </strong></p>
<p>Some years ago I testified as an &#8216;“expert witness&#8217;” in a civil lawsuit, at which the opposing &#8216;“expert witness”&#8217; asserted that the &#8216;“failure”&#8217; of the project could be attributed to a lack of strict compliance with the ISO 9000 standard.</p>
<p>Smart people can have a reasonable discussion about whether ISO 9000 will improve the likelihood of success on very large projects (e.g. , the software for the mission to Mars). I personally would not like to work on a software project that is managed using anything like such a bureaucratic, heavyweight, inflexible, document-intensive, rigid processes, but that does not necessarily mean that I can prove that no project would ever benefit from it.</p>
<p>I had no hesitation, however, in asserting under oath, that the fact that various authorities asserted this was the right process for every project was abject nonsense.  I went on, at the arbiter&#8217;s insistence, that my personal assessment was that  a project with ten developers would benefit from strict adherence to ISO 9000 like a drowning man would benefit from being thrown an anchor. It was my opinion that knee-jerk reliance on a process like ISO 9000 to guide you through each project is a form of Apophenia; <strong>the connection between the pattern of ISO 9000 compliance steps and success, however measured, is imaginary</strong>. And, I concluded, supporting that theory with <em>Argument From Authority</em> was, at the least, irrational.</p>
<p><strong>Looking where the light is</strong></p>
<p>There is an old joke about a man searching for his keys under a street lamp. He lost the keys in the alley behind him, but this is where he can see.</p>
<p>In our desperate attempt to gain control over very complex processes, with so much money at stake, and so many examples of previous failures, <strong>we often fall victim to seeing apparent patterns </strong>(be they processes or otherwise) where they do not exist. We examine various projects and say:</p>
<blockquote><p>“&#8217;Ah ha! I see why this project worked and that one didn’t: the difference was too much/ (too little)  analysis (/ design) (/ documentation) (/ process) (/ oversight) (/ communication).</p>
<p>And all we have to do is increase/  (decrease) the number/ le (length) (/ duration) (/ sequence) (/ complexity) (/ formality) of the meetings (/ documents/ ) (diagrams) (/ studies) (/ sign-offs) , etc.</p></blockquote>
<p>These false patterns lead us astray; offering us the promise that if we paint by the numbers, we too can be Renoir.  It may be, however, that the variables of successful process are far more complex; including, if we are terribly unlucky, factors over which we have little or no control; or, only marginally better, factors over which we will have no control until our tools and technologies mature.</p>
<p>Or, it may just may be that some developers are better at the &#8216;“art”&#8217; of programming and shipping product; and that the old adage &#8216;“’tis a poor carpenter who blames his tools”&#8217; applies to software as well as it does to other crafts.</p>
<p><strong>The Scientific Method</strong></p>
<p>Over the years, at least to some degree, society has given up many (though not all) of its superstitions when presented with more compelling alternatives. One of the most effective techniques for distinguishing between superstition and truth (or some approximation of truth) is the scientific method; in short, controllable, measurable, reproducible effects <em>that are disprovable.</em></p>
<p>It’s hard to do that sort of thing when you’re trying to hit a deadline, and it’s particularly hard to sort out all the alternatives when there are so few objective comparisons.</p>
<p>When was the last time you were able to find anything like an objective answer to the question “which is better: Java or .NET?” (Please don’t write in, my mailbox fills quickly).</p>
<p>It is particularly interesting that the work done at Universities and Research Centers is often not only unrelated to, but totally disparaged by, the folks who write code for a living. That is not the way things work in other Engineering fields and I’m not convinced we can afford the disconnect for much longer.</p>
<p><strong>We seem to be writing 21st century software with a 12th  century mindset</strong> and that can’t be good.</p>
]]></content:encoded>
			<wfw:commentRss>http://jesseliberty.com/2010/08/26/one-from-the-vault-programmer-superstitions/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Coding Without A Net</title>
		<link>http://jesseliberty.com/2010/08/14/coding-without-a-net/</link>
		<comments>http://jesseliberty.com/2010/08/14/coding-without-a-net/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 09:45:00 +0000</pubDate>
		<dc:creator>Jesse Liberty</dc:creator>
				<category><![CDATA[Languages]]></category>
		<category><![CDATA[Patterns & Skills]]></category>
		<category><![CDATA[BestPractices]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Patterns]]></category>

		<guid isPermaLink="false">http://jesseliberty.com/2010/08/16/comments-a-liberty-v-liberty-debate/</guid>
		<description><![CDATA[I recently imposed on myself the constraint of coding without comments.  Why?

    * Comments rust faster than code, even when you're careful
    * Well written code can be read, and comments are annoying footnotes
    * Comments make for lazy coding
 <a href="http://jesseliberty.com/2010/08/14/coding-without-a-net/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I recently imposed on myself the constraint of coding without comments.  Why?</p>
<ul>
<li>Comments rust faster than code, even when you&#8217;re careful</li>
<li>Well written code can be read, and comments are annoying footnotes</li>
<li>Comments make for lazy coding</li>
</ul>
<p>Now, setting the bar at <em>no comments at all </em>seems a bit fanatic, but any value greater than zero is an invitation to using comments when better approaches are available, and like any addiction, I bet you can&#8217;t stop at one.</p>
<p><span id="more-3179"></span></p>
<h3>The Traditional View</h3>
<p>In Programming C# 4, we write,</p>
<blockquote><p>&#8220;…so even if your code is sufficiently clear that it&#8217;s easy to see <em>what</em> it does, it may not be at all clear <em>why</em> it does certain things….</p></blockquote>
<p>We then go on to give an example,</p>
<pre class="brush: csharp;">Frobnicator.SetTarget("");
Frobnicator.SetTarget("Norfolk");</pre>
<p>and then suggest that a comment will clarify the purpose of the code,</p>
<pre class="brush: csharp;">// Frobnicator 2.41 has a bug where it crashes occasionally if
// we try to set the target to "Norfolk".  Setting it to an empty // string first seems to work around the problem.
Frobnicator.SetTarget("");
Frobnicator.SetTarget("Norfolk");</pre>
<p>You can, however, eliminate these comments by being willing to put that information into the method name,</p>
<pre class="brush: csharp;">private void SetTargetToEmptyStringToWorkAroundBugInFrobnicator()
{
   Frobnicator.SetTarget("");
}

SetTargetToEmptyStringToWorkAroundBugInFrobnicator();
Frobnicator.SetTarget("Norfolk");</pre>
<p>What I prefer here is that the code and comments <em>cannot </em>get out of sync, and if the bug goes away, I just remove the obviously redundant code.  Since I started this approach I&#8217;ve not found the need for comments (nor the need for such absurdly long method names).</p>
<p>NB: I&#8217;m not advocating (yet), just experimenting.</p>
<h3>Beware of the temptation to refactor,</h3>
<p>When I first wrote this, I was tempted to factor out the common code:</p>
<pre class="brush: csharp;">private void SetStringToEmptyToFixBugThenSetStringYouWant(
                                string newString)
{
    Frobnicator.SetTarget("");
    Frobnicator.SetTarget(newString);
}

SetStringToEmptyToFixBugThenSetStringYouWant("Norfolk");</pre>
<p>While this has appeal, the problem is that when the bug is fixed, I&#8217;d have to change every call to this method everywhere, rather than just eliminating the call to the fix. Ugly.</p>
<p>Of course, I could add comments to explain why the code no longer makes sense:</p>
<p>The last thing you want is to end up with code like this!</p>
<pre class="brush: csharp;">// no longer need to set the empty string private void SetStringToEmptyToFixBugThenSetStringYouWant(
                                string newString)
{
    //   Frobnicator.SetTarget("");    Frobnicator.SetTarget(newString); }

SetStringToEmptyToFixBugThenSetStringYouWant("Norfolk");</pre>
<p>Yikes!</p>
]]></content:encoded>
			<wfw:commentRss>http://jesseliberty.com/2010/08/14/coding-without-a-net/feed/</wfw:commentRss>
		<slash:comments>45</slash:comments>
		</item>
		<item>
		<title>Silverlight As A Transmedia Platform</title>
		<link>http://jesseliberty.com/2010/06/17/silverlight-as-a-transmedia-platform/</link>
		<comments>http://jesseliberty.com/2010/06/17/silverlight-as-a-transmedia-platform/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 15:01:00 +0000</pubDate>
		<dc:creator>Jesse Liberty</dc:creator>
				<category><![CDATA[HyperVideo Player]]></category>
		<category><![CDATA[Mini-Tutorial]]></category>
		<category><![CDATA[Patterns & Skills]]></category>
		<category><![CDATA[WindowsPhone]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[wp7Tutorial]]></category>

		<guid isPermaLink="false">http://jesseliberty.com/2010/06/17/silverlight-as-a-transmedia-platform/</guid>
		<description><![CDATA[The advent of Windows Phone 7 is particularly exciting to current Silverlight programmers, because Silverlight (along with .xna) is the development platform for the new phone.  I recently recorded two Silverlight TV episodes, and in one I created a typical &#8230; <a href="http://jesseliberty.com/2010/06/17/silverlight-as-a-transmedia-platform/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://jesseliberty.com/wp-content/uploads/2010/06/MiniTutorialLogo21.jpg"><img class="alignnone size-full wp-image-2747" title="MiniTutorialLogo2" src="http://jesseliberty.com/wp-content/uploads/2010/06/MiniTutorialLogo21.jpg" alt="" width="256" height="75" /></a></p>
<p>The advent of Windows Phone 7 is particularly exciting to current Silverlight programmers, because Silverlight (along with .xna) is the development platform for the new phone.  I recently recorded two Silverlight TV episodes, and in one I created a typical form that might appear in any LOB application, but I created it simultaneously on both the phone and for the web using identical Xaml and C#.  (This is not to deny that there are some differences in coding for each, but the overlap is very very high).</p>
<p><a href="http://jpapa.me/sltv33" target="_blank">Link to SLTV video</a></p>
<p>But does it make sense to create the same application on the web and on the phone?</p>
<p><span id="more-2675"></span></p>
<p>Certainly that is the default assumption&#8230; you take your application and shrink it down to the form factor of the phone.</p>
<p><a href="http://jesseliberty.com/wp-content/uploads/2010/06/Outlook.jpg"><img class="alignleft size-medium wp-image-2740" title="Outlook" src="http://jesseliberty.com/wp-content/uploads/2010/06/Outlook-300x239.jpg" alt="" width="300" height="239" /></a><a href="http://jesseliberty.com/wp-content/uploads/2010/06/Migrate1.jpg"><img class="alignleft size-medium wp-image-2741" style="margin: 10px 20px;" title="Migrate" src="http://jesseliberty.com/wp-content/uploads/2010/06/Migrate1-153x300.jpg" alt="" width="153" height="300" /></a></p>
<p>This crude migration never makes it to market (or dies a quick and painful death) because a phone has (surprise!) a much smaller screen.</p>
<p>The    improvement is to re-envision the UI to be easier to use on the smaller screen.</p>
<p><a href="http://jesseliberty.com/wp-content/uploads/2010/06/rescale1.jpg"><img class="size-medium wp-image-2742 alignleft" style="margin: 10px 15px;" title="rescale" src="http://jesseliberty.com/wp-content/uploads/2010/06/rescale1-153x300.jpg" alt="" width="153" height="300" /></a></p>
<p>And, frankly, that is where most developers stop.  Not that this is bad; there are many applications that have been modified so as to have an excellent phone UI and I&#8217;m certain that Windows Phone 7 will have many exemplary migrations.</p>
<p>It is not that this is bad, but it may be a missed opportunity.  The phone offers different opportunities, different use-cases and different capabilities than a browser or desktop application.  Is it possible to create a second, complimentary application that stands on its own but together with the web application make for a greatly enhanced experience?</p>
<h2>Transmedia Storytelling</h2>
<p>The premise of Transmedia Storytelling is to tell the same story on various media, but to use each medium to its own advantage.  According to <a href="http://en.wikipedia.org/wiki/Transmedia_storytelling" target="_blank">Wikipedia</a>, the concept of Transmedia Storytelling was first mentioned in 1991 by Marsha Kinder in her seminal work <em>Playing with Power in Movies, Television, and Video Games: From Muppet Babies to Teenage Mutant Ninja Turtles </em>She asserted that this approach  &#8220;works to position consumers as powerful players.&#8221;</p>
<p>Some ten years later this was picked up by Dr. Henry Jenkins at the  MIT Media Lab. He said,</p>
<blockquote><p>The coordinated use of storytelling across platforms can make the story more compelling</p></blockquote>
<p>Is there a lesson to be learned here for Win Phone 7 developers?  It is early days, but the <a href="http://jesseliberty.com/Tags/hvp/" target="_blank">Silverlight Hypervideo Project</a> provides a great test bed for this concept.  Rather than simply migrating the HVP to the phone, we will pursue the idea of creating a separate, phone-based and phone-directed application that when used in tandem with the HVP will create a (you should pardon the expression) <em>synergy</em> that should make each more valuable.</p>
<p>Much more on this soon, and you can follow the progress of this effort on the <a href="http://slhvp.com" target="_blank">HVP site</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://jesseliberty.com/2010/06/17/silverlight-as-a-transmedia-platform/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MVVM – It’s Not Kool-Aid*</title>
		<link>http://jesseliberty.com/2010/05/08/mvvm-its-not-kool-aid-3/</link>
		<comments>http://jesseliberty.com/2010/05/08/mvvm-its-not-kool-aid-3/#comments</comments>
		<pubDate>Sat, 08 May 2010 17:35:00 +0000</pubDate>
		<dc:creator>Jesse Liberty</dc:creator>
				<category><![CDATA[Mini-Tutorial]]></category>
		<category><![CDATA[Patterns & Skills]]></category>
		<category><![CDATA[Patterns]]></category>

		<guid isPermaLink="false">http://jesseliberty.com/2010/05/08/mvvm-its-not-kool-aid-3/</guid>
		<description><![CDATA[[ Revised with C# and VB.NET code] Okay, first, understand that I’m in the position of running through the streets yelling at folks “c’mere! ya’ gotta see this!” and what I’m pointing to is the incredible new invention of… a &#8230; <a href="http://jesseliberty.com/2010/05/08/mvvm-its-not-kool-aid-3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://jesseliberty.com/wp-content/uploads/2010/05/MiniTutorialLogo21.jpg"><img style="margin: 10px 0px; display: inline; border: 0pt none;" title="MiniTutorialLogo2" src="http://jesseliberty.com/wp-content/uploads/2010/05/MiniTutorialLogo_thumb3.jpg" border="0" alt="MiniTutorialLogo2" width="240" height="70" /></a></p>
<p>[ Revised with C# and VB.NET code]</p>
<p>Okay, first, understand that I’m in the position of running through the streets yelling at folks “c’mere! ya’ gotta see this!” and what I’m pointing to is the incredible new invention of… a laptop computer. Something that is undeniably amazing and cool, but everyone else on my block has already got one.</p>
<p>Second, and much worse, I’m about to show you how I used a “pattern” that you either have already embraced, or that you’ve been avoiding like the plague because the folks who are running around shouting “MVVM! MVVM!” sound just like the folks who were running around shouting “MVC! MVC!” and “OOP! OOP!” and “COM! COM!”…  you get the idea.</p>
<p>Many of us are still recovering from the last five fads that caused us to go out and buy dozens of books and break our head on the latest/greatest trend, only to have it be “oh so last year” by the time we fully <a href="http://en.wikipedia.org/wiki/Grok" target="_blank">grokked</a> it.</p>
<p><span id="more-1334"></span></p>
<h3>Drinking The Kool Aid*</h3>
<p><a><img style="margin: 10px 20px 10px 0px; display: inline; border-width: 0px;" title="Kool Aid Man" src="http://upload.wikimedia.org/wikipedia/en/1/12/Kool_Aid_Man.jpeg" border="0" alt="Kool Aid Man" width="250" height="280" align="left" /></a></p>
<p>But this is different. Honest.</p>
<p>Here are three heretical assertions about MVVM:</p>
<ol>
<li><strong>It is not all that different</strong> from what you are already doing</li>
<li><strong>It is not hard</strong> to understand or to do</li>
<li>You will write better code, and<strong> you’ll write <em>less </em>code.</strong></li>
</ol>
<p>Typically, when a pattern or practice comes along, there is a steep learning curve, and the <em>cognoscenti</em> will tell you that it takes a very long time to truly master the approach. Feh. And not so, at least not this time. Let’s go over the assertions above, and I’ll explain, briefly, what you need to know to profit from MVVM.</p>
<table border="3" cellspacing="2" cellpadding="4" width="400">
<tbody>
<tr>
<td width="400" valign="top">Disclaimer: I’m not saying this is <em>all</em> you’ll ever need to know about MVVM, I’m saying if you know this, you can benefit from MVVM on any non-trivial application, while you’re learning more.While I’m disclaiming, please note that I’m writing very specifically about a Silverlight 4 project and that I’ve been coding with MVVM for about a half hour.</td>
</tr>
</tbody>
</table>
<h3>It’s Not All That Different and It’s Not That Hard</h3>
<p>We’ve been talking about n-tier development, decoupling, scoping, visibility and related topics since at least 1990. I’m pretty sure that when they were cracking the Enigma machine in World War II, they discussed decoupling the code-breaker module from the UI (did they have UI then?)</p>
<p>MVVM, at its heart has three core concepts, only the third of which is new, but that difference is all the difference in the world when you’re writing a Silverlight application that you want to be able to maintain and create unit tests for (Yes, I owe a blog post on Test-Driven design, but one glass of grape juice at a time).</p>
<p><img style="margin: 10px 10px 10px 0px; border: 0pt;" title="MVVMSketch" src="http://jesseliberty.com/wp-content/uploads/2010/05/MVVMSketch_thumb.jpg" border="0" alt="MVVMSketch" width="266" height="480" align="left" /></p>
<p><strong>Core Concept #1</strong>:  Separate your User Interface concerns (<strong>View)</strong> from your Business objects and behaviors (<strong>View Model</strong>) and from your data/persistence layer <strong>(Model)</strong>.</p>
<p><strong>Core Concept #2 Don’t Look Up</strong>.</p>
<p>We tend to conceptualize the View (User Interface objects) at the top, the ViewModel (objects that provide the UI with its data and behaviors) in the middle and the model (often the persistence layer) at the bottom.  The View can know about the ViewModel, the ViewModel about the Model, and the Model, like the cheese, stands alone.</p>
<p><strong>Core Concept #3 – And this is the killer: Binding.</strong></p>
<p>In MVVM the mechanism for the ViewModel to provide data to the View, is for the View to set the ViewModel as its DataContext.  That is so cool; it takes a while to realize the implications.  Further, we don’t just bind data, as I’ll show below.</p>
<h3>Why Would You Want To Do That, &amp; What Does It Cost?</h3>
<p>The huge advantages of using binding and making the VM the datacontext for the View is that <em>you write less code</em> and, equally important, your behaviors and state are all separated from the UI and thus you have enormously increased the testability of your application. (It is a bear to try to test a UI object because the pesky UI gets in the way. ViewModels have no UI, they have just the things you want to test: “does it behave as expected? and is the data correct at any given instant?”</p>
<p>So, the cost is negative; that is, by adopting MVVM you don’t work harder, you work less, and in exchange for doing less, your code is easier to write, to read, to maintain and to test. Not bad.</p>
<h3>Names</h3>
<p>Simplifying is one thing, over-simplifying another, and there is an elegance in the chosen names.</p>
<p>The <strong>Model</strong> is that which the application is modeling. Calling this the database layer or the persistence layer loses site of the fact that the  model might be virtually any time of information in virtually any format.</p>
<p>Calling the top layer the <strong>View</strong>, rather than the User Interface is important both to emphasize that it is just one of many possible views of the model, and to keep clear that the User Interface comprises both the appearance and the behaviors and the View is concerned only with the appearance.</p>
<p>The <strong>ViewModel</strong> is the bridge between the Model and the View; and the ViewModel thus owns responsibility for binding the relevant data to the view and for handling user actions appropriately, whether the response is in the widget, elsewhere in the View or in other parts of the application.</p>
<h3>A Practical Example</h3>
<p>To see this at work, we’ll start by creating a new Silverlight Application. (Complete source code is available <a href="http://blogs.silverlight.net/blogs/jesseliberty/0MiniT/MVVMWithBehaviors.zip" target="_blank">here</a>)</p>
<p>Immediately add a new UserControl and name it PeopleView. Here is the Xaml for the UserControl:</p>
<div id="highlighter_547889" class="syntaxhighlighter  xml">
<div class="bar">
<div class="toolbar"><a class="item viewSource" style="width: 16px; height: 16px;" title="view source" href="#viewSource">view source</a></p>
<div class="item copyToClipboard"><object id="highlighter_547889_clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="Movie" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="Src" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="WMode" value="Transparent" /><param name="Play" value="0" /><param name="Loop" value="-1" /><param name="Quality" value="High" /><param name="Menu" value="0" /><param name="AllowScriptAccess" value="always" /><param name="Scale" value="ShowAll" /><param name="DeviceFont" value="0" /><param name="EmbedMovie" value="0" /><param name="SeamlessTabbing" value="1" /><param name="Profile" value="0" /><param name="ProfilePort" value="0" /><param name="AllowNetworking" value="all" /><param name="AllowFullScreen" value="false" /><param name="wmode" value="Transparent" /><param name="allowfullscreen" value="false" /><param name="quality" value="High" /><embed id="highlighter_547889_clipboard" type="application/x-shockwave-flash" width="16" height="16" allowfullscreen="false" allownetworking="all" profileport="0" profile="0" seamlesstabbing="1" embedmovie="0" devicefont="0" scale="ShowAll" allowscriptaccess="always" menu="0" quality="High" loop="-1" play="0" wmode="Transparent" movie="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf"></embed></object></div>
<p><a class="item printSource" style="width: 16px; height: 16px;" title="print" href="#printSource">print</a><a class="item about" style="width: 16px; height: 16px;" title="?" href="#about">?</a></p>
</div>
</div>
<div class="lines">
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>01</code></td>
<td class="content"><code class="xml plain">&lt;</code><code class="xml keyword">UserControl</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>02</code></td>
<td class="content"><code class="xml color1">x:Class</code><code class="xml plain">=</code><code class="xml string">"MVVMWithBehaviors.PeopleView"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>03</code></td>
<td class="content"><code class="xml color1">xmlns</code><code class="xml plain">= </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>04</code></td>
<td class="content"><code class="xml string">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>05</code></td>
<td class="content"><code class="xml color1">xmlns:x</code><code class="xml plain">= </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>06</code></td>
<td class="content"><code class="xml string">"http://schemas.microsoft.com/winfx/2006/xaml"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>07</code></td>
<td class="content"><code class="xml color1">xmlns:d</code><code class="xml plain">= </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>08</code></td>
<td class="content"><code class="xml string">"http://schemas.microsoft.com/expression/blend/2008"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>09</code></td>
<td class="content"><code class="xml color1">xmlns:mc</code><code class="xml plain">=</code><code class="xml string">"http://schemas.openxmlformats.org/markup-compatibility/2006"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>10</code></td>
<td class="content"><code class="xml color1">mc:Ignorable</code><code class="xml plain">=</code><code class="xml string">"d"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>11</code></td>
<td class="content"><code class="xml color1">d:DesignHeight</code><code class="xml plain">=</code><code class="xml string">"300"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>12</code></td>
<td class="content"><code class="xml color1">d:DesignWidth</code><code class="xml plain">=</code><code class="xml string">"400"</code><code class="xml plain">&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>13</code></td>
<td class="content"><code class="xml plain">&lt;</code><code class="xml keyword">Grid</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>14</code></td>
<td class="content"><code class="xml color1">x:Name</code><code class="xml plain">=</code><code class="xml string">"LayoutRoot"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>15</code></td>
<td class="content"><code class="xml color1">Background</code><code class="xml plain">=</code><code class="xml string">"White"</code><code class="xml plain">&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>16</code></td>
<td class="content"><code class="xml plain">&lt;</code><code class="xml keyword">ListBox</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>17</code></td>
<td class="content"><code class="xml color1">Name</code><code class="xml plain">=</code><code class="xml string">"Names"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>18</code></td>
<td class="content"><code class="xml color1">Background</code><code class="xml plain">=</code><code class="xml string">"Beige"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>19</code></td>
<td class="content"><code class="xml color1">Width</code><code class="xml plain">=</code><code class="xml string">"200"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>20</code></td>
<td class="content"><code class="xml color1">Height</code><code class="xml plain">=</code><code class="xml string">"250"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>21</code></td>
<td class="content"><code class="xml color1">HorizontalAlignment</code><code class="xml plain">=</code><code class="xml string">"Center"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>22</code></td>
<td class="content"><code class="xml color1">VerticalAlignment</code><code class="xml plain">=</code><code class="xml string">"Center"</code><code class="xml plain">&gt;&lt;/</code><code class="xml keyword">ListBox</code><code class="xml plain">&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>23</code></td>
<td class="content"><code class="xml plain">&lt;/</code><code class="xml keyword">Grid</code><code class="xml plain">&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>24</code></td>
<td class="content"><code class="xml plain">&lt;/</code><code class="xml keyword">UserControl</code><code class="xml plain">&gt;</code></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div>For completeness, here is the Xaml for MainPage.xaml</div>
<div id="highlighter_873906" class="syntaxhighlighter  xml">
<div class="bar">
<div class="toolbar"><a class="item viewSource" style="width: 16px; height: 16px;" title="view source" href="#viewSource">view source</a></p>
<div class="item copyToClipboard"><object id="highlighter_873906_clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="Movie" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="Src" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="WMode" value="Transparent" /><param name="Play" value="0" /><param name="Loop" value="-1" /><param name="Quality" value="High" /><param name="Menu" value="0" /><param name="AllowScriptAccess" value="always" /><param name="Scale" value="ShowAll" /><param name="DeviceFont" value="0" /><param name="EmbedMovie" value="0" /><param name="SeamlessTabbing" value="1" /><param name="Profile" value="0" /><param name="ProfilePort" value="0" /><param name="AllowNetworking" value="all" /><param name="AllowFullScreen" value="false" /><param name="wmode" value="Transparent" /><param name="allowfullscreen" value="false" /><param name="quality" value="High" /><embed id="highlighter_873906_clipboard" type="application/x-shockwave-flash" width="16" height="16" allowfullscreen="false" allownetworking="all" profileport="0" profile="0" seamlesstabbing="1" embedmovie="0" devicefont="0" scale="ShowAll" allowscriptaccess="always" menu="0" quality="High" loop="-1" play="0" wmode="Transparent" movie="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf"></embed></object></div>
<p><a class="item printSource" style="width: 16px; height: 16px;" title="print" href="#printSource">print</a><a class="item about" style="width: 16px; height: 16px;" title="?" href="#about">?</a></p>
</div>
</div>
<div class="lines">
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>01</code></td>
<td class="content"><code class="xml plain">&lt;</code><code class="xml keyword">UserControl</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>02</code></td>
<td class="content"><code class="xml color1">x:Class</code><code class="xml plain">=</code><code class="xml string">"MVVMWithBehaviors.MainPage"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>03</code></td>
<td class="content"><code class="xml color1">xmlns</code><code class="xml plain">=</code><code class="xml string">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>04</code></td>
<td class="content"><code class="xml color1">xmlns:x</code><code class="xml plain">=</code><code class="xml string">"http://schemas.microsoft.com/winfx/2006/xaml"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>05</code></td>
<td class="content"><code class="xml color1">xmlns:d</code><code class="xml plain">=</code><code class="xml string">"http://schemas.microsoft.com/expression/blend/2008"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>06</code></td>
<td class="content"><code class="xml color1">xmlns:mc</code><code class="xml plain">=</code><code class="xml string">"http://schemas.openxmlformats.org/markup-compatibility/2006"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>07</code></td>
<td class="content"><code class="xml color1">mc:Ignorable</code><code class="xml plain">=</code><code class="xml string">"d"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>08</code></td>
<td class="content"><code class="xml color1">xmlns:me</code><code class="xml plain">=</code><code class="xml string">"clr-namespace:MVVMWithBehaviors"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>09</code></td>
<td class="content"><code class="xml color1">d:DesignHeight</code><code class="xml plain">=</code><code class="xml string">"300"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>10</code></td>
<td class="content"><code class="xml color1">d:DesignWidth</code><code class="xml plain">=</code><code class="xml string">"400"</code><code class="xml plain">&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>11</code></td>
<td class="content"><code class="xml plain">&lt;</code><code class="xml keyword">Grid</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>12</code></td>
<td class="content"><code class="xml color1">x:Name</code><code class="xml plain">=</code><code class="xml string">"LayoutRoot"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>13</code></td>
<td class="content"><code class="xml color1">Background</code><code class="xml plain">=</code><code class="xml string">"White"</code><code class="xml plain">&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>14</code></td>
<td class="content"><code class="xml plain">&lt;</code><code class="xml keyword">me:PeopleView</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>15</code></td>
<td class="content"><code class="xml color1">HorizontalAlignment</code><code class="xml plain">=</code><code class="xml string">"Stretch"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>16</code></td>
<td class="content"><code class="xml color1">VerticalAlignment</code><code class="xml plain">=</code><code class="xml string">"Stretch"</code> <code class="xml plain">/&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>17</code></td>
<td class="content"><code class="xml plain">&lt;/</code><code class="xml keyword">Grid</code><code class="xml plain">&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>18</code></td>
<td class="content"><code class="xml plain">&lt;/</code><code class="xml keyword">UserControl</code><code class="xml plain">&gt;</code></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<table border="3" cellspacing="2" cellpadding="4" width="400">
<tbody>
<tr>
<td width="400" valign="top">Note: If my solution were named HVP I’d have the following projects to support this model:HVPHVP.Web</p>
<p>HVP.Model</p>
<p>HVP.ViewModel</p>
<p>HVP.View</p>
<p>HVP.Tests</p>
<p>The advantage, for me, is that when I wish to touch a method or property in another class, the compiler will let me know if I’m crossing a project boundary (I’ll need a using statement) and that is a great time to double check that I have my visibility correct (e.g., a class in the View project can include ViewModel but not vice versa)</td>
</tr>
</tbody>
</table>
<div>Next we’ll create PeopleViewModel, as a class.  The job of this class is to expose the properties (and as you’ll see, the methods) that we want the View to bind to.  Specifically, we want the ListBox within the view to bind its ItemsSource property to a collection of People, and we want the Person object to have a property which will display the name of that person. The complete source code is shown here:</div>
<h3>C#</h3>
<div id="highlighter_346336" class="syntaxhighlighter  csharp">
<div class="bar">
<div class="toolbar"><a class="item viewSource" style="width: 16px; height: 16px;" title="view source" href="#viewSource">view source</a></p>
<div class="item copyToClipboard"><object id="highlighter_346336_clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="Movie" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="Src" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="WMode" value="Transparent" /><param name="Play" value="0" /><param name="Loop" value="-1" /><param name="Quality" value="High" /><param name="Menu" value="0" /><param name="AllowScriptAccess" value="always" /><param name="Scale" value="ShowAll" /><param name="DeviceFont" value="0" /><param name="EmbedMovie" value="0" /><param name="SeamlessTabbing" value="1" /><param name="Profile" value="0" /><param name="ProfilePort" value="0" /><param name="AllowNetworking" value="all" /><param name="AllowFullScreen" value="false" /><param name="wmode" value="Transparent" /><param name="allowfullscreen" value="false" /><param name="quality" value="High" /><embed id="highlighter_346336_clipboard" type="application/x-shockwave-flash" width="16" height="16" allowfullscreen="false" allownetworking="all" profileport="0" profile="0" seamlesstabbing="1" embedmovie="0" devicefont="0" scale="ShowAll" allowscriptaccess="always" menu="0" quality="High" loop="-1" play="0" wmode="Transparent" movie="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf"></embed></object></div>
<p><a class="item printSource" style="width: 16px; height: 16px;" title="print" href="#printSource">print</a><a class="item about" style="width: 16px; height: 16px;" title="?" href="#about">?</a></p>
</div>
</div>
<div class="lines">
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>01</code></td>
<td class="content"><code class="csharp keyword">using</code> <code class="csharp plain">System.Collections.ObjectModel; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>02</code></td>
<td class="content"><code class="csharp keyword">using</code> <code class="csharp plain">System.ComponentModel; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>03</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>04</code></td>
<td class="content"><code class="csharp keyword">namespace</code> <code class="csharp plain">MVVMWithBehaviors </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>05</code></td>
<td class="content"><code class="csharp plain">{ </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>06</code></td>
<td class="content"><code class="csharp keyword">public</code> <code class="csharp keyword">class</code> <code class="csharp plain">PeopleViewModel : INotifyPropertyChanged </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>07</code></td>
<td class="content"><code class="csharp plain">{ </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>08</code></td>
<td class="content"><code class="csharp keyword">public</code> <code class="csharp keyword">class</code> <code class="csharp plain">Person </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>09</code></td>
<td class="content"><code class="csharp plain">{ </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>10</code></td>
<td class="content"><code class="csharp keyword">public</code> <code class="csharp keyword">string</code> <code class="csharp plain">Name { </code><code class="csharp keyword">get</code><code class="csharp plain">; </code><code class="csharp keyword">private</code> <code class="csharp keyword">set</code><code class="csharp plain">; } </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>11</code></td>
<td class="content"><code class="csharp keyword">public</code> <code class="csharp plain">Person( </code><code class="csharp keyword">string</code> <code class="csharp plain">name ) </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>12</code></td>
<td class="content"><code class="csharp plain">{ </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>13</code></td>
<td class="content"><code class="csharp keyword">this</code><code class="csharp plain">.Name = name; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>14</code></td>
<td class="content"><code class="csharp plain">} </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>15</code></td>
<td class="content"><code class="csharp plain">} </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>16</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>17</code></td>
<td class="content"><code class="csharp keyword">private</code> <code class="csharp plain">ObservableCollection&lt;PERSON&gt; people; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>18</code></td>
<td class="content"><code class="csharp keyword">public</code> <code class="csharp plain">ObservableCollection&lt;/PERSON&gt;&lt;PERSON&gt; People </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>19</code></td>
<td class="content"><code class="csharp plain">{ </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>20</code></td>
<td class="content"><code class="csharp keyword">get</code> <code class="csharp plain">{ </code><code class="csharp keyword">return</code> <code class="csharp plain">people; } </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>21</code></td>
<td class="content"><code class="csharp keyword">set</code> <code class="csharp plain">{ people = value; } </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>22</code></td>
<td class="content"><code class="csharp plain">} </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>23</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>24</code></td>
<td class="content"><code class="csharp keyword">public</code> <code class="csharp plain">PeopleViewModel() </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>25</code></td>
<td class="content"><code class="csharp plain">{ </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>26</code></td>
<td class="content"><code class="csharp plain">MockGetDataFromTheModel(); </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>27</code></td>
<td class="content"><code class="csharp plain">} </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>28</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>29</code></td>
<td class="content"><code class="csharp keyword">private</code> <code class="csharp keyword">void</code> <code class="csharp plain">MockGetDataFromTheModel() </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>30</code></td>
<td class="content"><code class="csharp plain">{ </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>31</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>32</code></td>
<td class="content"><code class="csharp keyword">string</code><code class="csharp plain">[ ] firsts = </code><code class="csharp keyword">new</code><code class="csharp plain">[ ] { </code><code class="csharp string">"Tom"</code><code class="csharp plain">, </code><code class="csharp string">"Dick"</code><code class="csharp plain">, </code><code class="csharp string">"Harry"</code><code class="csharp plain">, </code><code class="csharp string">"Joe"</code><code class="csharp plain">, </code><code class="csharp string">"John"</code><code class="csharp plain">, </code><code class="csharp string">"Ringo"</code> <code class="csharp plain">}; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>33</code></td>
<td class="content"><code class="csharp keyword">string</code><code class="csharp plain">[ ] lasts = </code><code class="csharp keyword">new</code><code class="csharp plain">[ ] { </code><code class="csharp string">"Liberty"</code><code class="csharp plain">, </code><code class="csharp string">"Papa"</code><code class="csharp plain">, </code><code class="csharp string">"Hanselman"</code><code class="csharp plain">, </code><code class="csharp string">"Heuer"</code><code class="csharp plain">, </code><code class="csharp string">"Brown"</code><code class="csharp plain">, </code><code class="csharp string">"Gu"</code> <code class="csharp plain">}; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>34</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>35</code></td>
<td class="content"><code class="csharp plain">var r = </code><code class="csharp keyword">new</code> <code class="csharp plain">System.Random(); </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>36</code></td>
<td class="content"><code class="csharp plain">people = </code><code class="csharp keyword">new</code> <code class="csharp plain">ObservableCollection &lt;/PERSON&gt;&lt;PERSON&gt;(); </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>37</code></td>
<td class="content"><code class="csharp keyword">for</code> <code class="csharp plain">(</code><code class="csharp keyword">int</code> <code class="csharp plain">i = 0; i  &lt; 10; i++) </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>38</code></td>
<td class="content"><code class="csharp plain">{ </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>39</code></td>
<td class="content"><code class="csharp plain">people.Add( </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>40</code></td>
<td class="content"><code class="csharp keyword">new</code> <code class="csharp plain">Person( </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>41</code></td>
<td class="content"><code class="csharp plain">firsts[r.Next( firsts.Length )] </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>42</code></td>
<td class="content"><code class="csharp plain">+ </code><code class="csharp string">" "</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>43</code></td>
<td class="content"><code class="csharp plain">+ lasts[r.Next( lasts.Length )] ) ); </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>44</code></td>
<td class="content"><code class="csharp plain">} </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>45</code></td>
<td class="content"><code class="csharp plain">} </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>46</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>47</code></td>
<td class="content"><code class="csharp keyword">public</code> <code class="csharp keyword">event</code> <code class="csharp plain">PropertyChangedEventHandler PropertyChanged; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>48</code></td>
<td class="content"><code class="csharp keyword">private</code> <code class="csharp keyword">void</code> <code class="csharp plain">OnPropertyChanged( </code><code class="csharp keyword">string</code> <code class="csharp plain">propertyName ) </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>49</code></td>
<td class="content"><code class="csharp plain">{ </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>50</code></td>
<td class="content"><code class="csharp keyword">if</code> <code class="csharp plain">(PropertyChanged != </code><code class="csharp keyword">null</code><code class="csharp plain">) </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>51</code></td>
<td class="content"><code class="csharp plain">{ </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>52</code></td>
<td class="content"><code class="csharp plain">PropertyChanged( </code><code class="csharp keyword">this</code><code class="csharp plain">, </code><code class="csharp keyword">new</code> <code class="csharp plain">PropertyChangedEventArgs( propertyName ) ); </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>53</code></td>
<td class="content"><code class="csharp plain">} </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>54</code></td>
<td class="content"><code class="csharp plain">} </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>55</code></td>
<td class="content"><code class="csharp plain">} </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>56</code></td>
<td class="content"><code class="csharp plain">}</code></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<h3>VB.Net</h3>
<div id="highlighter_22900" class="syntaxhighlighter  vb">
<div class="bar">
<div class="toolbar"><a class="item viewSource" style="width: 16px; height: 16px;" title="view source" href="#viewSource">view source</a></p>
<div class="item copyToClipboard"><object id="highlighter_22900_clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="Movie" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="Src" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="WMode" value="Transparent" /><param name="Play" value="0" /><param name="Loop" value="-1" /><param name="Quality" value="High" /><param name="Menu" value="0" /><param name="AllowScriptAccess" value="always" /><param name="Scale" value="ShowAll" /><param name="DeviceFont" value="0" /><param name="EmbedMovie" value="0" /><param name="SeamlessTabbing" value="1" /><param name="Profile" value="0" /><param name="ProfilePort" value="0" /><param name="AllowNetworking" value="all" /><param name="AllowFullScreen" value="false" /><param name="wmode" value="Transparent" /><param name="allowfullscreen" value="false" /><param name="quality" value="High" /><embed id="highlighter_22900_clipboard" type="application/x-shockwave-flash" width="16" height="16" allowfullscreen="false" allownetworking="all" profileport="0" profile="0" seamlesstabbing="1" embedmovie="0" devicefont="0" scale="ShowAll" allowscriptaccess="always" menu="0" quality="High" loop="-1" play="0" wmode="Transparent" movie="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf"></embed></object></div>
<p><a class="item printSource" style="width: 16px; height: 16px;" title="print" href="#printSource">print</a><a class="item about" style="width: 16px; height: 16px;" title="?" href="#about">?</a></p>
</div>
</div>
<div class="lines">
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>01</code></td>
<td class="content"><code class="vb keyword">Imports</code> <code class="vb plain">System.Collections.ObjectModel </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>02</code></td>
<td class="content"><code class="vb keyword">Imports</code> <code class="vb plain">System.ComponentModel </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>03</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>04</code></td>
<td class="content"><code class="vb keyword">Namespace</code> <code class="vb plain">MVVMWithBehaviors </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>05</code></td>
<td class="content"><code class="vb keyword">Public</code> <code class="vb keyword">Class</code> <code class="vb plain">PeopleViewModel </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>06</code></td>
<td class="content"><code class="vb keyword">Implements</code> <code class="vb plain">INotifyPropertyChanged </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>07</code></td>
<td class="content"><code class="vb keyword">Public</code> <code class="vb keyword">Class</code> <code class="vb plain">Person </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>08</code></td>
<td class="content"><code class="vb keyword">Private</code> <code class="vb plain">privateName </code><code class="vb keyword">As</code> <code class="vb keyword">String</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>09</code></td>
<td class="content"><code class="vb keyword">Public</code> <code class="vb keyword">Property</code> <code class="vb plain">Name() </code><code class="vb keyword">As</code> <code class="vb keyword">String</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>10</code></td>
<td class="content"><code class="vb keyword">Get</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>11</code></td>
<td class="content"><code class="vb keyword">Return</code> <code class="vb plain">privateName </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>12</code></td>
<td class="content"><code class="vb keyword">End</code> <code class="vb keyword">Get</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>13</code></td>
<td class="content"><code class="vb keyword">Private</code> <code class="vb keyword">Set</code><code class="vb plain">(</code><code class="vb keyword">ByVal</code> <code class="vb plain">value </code><code class="vb keyword">As</code> <code class="vb keyword">String</code><code class="vb plain">) </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>14</code></td>
<td class="content"><code class="vb plain">privateName = value </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>15</code></td>
<td class="content"><code class="vb keyword">End</code> <code class="vb keyword">Set</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>16</code></td>
<td class="content"><code class="vb keyword">End</code> <code class="vb keyword">Property</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>17</code></td>
<td class="content"><code class="vb keyword">Public</code> <code class="vb keyword">Sub</code> <code class="vb keyword">New</code><code class="vb plain">(</code><code class="vb keyword">ByVal</code> <code class="vb plain">name </code><code class="vb keyword">As</code> <code class="vb keyword">String</code><code class="vb plain">) </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>18</code></td>
<td class="content"><code class="vb keyword">Me</code><code class="vb plain">.Name = name </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>19</code></td>
<td class="content"><code class="vb keyword">End</code> <code class="vb keyword">Sub</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>20</code></td>
<td class="content"><code class="vb keyword">End</code> <code class="vb keyword">Class</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>21</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>22</code></td>
<td class="content"><code class="vb keyword">Private</code> <code class="vb plain">people_Renamed </code><code class="vb keyword">As</code> <code class="vb plain">ObservableCollection(Of Person) </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>23</code></td>
<td class="content"><code class="vb keyword">Public</code> <code class="vb keyword">Property</code> <code class="vb plain">People() </code><code class="vb keyword">As</code> <code class="vb plain">ObservableCollection(Of Person) </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>24</code></td>
<td class="content"><code class="vb keyword">Get</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>25</code></td>
<td class="content"><code class="vb keyword">Return</code> <code class="vb plain">people_Renamed </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>26</code></td>
<td class="content"><code class="vb keyword">End</code> <code class="vb keyword">Get</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>27</code></td>
<td class="content"><code class="vb keyword">Set</code><code class="vb plain">(</code><code class="vb keyword">ByVal</code> <code class="vb plain">value </code><code class="vb keyword">As</code> <code class="vb plain">ObservableCollection(Of Person)) </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>28</code></td>
<td class="content"><code class="vb plain">people_Renamed = value </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>29</code></td>
<td class="content"><code class="vb keyword">End</code> <code class="vb keyword">Set</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>30</code></td>
<td class="content"><code class="vb keyword">End</code> <code class="vb keyword">Property</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>31</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>32</code></td>
<td class="content"><code class="vb keyword">Public</code> <code class="vb keyword">Sub</code> <code class="vb keyword">New</code><code class="vb plain">() </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>33</code></td>
<td class="content"><code class="vb plain">MockGetDataFromTheModel() </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>34</code></td>
<td class="content"><code class="vb keyword">End</code> <code class="vb keyword">Sub</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>35</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>36</code></td>
<td class="content"><code class="vb keyword">Private</code> <code class="vb keyword">Sub</code> <code class="vb plain">MockGetDataFromTheModel() </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>37</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>38</code></td>
<td class="content"><code class="vb keyword">Dim</code> <code class="vb plain">firsts() </code><code class="vb keyword">As</code> <code class="vb keyword">String</code> <code class="vb plain">= { </code><code class="vb string">"Tom"</code><code class="vb plain">, </code><code class="vb string">"Dick"</code><code class="vb plain">, </code><code class="vb string">"Harry"</code><code class="vb plain">, </code><code class="vb string">"Joe"</code><code class="vb plain">, </code><code class="vb string">"John"</code><code class="vb plain">, </code><code class="vb string">"Ringo"</code> <code class="vb plain">} </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>39</code></td>
<td class="content"><code class="vb keyword">Dim</code> <code class="vb plain">lasts() </code><code class="vb keyword">As</code> <code class="vb keyword">String</code> <code class="vb plain">= { </code><code class="vb string">"Liberty"</code><code class="vb plain">, </code><code class="vb string">"Papa"</code><code class="vb plain">, </code><code class="vb string">"Hanselman"</code><code class="vb plain">, </code><code class="vb string">"Heuer"</code><code class="vb plain">, </code><code class="vb string">"Brown"</code><code class="vb plain">, </code><code class="vb string">"Gu"</code> <code class="vb plain">} </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>40</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>41</code></td>
<td class="content"><code class="vb keyword">Dim</code> <code class="vb plain">r = </code><code class="vb keyword">New</code> <code class="vb plain">System.Random() </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>42</code></td>
<td class="content"><code class="vb plain">people_Renamed = </code><code class="vb keyword">New</code> <code class="vb plain">ObservableCollection (Of Person)() </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>43</code></td>
<td class="content"><code class="vb keyword">For</code> <code class="vb plain">i </code><code class="vb keyword">As</code> <code class="vb keyword">Integer</code> <code class="vb plain">= 0 </code><code class="vb keyword">To</code> <code class="vb plain">9 </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>44</code></td>
<td class="content"><code class="vb plain">people_Renamed.Add(</code><code class="vb keyword">New</code> <code class="vb plain">Person(firsts(r.</code><code class="vb keyword">Next</code><code class="vb plain">(firsts.Length)) &amp; </code><code class="vb string">" "</code> <code class="vb plain">&amp; lasts(r.</code><code class="vb keyword">Next</code><code class="vb plain">(lasts.Length)))) </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>45</code></td>
<td class="content"><code class="vb keyword">Next</code> <code class="vb plain">i </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>46</code></td>
<td class="content"><code class="vb keyword">End</code> <code class="vb keyword">Sub</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>47</code></td>
<td class="content"></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>48</code></td>
<td class="content"><code class="vb keyword">Public</code> <code class="vb keyword">Event</code> <code class="vb plain">PropertyChanged </code><code class="vb keyword">As</code> <code class="vb plain">PropertyChangedEventHandler </code><code class="vb keyword">Implements</code> <code class="vb plain">INotifyPropertyChanged.PropertyChanged </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>49</code></td>
<td class="content"><code class="vb keyword">Private</code> <code class="vb keyword">Sub</code> <code class="vb plain">OnPropertyChanged(</code><code class="vb keyword">ByVal</code> <code class="vb plain">propertyName </code><code class="vb keyword">As</code> <code class="vb keyword">String</code><code class="vb plain">) </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>50</code></td>
<td class="content"><code class="vb keyword">RaiseEvent</code> <code class="vb plain">PropertyChanged(</code><code class="vb keyword">Me</code><code class="vb plain">, </code><code class="vb keyword">New</code> <code class="vb plain">PropertyChangedEventArgs(propertyName)) </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>51</code></td>
<td class="content"><code class="vb keyword">End</code> <code class="vb keyword">Sub</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>52</code></td>
<td class="content"><code class="vb keyword">End</code> <code class="vb keyword">Class</code></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>We start by defining a Person (lines 6-15) and then we give the PeopleViewModel class a property People which is an ObservableCollection of Person objects.  The constructor (lines 24-27) calls a method that mocks up getting data from the Model; in this case I just generate ten names on lines 30-48   The final code implements INotifyPropertyChanged, which is not required yet, as the only property we have is an Observable collection.</p>
<h3>Binding</h3>
<div>We are now ready to bind the ListBox inside the View class to the ViewModel.  Add the following two lines to the ListBox declaration in PeopleView.xaml</div>
<div>
<pre style="line-height: 12pt; width: 100%; font-family: 'direction; color: black; font-size: 8pt; overflow: visible; border-style: none; margin: 0; padding: 0; background-color: #f4f4f4; text-align: left';">ItemsSource="{Binding People}"DisplayMemberPath="Name"</pre>
</div>
<p>and then add this to the constructor in the code behind:</p>
<h3>C#</h3>
<div id="highlighter_860854" class="syntaxhighlighter  csharp">
<div class="bar">
<div class="toolbar"><a class="item viewSource" style="width: 16px; height: 16px;" title="view source" href="#viewSource">view source</a></p>
<div class="item copyToClipboard"><object id="highlighter_860854_clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="Movie" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="Src" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="WMode" value="Transparent" /><param name="Play" value="0" /><param name="Loop" value="-1" /><param name="Quality" value="High" /><param name="Menu" value="0" /><param name="AllowScriptAccess" value="always" /><param name="Scale" value="ShowAll" /><param name="DeviceFont" value="0" /><param name="EmbedMovie" value="0" /><param name="SeamlessTabbing" value="1" /><param name="Profile" value="0" /><param name="ProfilePort" value="0" /><param name="AllowNetworking" value="all" /><param name="AllowFullScreen" value="false" /><param name="wmode" value="Transparent" /><param name="allowfullscreen" value="false" /><param name="quality" value="High" /><embed id="highlighter_860854_clipboard" type="application/x-shockwave-flash" width="16" height="16" allowfullscreen="false" allownetworking="all" profileport="0" profile="0" seamlesstabbing="1" embedmovie="0" devicefont="0" scale="ShowAll" allowscriptaccess="always" menu="0" quality="High" loop="-1" play="0" wmode="Transparent" movie="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf"></embed></object></div>
<p><a class="item printSource" style="width: 16px; height: 16px;" title="print" href="#printSource">print</a><a class="item about" style="width: 16px; height: 16px;" title="?" href="#about">?</a></p>
</div>
</div>
<div class="lines">
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>1</code></td>
<td class="content"><code class="csharp plain">DataContext = </code><code class="csharp keyword">new</code> <code class="csharp plain">PeopleViewModel();</code></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<h3>VB.Net</h3>
<div id="highlighter_270418" class="syntaxhighlighter  vb">
<div class="bar">
<div class="toolbar"><a class="item viewSource" style="width: 16px; height: 16px;" title="view source" href="#viewSource">view source</a></p>
<div class="item copyToClipboard"><object id="highlighter_270418_clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="Movie" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="Src" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="WMode" value="Transparent" /><param name="Play" value="0" /><param name="Loop" value="-1" /><param name="Quality" value="High" /><param name="Menu" value="0" /><param name="AllowScriptAccess" value="always" /><param name="Scale" value="ShowAll" /><param name="DeviceFont" value="0" /><param name="EmbedMovie" value="0" /><param name="SeamlessTabbing" value="1" /><param name="Profile" value="0" /><param name="ProfilePort" value="0" /><param name="AllowNetworking" value="all" /><param name="AllowFullScreen" value="false" /><param name="wmode" value="Transparent" /><param name="allowfullscreen" value="false" /><param name="quality" value="High" /><embed id="highlighter_270418_clipboard" type="application/x-shockwave-flash" width="16" height="16" allowfullscreen="false" allownetworking="all" profileport="0" profile="0" seamlesstabbing="1" embedmovie="0" devicefont="0" scale="ShowAll" allowscriptaccess="always" menu="0" quality="High" loop="-1" play="0" wmode="Transparent" movie="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf"></embed></object></div>
<p><a class="item printSource" style="width: 16px; height: 16px;" title="print" href="#printSource">print</a><a class="item about" style="width: 16px; height: 16px;" title="?" href="#about">?</a></p>
</div>
</div>
<div class="lines">
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>1</code></td>
<td class="content"><code class="vb plain">DataContext = </code><code class="vb keyword">New</code> <code class="vb plain">PeopleViewModel()</code></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div>Running the application will now display the data from the ViewModel in the View</div>
<h3>Behavior</h3>
<div>The design of the <a href="http://slhvp.com" target="_blank">Silverlight HVP</a> says that when an object changes its state (e.g., the user changes the current item in a list box) the View object will notify the state object of the change. The State object then raises the StateChanged event to which all the View objects have subscribed, and each resets its state.</div>
<div>It would be nice to avoid having code in the View to manage the State Change notification; we’d like to bind this as well as the data, thus increasing the overall testability of the project.  Unfortunately, as of now, there is little support for this built into Silverlight (though there is some, using <a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand(VS.96).aspx" target="_blank">ICommand</a>, with ButtonBase and HyperLink derived classes)</div>
<div>The solution is to be friends with John Papa, who pointed me to the Expression Blend Samples project on CodePlex, which, when installed, provides a library that includes, among other things, the wondrous CallDataMethod, enabling you to trigger a method in your ViewModel based on an event in your view(!)</div>
<div>Since I had to spend quite a bit of time figuring out how to make this work, I thought I’d walk through it here. It is very easy, once you know how, but the project doesn’t yet provide the necessary instructions. Begin by going to the <a href="http://expressionblend.codeplex.com/" target="_blank">Expression Blend Samples</a> page and downloading the latest release (which currently is from July 12, 2009 and marked Alpha.  This will put a .msi file on your disk, and running that will install the samples; unfortunately it will do so shockingly quietly, and you’ll have no idea what to do next.</div>
<div>Here’s what you do:  in your project you’ll need to add two references. The first is to System.Windows.Interactivity which on my machine is in:</div>
<div>
<pre style="line-height: 12pt; width: 100%; font-family: 'direction; color: black; font-size: 8pt; overflow: visible; border-style: none; margin: 0; padding: 0; background-color: #f4f4f4; text-align: left';">c:\Program Files (x86)\Microsoft SDKs\Expression\Blend Preview for
.NET 4\Interactivity\Libraries\Silverlight\
System.Windows.Interactivity.dll</pre>
</div>
<div>the second is Expression.Samples.Interactivey, which on my machine was in:</div>
<div>
<pre style="line-height: 12pt; width: 100%; font-family: 'direction; color: black; font-size: 8pt; overflow: visible; border-style: none; margin: 0; padding: 0; background-color: #f4f4f4; text-align: left';">C:\Program Files (x86)\Microsoft Expression\Blend 3
Samples\Silverlight\Design\Expression.Samples.Interactivity.dll</pre>
</div>
<div>You’ll now modify the view class to include the namespaces:</div>
<div id="codeSnippetWrapper">
<pre style="line-height: 12pt; width: 100%; font-family: 'direction; color: black; font-size: 8pt; overflow: visible; border-style: none; margin: 0; padding: 0; background-color: #f4f4f4; text-align: left';">xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=
System.Windows.Interactivity"xmlns:si="clr-namespace:Expression.Samples.Interactivity;assembly=
Expression.Samples.Interactivity"</pre>
</div>
<p>and finally, you modify the control (the listbox) to add the trigger and behavior</p>
<div id="highlighter_83255" class="syntaxhighlighter  xml">
<div class="bar     ">
<div class="toolbar"><a class="item viewSource" style="width: 16px; height: 16px;" title="view source" href="#viewSource">view source</a></p>
<div class="item copyToClipboard"><object id="highlighter_83255_clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="Movie" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="Src" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="WMode" value="Transparent" /><param name="Play" value="0" /><param name="Loop" value="-1" /><param name="Quality" value="High" /><param name="Menu" value="0" /><param name="AllowScriptAccess" value="always" /><param name="Scale" value="ShowAll" /><param name="DeviceFont" value="0" /><param name="EmbedMovie" value="0" /><param name="SeamlessTabbing" value="1" /><param name="Profile" value="0" /><param name="ProfilePort" value="0" /><param name="AllowNetworking" value="all" /><param name="AllowFullScreen" value="false" /><param name="wmode" value="Transparent" /><param name="allowfullscreen" value="false" /><param name="quality" value="High" /><embed id="highlighter_83255_clipboard" type="application/x-shockwave-flash" width="16" height="16" allowfullscreen="false" allownetworking="all" profileport="0" profile="0" seamlesstabbing="1" embedmovie="0" devicefont="0" scale="ShowAll" allowscriptaccess="always" menu="0" quality="High" loop="-1" play="0" wmode="Transparent" movie="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf"></embed></object></div>
<p><a class="item printSource" style="width: 16px; height: 16px;" title="print" href="#printSource">print</a><a class="item about" style="width: 16px; height: 16px;" title="?" href="#about">?</a></p>
</div>
</div>
<div class="lines">
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>01</code></td>
<td class="content"><code class="xml plain">&lt;</code><code class="xml keyword">ListBox</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>02</code></td>
<td class="content"><code class="xml color1">Name</code><code class="xml plain">=</code><code class="xml string">"Names"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>03</code></td>
<td class="content"><code class="xml color1">Background</code><code class="xml plain">=</code><code class="xml string">"Beige"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>04</code></td>
<td class="content"><code class="xml color1">Width</code><code class="xml plain">=</code><code class="xml string">"200"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>05</code></td>
<td class="content"><code class="xml color1">Height</code><code class="xml plain">=</code><code class="xml string">"250"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>06</code></td>
<td class="content"><code class="xml color1">HorizontalAlignment</code><code class="xml plain">=</code><code class="xml string">"Center"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>07</code></td>
<td class="content"><code class="xml color1">VerticalAlignment</code><code class="xml plain">=</code><code class="xml string">"Center"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>08</code></td>
<td class="content"><code class="xml color1">ItemsSource</code><code class="xml plain">=</code><code class="xml string">"{Binding People}"</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>09</code></td>
<td class="content"><code class="xml color1">DisplayMemberPath</code><code class="xml plain">=</code><code class="xml string">"Name"</code><code class="xml plain">&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>10</code></td>
<td class="content"><code class="xml plain">&lt;</code><code class="xml keyword">i:Interaction.Triggers</code><code class="xml plain">&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>11</code></td>
<td class="content"><code class="xml plain">&lt;</code><code class="xml keyword">i:EventTrigger</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>12</code></td>
<td class="content"><code class="xml color1">EventName</code><code class="xml plain">=</code><code class="xml string">"SelectionChanged"</code><code class="xml plain">&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>13</code></td>
<td class="content"><code class="xml plain">&lt;</code><code class="xml keyword">si:CallDataMethod</code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>14</code></td>
<td class="content"><code class="xml color1">Method</code><code class="xml plain">=</code><code class="xml string">"HandleSelectionChanged"</code> <code class="xml plain">/&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>15</code></td>
<td class="content"><code class="xml plain">&lt;/</code><code class="xml keyword">i:EventTrigger</code><code class="xml plain">&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>16</code></td>
<td class="content"><code class="xml plain">&lt;/</code><code class="xml keyword">i:Interaction.Triggers</code><code class="xml plain">&gt; </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>17</code></td>
<td class="content"><code class="xml plain">&lt;/</code><code class="xml keyword">ListBox</code><code class="xml plain">&gt;</code></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>The EventTrigger has a property for the EventName; indicating that this trigger will fire when the event SelectionChanged is raised for the ListBox.  The CallDataMethod has a property Method for the name of the method to invoke. Since the ViewModel class is the data context, you don’t need to indicated which class supplies the method, any more than you need to indicate which class has the property People to which the ListBox’s ItemsSource is binding.</p>
<p>Just add that method to the ViewModel class…</p>
<h3>C#</h3>
<div id="highlighter_621621" class="syntaxhighlighter  csharp">
<div class="bar">
<div class="toolbar"><a class="item viewSource" style="width: 16px; height: 16px;" title="view source" href="#viewSource">view source</a></p>
<div class="item copyToClipboard"><object id="highlighter_621621_clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="Movie" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="Src" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="WMode" value="Transparent" /><param name="Play" value="0" /><param name="Loop" value="-1" /><param name="Quality" value="High" /><param name="Menu" value="0" /><param name="AllowScriptAccess" value="always" /><param name="Scale" value="ShowAll" /><param name="DeviceFont" value="0" /><param name="EmbedMovie" value="0" /><param name="SeamlessTabbing" value="1" /><param name="Profile" value="0" /><param name="ProfilePort" value="0" /><param name="AllowNetworking" value="all" /><param name="AllowFullScreen" value="false" /><param name="wmode" value="Transparent" /><param name="allowfullscreen" value="false" /><param name="quality" value="High" /><embed id="highlighter_621621_clipboard" type="application/x-shockwave-flash" width="16" height="16" allowfullscreen="false" allownetworking="all" profileport="0" profile="0" seamlesstabbing="1" embedmovie="0" devicefont="0" scale="ShowAll" allowscriptaccess="always" menu="0" quality="High" loop="-1" play="0" wmode="Transparent" movie="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf"></embed></object></div>
<p><a class="item printSource" style="width: 16px; height: 16px;" title="print" href="#printSource">print</a><a class="item about" style="width: 16px; height: 16px;" title="?" href="#about">?</a></p>
</div>
</div>
<div class="lines">
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>1</code></td>
<td class="content"><code class="csharp keyword">public</code> <code class="csharp keyword">void</code> <code class="csharp plain">HandleSelectionChanged(){   System.Windows.MessageBox.Show( </code><code class="csharp string">"Update the state!"</code> <code class="csharp plain">);}</code></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<h3>VB.Net</h3>
<div id="highlighter_177409" class="syntaxhighlighter  vb">
<div class="bar ">
<div class="toolbar"><a class="item viewSource" style="width: 16px; height: 16px;" title="view source" href="#viewSource">view source</a></p>
<div class="item copyToClipboard"><object id="highlighter_177409_clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="Movie" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="Src" value="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf" /><param name="WMode" value="Transparent" /><param name="Play" value="0" /><param name="Loop" value="-1" /><param name="Quality" value="High" /><param name="Menu" value="0" /><param name="AllowScriptAccess" value="always" /><param name="Scale" value="ShowAll" /><param name="DeviceFont" value="0" /><param name="EmbedMovie" value="0" /><param name="SeamlessTabbing" value="1" /><param name="Profile" value="0" /><param name="ProfilePort" value="0" /><param name="AllowNetworking" value="all" /><param name="AllowFullScreen" value="false" /><param name="wmode" value="Transparent" /><param name="allowfullscreen" value="false" /><param name="quality" value="High" /><embed id="highlighter_177409_clipboard" type="application/x-shockwave-flash" width="16" height="16" allowfullscreen="false" allownetworking="all" profileport="0" profile="0" seamlesstabbing="1" embedmovie="0" devicefont="0" scale="ShowAll" allowscriptaccess="always" menu="0" quality="High" loop="-1" play="0" wmode="Transparent" movie="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf"></embed></object></div>
<p><a class="item printSource" style="width: 16px; height: 16px;" title="print" href="#printSource">print</a><a class="item about" style="width: 16px; height: 16px;" title="?" href="#about">?</a></p>
</div>
</div>
<div class="lines">
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>1</code></td>
<td class="content"><code class="vb keyword">Public</code> <code class="vb keyword">Sub</code> <code class="vb plain">HandleSelectionChanged() </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt2">
<table>
<tbody>
<tr>
<td class="number"><code>2</code></td>
<td class="content"><code class="vb plain">System.Windows.MessageBox.Show(</code><code class="vb string">"Update the state!"</code><code class="vb plain">) </code></td>
</tr>
</tbody>
</table>
</div>
<div class="line alt1">
<table>
<tbody>
<tr>
<td class="number"><code>3</code></td>
<td class="content"><code class="vb keyword">End</code> <code class="vb keyword">Sub</code></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>… and start your program. When you change the selection, the method you’ve bound to will be called.</p>
<p>In the <a href="http://slhvp.com" target="_blank">Silverlight HVP</a> this will allow us to bind the event notification to the SelectionChanged event, further decouples the control from its data and logic. The technical term for this is “good.”</p>
<h3>Overall Impact of Refactoring for MVVM</h3>
<p>While this  is not an exhaustive understanding of MVVM by any means, with these fundamentals, it became obvious how to break up my code, and I found that there was less of it, and it was more intention-revealing.</p>
<p>In fact, the code-behind for my View classes have no code at all except setting the dataContext; and the ViewModel code is short and extremely readable.</p>
<p>All in all, I find MVVM well worth the small cognitive startup costs; yielding a very natural separation of concerns, and perhaps equally important, exposing far more of the program to unit tests, and thus driving down the overall time to release.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>* In 1978 cult leader <a href="http://en.wikipedia.org/wiki/Jim_Jones" target="_blank">Jim Jones</a> induced 900 followers to commit “revolutionary suicide” by knowingly drinking cyanide-laced grape <a href="http://en.wikipedia.org/wiki/Flavor_Aid" target="_blank"><em>Flavor Aid</em></a><em>. </em>To the chagrin of General Foods,<em> </em>the cultural memory of the event is that they drank <a href="http://en.wikipedia.org/wiki/Kool-Aid" target="_blank">Kool Aid</a> and the expression. <a href="http://en.wikipedia.org/wiki/Drink_the_Kool_Aid" target="_blank">To drink the Kool Aid</a> has evolved to mean “to embrace without reservations, the ideas of a strong leader”</p>
<p><script type="text/javascript">// < ![CDATA[
// < ![CDATA[
// < ![CDATA[
// < ![CDATA[</p>
<p>                (function(){
                                var corecss = document.createElement('link');
                                var themecss = document.createElement('link');
                                var corecssurl = "http://slgeek.com/wordpress/wp-content/plugins/syntaxhighlighter/syntaxhighlighter/styles/shCore.css?ver=2.1.364b";
                                if ( corecss.setAttribute ) {
                                                                corecss.setAttribute( "rel", "stylesheet" );
                                                                corecss.setAttribute( "type", "text/css" );
                                                                corecss.setAttribute( "href", corecssurl );
                                } else {
                                                                corecss.rel = "stylesheet";
                                                                corecss.href = corecssurl;
                                }
                                document.getElementsByTagName("head")[0].appendChild(corecss);
                                var themecssurl = "http://slgeek.com/wordpress/wp-content/plugins/syntaxhighlighter/syntaxhighlighter/styles/shThemeDefault.css?ver=2.1.364b";
                                if ( themecss.setAttribute ) {
                                                                themecss.setAttribute( "rel", "stylesheet" );
                                                                themecss.setAttribute( "type", "text/css" );
                                                                themecss.setAttribute( "href", themecssurl );
                                } else {
                                                                themecss.rel = "stylesheet";
                                                                themecss.href = themecssurl;
                                }
                                document.getElementsByTagName("head")[0].appendChild(themecss);
                })();
                SyntaxHighlighter.config.clipboardSwf = 'http://slgeek.com/wordpress/wp-content/plugins/syntaxhighlighter/syntaxhighlighter/scripts/clipboard.swf';
                SyntaxHighlighter.config.strings.expandSource = 'show source';
                SyntaxHighlighter.config.strings.viewSource = 'view source';
                SyntaxHighlighter.config.strings.copyToClipboard = 'copy to clipboard';
                SyntaxHighlighter.config.strings.copyToClipboardConfirmation = 'The code is in your clipboard now';
                SyntaxHighlighter.config.strings.print = 'print';
                SyntaxHighlighter.config.strings.help = '?';
                SyntaxHighlighter.config.strings.alert = 'SyntaxHighlighter\n\n';
                SyntaxHighlighter.config.strings.noBrush = 'Can\'t find brush for: ';
                SyntaxHighlighter.config.strings.brushNotHtmlScript = 'Brush wasn\'t configured for html-script option: ';
                SyntaxHighlighter.defaults['auto-links'] = false;
                SyntaxHighlighter.all();
// ]]&gt;</script><script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript"></script><script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js" type="text/javascript"></script><script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js" type="text/javascript"></script><script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js" type="text/javascript"></script><script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js" type="text/javascript"></script><script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js" type="text/javascript"></script><script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js" type="text/javascript"></script><script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js" type="text/javascript"></script><script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js" type="text/javascript"></script><script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js" type="text/javascript"></script><script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js" type="text/javascript"></script><script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js" type="text/javascript"></script><script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js" type="text/javascript"></script><script type="text/javascript">// < ![CDATA[
// < ![CDATA[
// < ![CDATA[
// < ![CDATA[</p>
<p>SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
// ]]&gt;</script> </p>
]]></content:encoded>
			<wfw:commentRss>http://jesseliberty.com/2010/05/08/mvvm-its-not-kool-aid-3/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>MEF, Silverlight and the HVP</title>
		<link>http://jesseliberty.com/2010/05/08/mef-silverlight-and-the-hvp/</link>
		<comments>http://jesseliberty.com/2010/05/08/mef-silverlight-and-the-hvp/#comments</comments>
		<pubDate>Sat, 08 May 2010 17:03:00 +0000</pubDate>
		<dc:creator>Jesse Liberty</dc:creator>
				<category><![CDATA[HyperVideo Player]]></category>
		<category><![CDATA[Patterns & Skills]]></category>
		<category><![CDATA[Patterns]]></category>

		<guid isPermaLink="false">http://jesseliberty.com/2010/05/07/mef-silverlight-and-the-hvp/</guid>
		<description><![CDATA[This article is part of the Mini-Tutorial Series Executive Summary This article continues the design and exploration phase of the Silverlight HVP project by beginning to examine the role the Managed Extensibility Framework (MEF) will play in solving a number &#8230; <a href="http://jesseliberty.com/2010/05/08/mef-silverlight-and-the-hvp/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://silverlight.net/learn/tutorials/mini/1/" target="_blank"><img style="display: inline; border: 0pt none;" title="MiniTutorialLogo" src="http://jesseliberty.com/wp-content/uploads/2010/05/MiniTutorialLogo_thumb3.jpg" border="0" alt="MiniTutorialLogo" width="240" height="69" /></a><br />
This article is part of the <a href="http://silverlight.net/learn/tutorials/mini/1/" target="_blank">Mini-Tutorial Series</a></p>
<h1>Executive Summary</h1>
<p>This article continues the design and exploration phase of the <a href="http://slhvp.com" target="_blank">Silverlight HVP</a> project by beginning to examine the role the <a href="http://mef.CodePlex.com" target="_blank">Managed Extensibility Framework</a> (MEF) will play in solving a number of challenges in the project.</p>
<p><span id="more-1254"></span></p>
<h1>Goal: Creation of an Extensible, Modular, Reliable, Robust application</h1>
<p>The Silverlight HVP poses the challenge of accommodating the different functional requirements that different audiences will want built into or added onto the player. Further, we know that if the Silverlight HVP is a success the requirements will evolve over time as the player is adopted and adapted in unanticipated ways.</p>
<p>This, of course is not unusual in software development, and a number of “patterns” have emerged to handle shifting requirements and the need to be able to add and remove parts of an application over time or across deployments. Key to this are certain well understood approaches:</p>
<ul>
<li>Decoupling of the various tiers: presentation, business logic, data, persistence, etc.</li>
<li>Loosely coupled functional modules</li>
<li><a href="http://compositewpf.codeplex.com/" target="_blank">Composite Applications</a></li>
</ul>
<p>To achieve the decoupling we desire, as well as to create a highly reliable, performant and robust application, we’ve decided to integrate the <a href="http://mef.codeplex.com/" target="_blank">Managed Extension Framework</a> (<a href="http://mef.codeplex.com" target="_blank">MEF</a>)  from the very start. [We will look at adding <a href="http://msdn.microsoft.com/en-us/library/dd458809.aspx" target="_blank">Prism</a> after <a href="http://silverlighthvp.codeplex.com/wikipage?title=Milestones&amp;referringTitle=Documentation" target="_blank">R1</a>].</p>
<p>In addition to providing crucial loose coupling among functional modules, MEF will help significantly with:</p>
<ul>
<li>Improved performance by allowing <strong>on-demand delivery</strong> of modules, and creation of smaller .xap files (and thus faster load)</li>
<li>Extensibility through Discovery (the core program need not know all the available modules)</li>
<li>Post-production plug-in capabilities.  (E.g., if we want the HVP to be a plug-in for other programs that were not designed with MEF, we can accomplish this by creating a wrapper around the other program and then plugging in some or all of the HVP)</li>
</ul>
<p>There is a good bit more, but this already is a lot to consume.  In this (and possibly a few subsequent tutorials) as well as a forthcoming video or two, I will walk through using MEF in the project <em>exactly as I would were I doing this on a paid project as an independent consultant. </em></p>
<h3><em>Goal Based Successive Approximation</em></h3>
<p>My approach to new technologies is typically successive approximation, driven by the goals of the project. To begin, I’ll want to understand how I can add a simple visual component to my application without the author of the application knowing in advance what I’ll be adding.</p>
<p>MEF will allow me to take one of two approaches to placing the control onto my page:</p>
<ul>
<li>The hosting application knows about the new component, allocates space and tells the component where to display itself, or</li>
<li>The hosting application does not know about what components may or may not exist, but provides a place for each discovered component to display itself</li>
</ul>
<p>(You can certainly imagine a somewhat more complex combination of the two in which all modules are discovered, each describes its own layout requirements and requests (I need 50&#215;200 but want 250&#215;400) and then the host provides panels.)</p>
<p>In this case, what I hope to do is to build a fairly simple MEF proof-of-concept within the HVP shell, and then add more capabilities in upcoming <a href="http://silverlight.net/learn/tutorials/mini/1/" target="_blank">Mini-tutorials</a>,  that are successively of greater complexity and utility.</p>
<p>To begin, I’ll check-out and open the <a href="http://silverlighthvp.codeplex.com/SourceControl/ListDownloadableCommits.aspx" target="_blank">HVP Source Code</a> (for now, I’m using Subversion to manage the source. If you are interested in contributing the the project, please <a href="http://mailhide.recaptcha.net/d?k=01Y3WuNVO1PPhzr-CCT7uKPw==&amp;c=rv83MhupI40-7n-SZmsIdmdnzMR4sPwXtIn3sKJlpSQ=" target="_blank">contact me</a> and I’ll add you as a Developer). [See note at the bottom of this posting on the versions involved]</p>
<table border="2" cellspacing="0" cellpadding="5" width="400">
<tbody>
<tr>
<td width="400" valign="top">Side Note: I use captcha’ for <a href="http://mailhide.recaptcha.net/d?k=01Y3WuNVO1PPhzr-CCT7uKPw==&amp;c=rv83MhupI40-7n-SZmsIdmdnzMR4sPwXtIn3sKJlpSQ=" target="_blank">my email address</a> not to prevent spam, but rather to support the <a href="http://recaptcha.net/learnmore.html" target="_blank">Digitizing Books</a> effort.</td>
</tr>
</tbody>
</table>
<h3>Handling Complexity of Opportunity</h3>
<p>In MEF as in many of the technologies we’ll be using, there are often many ways to accomplish the same thing. My general approach will be:</p>
<ul>
<li>Start with whatever is simplest</li>
<li>Explore more complex options when they meet a need of the project or are so incredibly interesting I can’t resist the tangent</li>
</ul>
<p>Within this approach, I will typically explore simplified versions of any approach (stripped down, with minimal supporting infrastructure or error handling) until I <a href="http://en.wikipedia.org/wiki/Grok" target="_blank">grok</a> what is required, and then I’ll go back and make it work for the project. Specifically, I have sketched out this design using Expression Blend with Sketchview</p>
<p><a href="http://jesseliberty.com/wp-content/uploads/2010/05/SketchFlowMarkupofMEFArea.jpg"><img style="display: inline; border-width: 0px;" title="SketchFlowMarkup of MEF Area" src="http://jesseliberty.com/wp-content/uploads/2010/05/SketchFlowMarkupofMEFArea_thumb.jpg" border="0" alt="SketchFlowMarkup of MEF Area" width="644" height="483" /></a></p>
<p>The top row consists of the Table of Contents and the List of Links flanking the running video. The bottom row has four panels into which MEF can place visible objects.</p>
<p>In the first iteration, I’ll create a Part that might be added to the HVP; specifically a note taking area so that you can jot down notes when you are watching the video and then copy and paste them to another application later. So as not to get distracted by side issues, I’ll use the Rich Text Area control, but I won’t, at this point, get caught up in the details of supporting rich text.</p>
<p>While I will want to experiment with downloading the module on demand, and discovering where it wants to be (left, center or right), and quite a bit more, I like to start simple, hard-coding as much as I can to focus on the issue at hand: adding a new control to my existing application.</p>
<p>My first modification is to the Home Page where I’ll add three columns and two rows, and place a TabControl into the middle of the lower row. What follows is an excerpt showing the relevant declarations. (For complete source code, please see the bottom of this posting)</p>
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="border-style: none; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">controls:TabControl</span> <span style="color: #ff0000;">Name</span><span style="color: #0000ff;">="MefTabs"</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">                     <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">                     <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Row</span><span style="color: #0000ff;">="1"</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">                     <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="5"</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">                     <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Stretch"</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">                     <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Stretch"</span><span style="color: #0000ff;">&gt;</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">   <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">controls:TabItem</span> <span style="color: #ff0000;">Name</span><span style="color: #0000ff;">="tabItem1"</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">                     <span style="color: #ff0000;">Header</span><span style="color: #0000ff;">="Tab 1"</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">                     <span style="color: #ff0000;">FontFamily</span><span style="color: #0000ff;">="Georgia"</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">                     <span style="color: #ff0000;">FontSize</span><span style="color: #0000ff;">="12"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">   <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">controls:TabItem</span> <span style="color: #ff0000;">Name</span><span style="color: #0000ff;">="tabItem2"</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">                     <span style="color: #ff0000;">Header</span><span style="color: #0000ff;">="Tab 2"</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">                     <span style="color: #ff0000;">FontFamily</span><span style="color: #0000ff;">="Georgia"</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;">                     <span style="color: #ff0000;">FontSize</span><span style="color: #0000ff;">="12"</span> <span style="color: #0000ff;">/&gt;</span></pre>
<p><!--CRLF--></p>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">controls:TabControl</span><span style="color: #0000ff;">&gt;</span></pre>
<p><!--CRLF--></p>
</div>
</div>
<h1>Creating the Part</h1>
<p>We’ve specified that the new module will provide note-taking capability. We’ll start by creating a control to do just that, but let’s think ahead just a bit about what we’re going to tell the TabControl about what we’ll be adding to it.  We could create a NoteTaking object and then tell the TabControl that it will take a NoteTaking instance, but that would tightly couple the hosting container to the new module, a bad idea especially since we anticipate that there will be new modules created after we release the application.</p>
<p>What we want is to signal that we’ll be adding some sort of new part, but that the host does not need to know any of the details (which is a good thing,  because by the time the host is completed, the new part may not yet be conceived!)</p>
<h3>Terminology</h3>
<p>It is imperative we agree on certain common terms,  or confusion will quickly take the wheel and drive us off a rhetorical cliff.</p>
<p>In our example, SilverlightHVP is the <em>application</em> and the TabControls will host the new Parts.</p>
<p>We’ll define a Part as an object that can be added to our application using the Import/Export mechanism of MEF.</p>
<p>We will need to tell the TabControls the type of the Parts we’re adding. We can do that in any number of ways, but two are most common as they afford the most flexibility:</p>
<ul>
<li>Define the new Part to be a UserControl and tell the TabControls to expect UserControls but not what sub-type of UserControl.</li>
<li>Define an interface, (e.g., IPart), and have every Part implement that interface. Tell the TabControls to expect objects that implement the interface.</li>
</ul>
<p>We’ll choose the latter as I’m wary of deciding today that every part we will ever create or host will be a UserControl.</p>
<h1>NoteTaker</h1>
<p>Our new part, which will extend the HyperVideo Player, will be the note taking region described above, encapsulated within a new UserControl: <strong>NoteTaker</strong>.</p>
<p>In a future iteration we’ll define NoteTaker in a class library. For now, to keep this a bit easier on my brain, I’ll add a new project to the current solution, named SilverlightHVP_Extensions.</p>
<p>To do this, click on Add-&gt;New Item and select Silverlight Class Library; delete the class.cp that Visual Studio creates and add a new User Control named NoteTaker.xaml. Since I want this class to implement the IPart interface, I need to define that interface, and I will do so in yet another proejct. which following convention I will name SilverlightHVP_Contracts. That entire project consists of IPart.cs / IPart.vb</p>
<h3>C#</h3>
<pre class="brush: csharp;">namespace SilverlightHVP_Contracts
{
  public interface IPart
  {
    // marker interface
  }
}</pre>
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="border-style: none; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"><!--CRLF--><!--CRLF--><!--CRLF--><!--CRLF--><!--CRLF--><!--CRLF--><!--CRLF--><!--CRLF--></div>
</div>
<h3>VB.NET</h3>
<pre class="brush: vb;">Namespace SilverlightHVP_Contracts
  Public Interface IPart
    ' marker interface
  End Interface
End Namespace</pre>
<p>I can now return to to my NoteTaker class and define that it implements IPart. For the class to recognize the interface, it will need a reference to the <img style="margin: 10px 0px 10px 10px; display: inline; border-width: 0px;" title="Adding Project Reference" src="http://jesseliberty.com/wp-content/uploads/2010/05/AddingProjectReference_thumb.jpg" border="0" alt="Adding Project Reference" width="146" height="240" align="right" />SilverlightHVP_Contracts project. That allows me to write</p>
<p><span style="font-family: Consolas;">public partial class NoteTaker : UserControl, IPart</span></p>
<p>though IPart will still have a red underline as I’ve not added the Using statement. I can do so by hand, or I can click on IPart and enter ^. (control dot) which brings up a context menu offering to add the using statement or to modify the reference to IPart to include the namespace,</p>
<p><a href="http://jesseliberty.com/wp-content/uploads/2010/05/Using.jpg"><img style="margin: 10px 10px 10px 0px; display: inline; border-width: 0px;" title="Using" src="http://jesseliberty.com/wp-content/uploads/2010/05/Using_thumb.jpg" border="0" alt="Using" width="240" height="112" align="left" /></a></p>
<h3>Exporting NoteTaker</h3>
<p>The heart of MEF is that a Part can be marked for Export, allowing any consumer to Import it.</p>
<table border="2" cellspacing="0" cellpadding="5" width="400">
<tbody>
<tr>
<td width="400" valign="top">Of course, a Part can also Import another Part – for example, we might have the NoteTaker import a set of buttons that control rich text (e.g., Bold, Italics, and so forth).</td>
</tr>
</tbody>
</table>
<p>To mark the NoteTaker for Export, however, we need to add a reference to the required DLL:  System.ComponentModel.Composition   You’ll find that in  …Microsoft SDK’s –&gt; Silverlight –&gt; v4.0 –&gt; Libraries –&gt; Client as shown.</p>
<p>The code-behind file (NoteTaker.xaml.cs/vb) now looks like this:</p>
<h3>C#</h3>
<pre class="brush: csharp;">using System.Windows.Controls;
using SilverlightHVP_Contracts;
using System.ComponentModel.Composition;

namespace SilverlightHVP_Extensions
{
  [Export( typeof( IPart ) )]
  public partial class NoteTaker : UserControl, IPart
  {
    public NoteTaker()
    {
      InitializeComponent();
    }
  }
}</pre>
<h3>VB.NET</h3>
<pre class="brush: vb;">Imports System.Windows.Controls
Imports SilverlightHVP_Contracts
Imports System.ComponentModel.Composition

Namespace SilverlightHVP_Extensions
  &lt;EXPORT (GetType(IPart))&gt;
  Partial Public Class NoteTaker
      Inherits UserControl
      Implements IPart
    Public Sub New()
      InitializeComponent()
    End Sub
  End Class
End Namespace</pre>
<h3>Adding NoteTaker To The Application</h3>
<p>The challenge now is to add the NoteTaker to the application when the Application doesn’t know NoteTaker exists. You’ll remember, however, that we did agree that our TabControl would know that it will take <em>something </em>that implements IPart. That is all we need, we can ask it to bind to a collection of IPart objects, and then distribute the IParts appropriately.</p>
<p>In Home.xaml.cs be sure to add references to</p>
<ul>
<li>System.ComponentModel.Composition</li>
<li>System.ComponentModel.Composition.Initialization</li>
<li>SilverlightHVP_Contracts</li>
<li>SilverlightHVP_Extensions</li>
</ul>
<p>with these in place, and the three corresponding Using statements at the top of the file,</p>
<ul>
<li>using System.ComponentModel.Composition;</li>
<li>using System.Collections.Generic;</li>
<li>using SilverlightHVP_Contracts;</li>
</ul>
<p>You are ready to rock and roll.  There are two steps:</p>
<p>1. Tell your Home page that you will have a collection of… (what?)  The type we have designated is “objects that implement IPart”:</p>
<h3>C#</h3>
<pre class="brush: csharp;">[ImportMany]
public IEnumerable&lt;IPART&gt; parts { get; set; }
&lt;/IPART&gt;</pre>
<h3>VB.Net</h3>
<pre class="brush: vb;">Private privateparts As IEnumerable(Of IPart)
&lt;IMPORTMANY&gt;
Public Property parts() As IEnumerable(Of IPart)
 Get
    Return privateparts
 End Get
 Set(Byval value as IEnumerable(Of IPart))
    privateparts=value
 End Set</pre>
<p>While we happen to know there is only one, MEF allows for any number of IPart implementing extensions.</p>
<p>The ImportMany attribute signals that this host will import all the IPart objects it can find.</p>
<p>2. Signal that <em>now is the time to import</em> since you have a class that imports but does not export (Home).  You do that by calling</p>
<h3>C#</h3>
<p><span style="font-family: Conso;">PartsInitializer.SatisfyImports(this);</span></p>
<h3>VB.Net</h3>
<p>PartsInitializer.SatisfyImports(me)</p>
<table border="2" cellspacing="0" cellpadding="5" width="400">
<tbody>
<tr>
<td width="400" valign="top">It is this call that causes the Parts to be initialized, which you can see by putting a break point at the call to SatisfyImports. You’ll find that the parts collection is null before the call, and filled after. Further, if your IPart implementing class does work in its constructor, that constructor is only called when SatisfyImports is invoked.</td>
</tr>
</tbody>
</table>
<p>Once you have invoked PartsInitializer.SatisfyImports, the parts collection is populated, and we can iterate through it, obtaining each part in turn. In this first iteration, we just grab the part and assign it to the Content property of the first tab.</p>
<h3>C#</h3>
<pre class="brush: csharp;">PartInitializer.SatisfyImports( this );
foreach ( var part in parts )
{
  tabItem1.Content = part;
}</pre>
<h3>VB.Net</h3>
<pre class="brush: vb;">PartInitializer.SatisfyImports(Me)
For Each part In parts
  tabItem1.Content = part
Next part</pre>
<h3>Source Code</h3>
<p>The complete source code for the starting application is available at <a href="http://slhvp.com">http://slhvp.com</a> – click on Source Code. </p>
]]></content:encoded>
			<wfw:commentRss>http://jesseliberty.com/2010/05/08/mef-silverlight-and-the-hvp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Silverlight HVP on Silverlight TV</title>
		<link>http://jesseliberty.com/2010/04/01/silverlight-hvp-on-silverlight-tv/</link>
		<comments>http://jesseliberty.com/2010/04/01/silverlight-hvp-on-silverlight-tv/#comments</comments>
		<pubDate>Thu, 01 Apr 2010 21:09:23 +0000</pubDate>
		<dc:creator>Jesse Liberty</dc:creator>
				<category><![CDATA[HyperVideo Player]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[HVP]]></category>
		<category><![CDATA[Patterns]]></category>

		<guid isPermaLink="false">http://jesseliberty.com/2010/04/01/silverlight-hvp-on-silverlight-tv/</guid>
		<description><![CDATA[&#160; The Silverlight HyperVideo Project has made two guest appearances on Silverlight TV.&#160; In the first, I talk with John Papa about the project itself and how it has evolved. Then, during Mix, Tim Heuer and I sat down with &#8230; <a href="http://jesseliberty.com/2010/04/01/silverlight-hvp-on-silverlight-tv/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://channel9.msdn.com/shows/SilverlightTV/Silverlight-TV-16-Top-Features-in-Silverlight-4/"><img style="border-bottom: 0px; border-left: 0px; margin: 5px 20px 20px 0px; display: inline; border-top: 0px; border-right: 0px" title="JLSLTV2" border="0" alt="JLSLTV2" align="left" src="http://jesseliberty.com/wp-content/uploads/2010/04/JLSLTV21.jpg" width="244" height="153" /></a> </p>
<p>&#160;</p>
<p>The <a href="http://silverlight.net/getstarted/slhvp" target="_blank">Silverlight HyperVideo Project</a> has made two guest appearances on Silverlight TV.&#160; </p>
<p><a href="http://channel9.msdn.com/shows/SilverlightTV/Silverlight-TV-10-Jesse-Liberty-Explains-the-Hyper-Video-Project/" target="_blank">In the first</a>, I talk with John Papa about the project itself and how it has evolved.</p>
<p>Then, during Mix, <a href="http://timheuer.com">Tim Heuer</a> and I sat down with John to discuss <a href="http://channel9.msdn.com/shows/SilverlightTV/Silverlight-TV-16-Top-Features-in-Silverlight-4/">What’s New In Silverlight 4</a>, and I managed to sneak in a few comments about the HVP as well. </p>
<p>Silverlight TV has numerous great interviews, and is quickly becoming a valued asset throughout the Silverlight community.&#160; </p>
<p><a href="http://channel9.msdn.com/shows/SilverlightTV/"><img style="border-bottom: 0px; border-left: 0px; margin: 5px 15px 15px 0px; display: inline; border-top: 0px; border-right: 0px" title="SilverlightTV_100px" border="0" alt="SilverlightTV_100px" align="left" src="http://jesseliberty.com/wp-content/uploads/2010/04/SilverlightTV_100px.png" width="104" height="104" /></a></p>
<p>Tens of thousands of people view each episode. Check it out <a href="http://channel9.msdn.com/shows/SilverlightTV/">here</a>. </p>
<p>Then take a look at <a href="http://johnpapa.net/">John Papa’s site</a> as well. </p>
<p>Then come back here, because the last thing I want is for you to decide you like JP so much you stop visiting. Next thing you know, I’m sitting in the dark.</p>
<p><a href="http://jesseliberty.com/wp-content/uploads/2010/04/SilverlightTV_100px1.png">&#160;</a></p>
<div class="wlWriterHeaderFooter" style="margin:0px; padding:0px 0px 0px 0px;">This work is licensed under a <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons  license.</a></div>
]]></content:encoded>
			<wfw:commentRss>http://jesseliberty.com/2010/04/01/silverlight-hvp-on-silverlight-tv/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>When Is It OK To Hack?</title>
		<link>http://jesseliberty.com/2010/02/26/when-is-it-ok-to-hack-3/</link>
		<comments>http://jesseliberty.com/2010/02/26/when-is-it-ok-to-hack-3/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 15:23:00 +0000</pubDate>
		<dc:creator>Jesse Liberty</dc:creator>
				<category><![CDATA[Patterns & Skills]]></category>
		<category><![CDATA[Mini-Tutorial]]></category>
		<category><![CDATA[Patterns]]></category>

		<guid isPermaLink="false">http://jesseliberty.com/2010/03/29/when-is-it-ok-to-hack-3/</guid>
		<description><![CDATA[This mini-tutorial is part of the SLHVP documentation One of the goals of the Silverlight HyperVideo Project is to demonstrate best practices.  So when is it okay to throw in a quick hack to get things working? Case in point: &#8230; <a href="http://jesseliberty.com/2010/02/26/when-is-it-ok-to-hack-3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://jesseliberty.com/wp-content/uploads/2010/03/MiniTutorialLogo9.jpg"><img style="margin: 10px 0px; display: inline; border-width: 0px;" title="MiniTutorialLogo" src="http://jesseliberty.com/wp-content/uploads/2010/03/MiniTutorialLogo_thumb7.jpg" border="0" alt="MiniTutorialLogo" width="240" height="69" /></a></p>
<p><span style="font-size: xx-small;">This </span><a href="http://silverlight.net/learn/tutorials/mini/1/"><span style="font-size: xx-small;">mini-tutorial</span></a><span style="font-size: xx-small;"> is part of the </span><a href="http://slhvp.com/" target="_blank"><span style="font-size: xx-small;">SLHVP</span></a><span style="font-size: xx-small;"> documentation</span></p>
<p>One of the goals of the <a href="http://slhvp.com" target="_blank">Silverlight HyperVideo Project</a> is to demonstrate best practices.  So when is it okay to throw in a quick hack to get things working?</p>
<p><span id="more-817"></span></p>
<p><a href="http://jesseliberty.com/wp-content/uploads/2010/03/CutDownPlayer1.jpg"><img style="margin: 10px 15px 10px 0px; display: inline; border-width: 0px;" title="CutDownPlayer" src="http://jesseliberty.com/wp-content/uploads/2010/03/CutDownPlayer_thumb1.jpg" border="0" alt="CutDownPlayer" width="240" height="171" align="left" /></a>Case in point: as I approached the release this week for the latest alpha,  I noted that the player was not updating when the user clicked on a topic, though the links were appearing <em>as if</em> the player had been advanced.</p>
<p>To make the issue clear, in this image you see a cut down version of the player. Each item (video) has its own set of topics and links. The topics are shown as soon as the video starts, the links appear as the video plays.</p>
<p>If the user clicks on a topic (lower left) what should happen is that the video (middle) jumps to that topic and the scrubber  (below the video) should advance to indicate where in the video the topic begins, relative to the start of the video.</p>
<p><span style="font-size: xx-small;"><strong>(Click on image to see it full size)</strong></span></p>
<p>After a bit of debugging (and some frantic calls to the Vertigo folks who wrote the <a href="http://smf.codeplex.com/" target="_blank">Silverlight Media Framework</a>, we were able to see that the problem was in the binding:</p>
<pre class="brush: xml; highlight: [5];">&lt;SmoothPlayer:Player Style="{StaticResource SLHVPTemplate}"  x:Name="smoothPlayer"&gt;
    &lt;hvp:HVPCoreMediaElement x:Name="corePlayer"
    SmoothStreamingSource="{Binding URI, Mode=TwoWay}"
    AutoPlay="True"
    Position="{Binding Offset, Mode=TwoWay}" /&gt;
&lt;/SmoothPlayer:Player&gt;</pre>
<p>Checking the source code for the <a href="http://smf.codeplex.com" target="_blank">SMF</a> (available here) we found that Position is a dependency property and was not responding to the Binding as we expected.</p>
<p>Since the folks at Vertigo owned that code and were convinced they could fix this in the next release, I opted to take their change an copy it into my project. To encapsulate the hack, however, I created the HVPCoreMediaElement, derived from the CoreSmoothStreamingMediaElement.</p>
<h3>C#</h3>
<pre class="brush: csharp; highlight: [31,32];">using System;
using System.Windows;
using Microsoft.SilverlightMediaFramework.Player;

namespace SilverlightHVP.View
{
   public class HVPCoreMediaElement :
           CoreSmoothStreamingMediaElement
   {
      public TimeSpan PositionOverride
      {
         get { return ( TimeSpan ) GetValue( PositionOverrideProperty ); }
         set { SetValue( PositionOverrideProperty, value ); }
      }

      public static readonly DependencyProperty PositionOverrideProperty =
             DependencyProperty.Register(
                "PositionOverride",
                typeof( TimeSpan ),
                typeof( CoreSmoothStreamingMediaElement ),
             new PropertyMetadata( HVPCoreMediaElement.OnPositionOverridePropertyChanged ) );

      private static void OnPositionOverridePropertyChanged(
            DependencyObject d, DependencyPropertyChangedEventArgs e )
      {
         HVPCoreMediaElement source = d as HVPCoreMediaElement;
         source.OnPositionOverrideChanged();
      }

      private void OnPositionOverrideChanged()
      {
         // Hack!!, to databind to Position
         Position = PositionOverride;
      }
   }
}</pre>
<h3>VB.Net</h3>
<pre class="brush: vb;">Imports System
Imports System.Windows
Imports Microsoft.SilverlightMediaFramework.Player

Namespace SilverlightHVP.View
   Public Class HVPCoreMediaElement
       Inherits CoreSmoothStreamingMediaElement
      Public Property PositionOverride() As TimeSpan
         Get
             Return CType(GetValue(PositionOverrideProperty), TimeSpan)
         End Get
         Set(ByVal value As TimeSpan)
             SetValue(PositionOverrideProperty, value)
         End Set
      End Property

      Public Shared ReadOnly PositionOverrideProperty As DependencyProperty = DependencyProperty.Register("PositionOverride", GetType(TimeSpan), GetType(CoreSmoothStreamingMediaElement), New PropertyMetadata(AddressOf HVPCoreMediaElement.OnPositionOverridePropertyChanged))

      Private Shared Sub OnPositionOverridePropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
         Dim source As HVPCoreMediaElement = TryCast(d, HVPCoreMediaElement)
         source.OnPositionOverrideChanged()
      End Sub

      Private Sub OnPositionOverrideChanged()
         ' Hack!!, to databind to Position
         Position = PositionOverride
      End Sub
   End Class
End Namespace</pre>
<p>I could then modify the binding</p>
<pre class="brush: csharp; highlight: [4];">&lt;SmoothPlayer:Player Style="{StaticResource SLHVPTemplate}"  x:Name="smoothPlayer"     &gt;
    &lt;hvp:HVPCoreMediaElement x:Name="corePlayer"
    SmoothStreamingSource="{Binding URI, Mode=TwoWay}" AutoPlay="True"
    PositionOverride="{Binding Offset, Mode=TwoWay}"
&lt;/SmoothPlayer:Player&gt;</pre>
<p>And all was right with the world.   This was minimally intrusive, and I was very pleased with it.  I should have known.</p>
<h3>In For A Penny…</h3>
<p>The problem, of course, is that now that I’m binding the new PositionOverride I’m reading wonderfully, but writing, not so.  There are a lot of ways to fix this, but the easiest, fastest and perhaps ugliest is to add a second binding. After all, binding to Position was working great for setting, and PositionOverride is now working great for reading.</p>
<pre class="brush: csharp; highlight: [4,5];">&lt;SmoothPlayer:Player Style="{StaticResource SLHVPTemplate}"  x:Name="smoothPlayer"     &gt;
    &lt;hvp:HVPCoreMediaElement x:Name="corePlayer"
    SmoothStreamingSource="{Binding URI, Mode=TwoWay}" AutoPlay="True"
    PositionOverride="{Binding Offset}"
    Position="{Binding PlayerPosition, Mode=TwoWay}" /&gt;
&lt;/SmoothPlayer:Player&gt;</pre>
<p>If this were the only change, maybe okay, but unfortunately we have to hack the VM as well,</p>
<h3>C#</h3>
<pre class="brush: csharp;">public TimeSpan Offset {  get { return state.Position; } }

public TimeSpan PlayerPosition
{
   get { return state.Position; }

   set
   {
      if ( value &gt; previousPosition + Interval )
      {
         previousPosition = value;
         state.Position = value;
      }
   }
}</pre>
<h3>VB.Net</h3>
<pre class="brush: vb;">Public ReadOnly Property Offset() As TimeSpan
    Get
        Return state.Position
    End Get
End Property

Public Property PlayerPosition() As TimeSpan
   Get
       Return state.Position
   End Get

   Set(ByVal value As TimeSpan)
      If value &gt; previousPosition + Interval Then
         previousPosition = value
         state.Position = value
      End If
   End Set
End Property</pre>
<h3>Oh What A Tangled Web We Weave…</h3>
<p>This is so ugly, and so likely to end up being a headache when we are ready to undo it, that I’m very tempted to find a cleaner solution. On the other hand, I know that we’re actively working on <a href="http://smf.codeplex.com" target="_blank">SMF</a> version 2, and that even before that I may have an interim release that makes the whole problem go away, so my Faustian bargain is to comment the hack</p>
<pre class="brush: csharp; highlight: [1,2,3,4,5,6,7,8,9];">/*   HACK!! We are binding the getter of Offset to the Position of the CoreSmoothStreamingMediaElement
     but we are binding the setter to the PositionOverride property of the (temporary) class HVPCoreMediaElement that
     derives from CoreSmoothStreamingMediaElement.  Also note that this is two way binding and we need both the getter
     and the setter.
     To Fix:
        1. Combine move get and set from PlayerPosition to Offset and remove PlayerPosition
        2. Change Binding in SmoothStreamingPlayer to bind to Offset, two way
        3. Remove file (and class) HVPCoreMediaElement.cs
*/

 public TimeSpan Offset {  get { return state.Position; } }

 public TimeSpan PlayerPosition
 {
    get { return state.Position; }

    set
    {
       if ( value &gt; previousPosition + Interval )
       {
          previousPosition = value;
          state.Position = value;
       }
    }
 }</pre>
<h3>VB.NET</h3>
<pre class="brush: vb;">'HACK!! We are binding the getter of Offset to the
'Position of the CoreSmoothStreamingMediaElement
'but we are binding the setter to the PositionOverride
'property of the (temporary) class HVPCoreMediaElement
'that derives from CoreSmoothStreamingMediaElement.
'Also note that this is two way binding and we
'need both the getter and the setter.
'To Fix:
'1. Combine move get and set from PlayerPosition to
'   Offset and remove PlayerPosition
'2. Change Binding in SmoothStreamingPlayer to bind to
'   Offset, two way
'3. Remove file (and class) HVPCoreMediaElement.vb

 Public ReadOnly Property Offset() As TimeSpan
     Get
         Return state.Position
     End Get
 End Property

 Public Property PlayerPosition() As TimeSpan
    Get
        Return state.Position
    End Get

    Set(ByVal value As TimeSpan)
       If value &gt; previousPosition + Interval Then
          previousPosition = value
          state.Position = value
       End If
    End Set
 End Property</pre>
<h3>Let the Flame Wars Begin</h3>
<p><strong><em>“Well?,”</em> as <a href="http://en.wikipedia.org/wiki/Howie_Mandel" target="_blank">Howie Mandel’s</a> tiny alter-ego <a href="http://www.bobbysworld.net/" target="_blank">Bobby</a> asks<em>, “what would you say?”</em></strong> </p>
]]></content:encoded>
			<wfw:commentRss>http://jesseliberty.com/2010/02/26/when-is-it-ok-to-hack-3/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Test Driven Silverlight Body Snatchers</title>
		<link>http://jesseliberty.com/2010/02/05/test-driven-silverlight-body-snatchers/</link>
		<comments>http://jesseliberty.com/2010/02/05/test-driven-silverlight-body-snatchers/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 03:18:41 +0000</pubDate>
		<dc:creator>Jesse Liberty</dc:creator>
				<category><![CDATA[Mini-Tutorial]]></category>
		<category><![CDATA[Patterns & Skills]]></category>
		<category><![CDATA[BestPractices]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Xaml]]></category>

		<guid isPermaLink="false">http://jesseliberty.com/2010/03/24/test-driven-silverlight-body-snatchers/</guid>
		<description><![CDATA[This posting is part of the Silverlight HyperVideo Platform documentation and a Silverlight Mini-tutorial. The information in this posting, however, should be of interest to anyone writing meaningful Line of Business applications with Silverlight. The premise of the classic 1956 &#8230; <a href="http://jesseliberty.com/2010/02/05/test-driven-silverlight-body-snatchers/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://Silverlight.net/learn"><img style="margin: 10px 0px; display: inline; border-width: 0px;" title="MiniTutorialLogo" src="http://jesseliberty.com/wp-content/uploads/2010/03/MiniTutorialLogo7.jpg" border="0" alt="MiniTutorialLogo" width="240" height="69" /></a></p>
<p><a href="http://blogs.silverlight.net/blogs/jesseliberty/SLHvpLogoNoBorder_38581AA8.jpg"><img style="margin: 10px 20px 10px 0px; display: inline; border-width: 0px;" title="SLHvpLogoNoBorder" src="http://blogs.silverlight.net/blogs/jesseliberty/SLHvpLogoNoBorder_thumb_0CA750AC.jpg" border="0" alt="SLHvpLogoNoBorder" width="207" height="240" align="left" /></a>This posting is part of the <a href="http://slhvp.com/" target="_blank">Silverlight HyperVideo Platform</a> documentation and a <a href="http://silverlight.net/learn/tutorials/mini/1/" target="_blank">Silverlight Mini-tutorial</a>. The information in this posting, however, should be of interest to anyone writing meaningful Line of Business applications with Silverlight.</p>
<p><strong>The premise of the classic 1956 film <em>Invasion of the Body Snatchers</em></strong> is that there are “pod people” among us, who are converting “normal” people into pod people one by one.</p>
<h3>“Once you are a pod person, you think everyone should be one”</h3>
<p>Once you begin seeing the benefits of TDD you tend to evangelize; its working great for you and you want everyone to become one.  This can be helpful, annoying or alarming depending on who you’re talking to.  My daughters, for example, are quite sick of hearing about it.</p>
<p><span id="more-177"></span></p>
<h3>&#8220;They&#8217;re here already! You&#8217;re next! You&#8217;re next!&#8221;</h3>
<p>It seems reasonable to many developers to create unit tests for their code; but the presumed high cost of doing so implies for waiting for a project that is not in “crunch mode.”  Most developers will be waiting a long, long, long time.</p>
<p>Experience indicates that TDD actually <em>saves time</em> – you spend less time debugging and more time coding. Unfortunately, that sounds like “a good theory” and we all know that <em>In theory, theory and practice are the same,<br />
But in practice, they never are. </em></p>
<p>The bigger problem is Isaac Newton. Most of us suffer from Newton’s first law (significant inertia) and when confronted with an evangelist, we are governed by his third law (the more you push, the more I push back.)</p>
<h3>“Give Up! You Can’t Get Away From Us! We’re Not Going To Hurt You!”</h3>
<p>That said, for the past few years I’ve had the nagging sense that I was missing something important.  Especially given that some of the folks I respect most in the industry were strong proponents; not least my mentors in all things good:  RMSquaredF: Robert (Uncle Bob) Martin and Martin Fowler who laid the ground work and established best practices in their seminal works <a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672%3FSubscriptionId%3D0JTCV5ZMHMF7ZYTXGFR2%26tag%3Dlibertyassocia00A%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201485672">Refactoring: Improving the Design of Existing Code</a> (Fowler) and <a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882%3FSubscriptionId%3D0JTCV5ZMHMF7ZYTXGFR2%26tag%3Dlibertyassocia00A%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0132350882">Clean Code: A Handbook of Agile Software Craftsmanship</a> (Martin).  In the latter book, Robert Martin summarizes his approach which I paraphrase here:</p>
<blockquote>
<ol>
<li>Don’t write production code until you’ve written a failing unit test</li>
<li>Write just enough of a test to fail.</li>
<li>Write just enough code to pass the test<strong> </strong></li>
</ol>
<p><strong>What you are aiming for is about a 30 second cycle of write-test, write-code, Run-test.</strong></p></blockquote>
<p>Uncle Bob’s premise is that you tremendously reduce your risk and thus your fear because your production code never gets ahead of what you know; and you know it because you’ve tested for it.</p>
<h3>“I Don’t Want Any Part Of It.”<br />
<em>“But You’re Forgetting Something….. You Have No Choice.”</em></h3>
<p><a href="http://en.wikipedia.org/wiki/Invasion_of_the_Body_Snatchers"><img class="alignleft" style="margin: 20px; display: inline;" src="http://upload.wikimedia.org/wikipedia/en/2/22/Invasion_of_the_body_snatchers.jpg" alt="Invasion poster" width="240" height="189" align="left" /></a> A second premise of folks who evangelize TDD is that you really have no choice; it is a case of “pay me now, or pay me later.” Either you create the unit tests or you spend that much time and a good deal more on debugging.</p>
<p>The <a href="http://slhvp.com/" target="_blank">Silverlight HyperVideo Platform</a> project offered the ideal opportunity to take on TDD, and the only way to do so was by Fiat. Thus, I made the executive decision to require unit tests for all code checked into the project (not hard to enforce so far, as at the moment all the code in the project is mine).</p>
<h3>“The words, the gesture, the tone of voice, everything else is the same, but not the feeling.”</h3>
<p>The rules for writing good tests are very similar to writing good code, but with a couple extra requirements.  Stealing again from Robert Martin, here is a paraphrase of the good-test rules developed at his company, <a href="http://Objectmentor.com/" target="_blank">Object Mentor</a>:</p>
<ul>
<li>Test must be <strong>quick</strong>. The slower a test runs the less likely you are to run it.</li>
<li>Tests must be <strong>independent</strong> of one another; any side effects or dependencies must be avoided</li>
<li>Tests must be <strong>repeatable</strong>: running the same test against the same code base must give the same results</li>
<li>Tests must return <strong>unambiguous </strong>results</li>
<li>Tests must be <strong>isolated</strong> from the production code</li>
</ul>
<h1>Configuration – ViewModel Objects</h1>
<p>I published a plan for configuration that made use of Xaml files. I realized yesterday, in one of those forehead slapping moments, that a design that relies on placing configuration files on the client of course will not work due to access limitations.  No harm done: the Xaml files were just a mechanism for creating the configuration business objects; and there are natural server-side analogs.</p>
<table border="3" cellspacing="2" cellpadding="4" width="400">
<tbody>
<tr>
<td width="400" valign="top">We’ll use the Xaml file approach for enabling the user to maintain the state of the program when suspended or shut down (using local storage), post V1.</td>
</tr>
</tbody>
</table>
<p>The working design now looks like this (using a relational database for persisting the configuration information, and WCF-RIA Services for moving the objects to the client. (A forthcoming blog entry will walk through that aspect of the implementation in detail)</p>
<p><a href="http://blogs.silverlight.net/blogs/jesseliberty/slhvpDBTables_2536EDFC.jpg"><img class="alignleft" style="border: 0pt none; margin: 20px; display: inline;" title="slhvpDBTables" src="http://blogs.silverlight.net/blogs/jesseliberty/slhvpDBTables_thumb_04AFAE4A.jpg" border="0" alt="slhvpDBTables" width="240" height="250" /></a></p>
<h3><span style="font-size: xx-small;">(Click on image for full size) </span></h3>
<h3>Links Vs Units</h3>
<p>Links are a unique identification of a Unit, and Units are not represented by a class. A Unit is a set of Items (and the selected item), each item’s set of topics (and the selected topic) and each item’s set of links (and which links are currently displayed).  Notice that units are identified by a URL.  In V1 the selected item and selected topic are the first in the set, and this design is used only for configuration.</p>
<p>After v1, we’ll move from read-only to read-write, allowing the user to persist the current unit and to recreate the state of the application at a later time.</p>
<h3>From Tables To Objects</h3>
<p>The diagram above was created to show how the RDB would work, but it is a bit misleading.  What we really want is not tables but rather objects.  There is a very small jump (in this case) from the tables to the business objects as shown here:</p>
<h3><a href="http://blogs.silverlight.net/blogs/jesseliberty/TDDObjects_0AF684D8.jpg"><img class="alignleft" style="border: 0pt none; margin: 20px; display: inline;" title="TDDObjects" src="http://blogs.silverlight.net/blogs/jesseliberty/TDDObjects_thumb_635008AD.jpg" border="0" alt="TDDObjects" width="240" height="235" /></a><br />
<span style="font-size: xx-small;">(Click on image for full size)</span></h3>
<p>There are a number of advantages to creating these objects, the most significant of which is that I can go ahead and implement the configuration without regard to how these objects were created, providing two implicit benefits:</p>
<ul>
<li>I don’t have to get all the <a href="http://silverlight.net/getstarted/riaservices/" target="_blank">WCF Ria Services</a> code working before I can make configuration work and…</li>
<li>The design now allows me to substitute virtually any persistence mechanism (database, Xaml configuration files, etc.) to back these business objects.</li>
</ul>
<p>Further, these objects are part of the ViewModel, and facilitate binding the View to the ViewModel (as discussed in my mini-tutorial on MVVM).</p>
<h1>Implementation</h1>
<p>We’re now (finally) ready to implement this, and as an experiment in open, honest and direct explanation I’m going to do this in real time, documenting my experience of creating the Unit Tests and the classes and their methods <em>as I do it</em>.</p>
<p>One of the contributors to the <a href="http://slhvp.com/" target="_blank">slhvp</a> project, Abby Fichtner (aka <a href="http://theHackerChickBlog.com" target="_blank">Hacker Chick</a>) said to me just last night,</p>
<blockquote><p><strong>The great advantage of testing <em>first</em> is that it forces you to think about what the ideal API would be to each of your classes.</strong></p></blockquote>
<p><em>Exactically. </em></p>
<h3>The Configuration Objects</h3>
<p>The first implementation issue is this:  I already have the following objects in the project:</p>
<p>It isn’t clear if the existing Item, Link and Topic (location) classes can be used for configuration, and I have a nagging feeling that I want something more. But here is where Agile development comes to the rescue: <em>Design for what you need right now</em>.</p>
<h3>Next up, A Real Time Walkthrough of Test-Driven Development….</h3>
<div class="wlWriterHeaderFooter" style="margin: 0px; padding: 0px 0px 0px 0px;">This work is licensed under a <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons license.</a></div>
]]></content:encoded>
			<wfw:commentRss>http://jesseliberty.com/2010/02/05/test-driven-silverlight-body-snatchers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rapidly Evolving Design</title>
		<link>http://jesseliberty.com/2010/01/05/rapidly-evolving-design-2/</link>
		<comments>http://jesseliberty.com/2010/01/05/rapidly-evolving-design-2/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 21:58:00 +0000</pubDate>
		<dc:creator>Jesse Liberty</dc:creator>
				<category><![CDATA[HyperVideo Player]]></category>
		<category><![CDATA[Patterns & Skills]]></category>
		<category><![CDATA[BestPractices]]></category>
		<category><![CDATA[Patterns]]></category>

		<guid isPermaLink="false">http://jesseliberty.com/2010/01/05/rapidly-evolving-design-2/</guid>
		<description><![CDATA[The problem with using a blog to track a rapidly evolving design, is that blogs don’t make for very fluid documents; the unwritten rule is that once posted, you ought not go back and substantially alter a post. Matching Blog &#8230; <a href="http://jesseliberty.com/2010/01/05/rapidly-evolving-design-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://jesseliberty.com/wp-content/uploads/2010/04/SLHvpLogo.jpg"><img style="border-right-width: 0px; margin: 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="SLHvpLogo" border="0" alt="SLHvpLogo" src="http://jesseliberty.com/wp-content/uploads/2010/04/SLHvpLogo_thumb.jpg" width="217" height="240" /></a> </p>
<p>The problem with using a blog to track a rapidly evolving design, is that blogs don’t make for very fluid documents; the unwritten rule is that once posted, you ought not go back and substantially alter a post.</p>
<h3>Matching Blog Posts to Discussions</h3>
<p>I do want to use these postings to keep everyone up to date on the evolution and lessons being learned in the <a href="http://slhvp.com/" target="_blank">SLHVP</a> project, but we also need a way to consolidate the discussion and the evolving understanding, and so each blog post will refer to a <a href="http://silverlighthvp.codeplex.com/Thread/List.aspx" target="_blank">specific discussion</a> on <a href="http://codeplex.com" target="_blank">CodePlex</a> where the ideas will be discussed and will evolve. I’ll then post a roll up of changes periodically, but not in response to each posting. The most recent post is being discussed here, where I have recognized that I violated my own design principles and backed away from two lines in the previous blog post. Here is what I wrote:</p>
<p>&#160;</p>
<blockquote><p>Your questions reveal that I have violated my own design principles: &quot;Do not let the design get ahead of what you know&quot; &#8212; The right answer is, of course, to design only for what we know we need, and keep the design open enough to extend as new needs emerge. To answer your questions specifically:</p>
<p>…What I meant was that we know that videos will want to signal a marker has been encountered, and I can imagine that other frame components might want to signal that something has happened that is equivalent (you&#8217;ve reached the 4th level of play in this game)&#8230; then I went off the track and speculated that this should be handled by the Frame. But that is absurd.&#160; The Frame <em>might</em> be the place to handle this, but I can easily imagine that there is a base class or interface that the video and game support or that there is a separate class they both associate with, etc. etc.&#160; So let&#8217;s just strike that statement (which I will do by editing my message and referring to this discussion.</p>
<p>2. [Each module will have its own xml config file] Here is where I really went over the edge. I totally retract this statement. <em>Maybe</em> it makes sense for each module to have its own configuration file, but we&#8217;ll only know that once we have modules and we&#8217;ve worked with a single integrated configuration file (the manifest you have working). So let&#8217;s please stay with the manifest until it is manifestly not working <img src='http://jesseliberty.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
</blockquote>
<p>Please do join us in the ongoing discussion. Feel free to leave comments here about the form of the post, but substantive comments about the project will be seen by the most people, and those most involved, in the ongoing <a href="http://silverlighthvp.codeplex.com/Thread/List.aspx" target="_blank">Discussions</a>. </p>
<p>Thanks</p>
<p>&#160;</p>
<p><a href="http://jesseliberty.com/wp-content/uploads/2010/04/jessesig.jpg"><img style="border-right-width: 0px; margin: 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="jessesig" border="0" alt="jessesig" src="http://jesseliberty.com/wp-content/uploads/2010/04/jessesig_thumb.jpg" width="125" height="57" /></a></p>
<div class="wlWriterHeaderFooter" style="margin:0px; padding:0px 0px 0px 0px;">This work is licensed under a <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons  license.</a></div>
]]></content:encoded>
			<wfw:commentRss>http://jesseliberty.com/2010/01/05/rapidly-evolving-design-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

