<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3761674922653685009</id><updated>2012-01-15T20:05:15.363-08:00</updated><category term='LINQ'/><category term='macro'/><category term='metaprogramming'/><category term='Enterprise Library 3'/><category term='Silverlight Toolkit'/><category term='web'/><category term='DSL'/><category term='Validation'/><category term='PLINQ'/><category term='functional programming'/><title type='text'>unfold</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>59</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-7617264165102856968</id><published>2011-04-13T10:24:00.001-07:00</published><updated>2011-04-13T10:24:05.449-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight Toolkit'/><title type='text'>Impressions of MIX 2011</title><content type='html'>&lt;p&gt;Bing sent me to MIX as an attendee this year and so far it has been a blast.&amp;#160; It’s great to be able to listen to customer concerns and take the temperature of a technology by checking out how many people show up to a talk.&amp;#160; Most of all it’s fun to talk to the people who own the technologies I care about (especially the developers).&amp;#160; It’s also nice to occasionally get props for my contributions to Silverlight even though I’ve since left the team. &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh3.ggpht.com/_HI1qT6wpc4w/TaXcMxsq0vI/AAAAAAAAATY/A3WJsdxVm_g/wlEmoticon-smile2.png?imgmax=800" /&gt;&lt;/p&gt;  &lt;p&gt;The feedback from customers continues to be concern about the future of Silverlight and all I can do is reference the blog post &lt;a href="http://team.silverlight.net/announcement/standards-based-web-plug-ins-and-silverlight/"&gt;“Standards-based web, plugins, and Silverlight.”&lt;/a&gt;&amp;#160; It also appears that many developers are somewhat wary of exploring HTML5.&amp;#160; It’s my feeling they might be more enthusiastic if the toolset were comparable to what Microsoft currently offers to Silverlight developers.&amp;#160; In a perfect world the release of IE9 would be accompanied by a Javascript unit testing framework built into Visual Studio, comprehensive Blend support for HTML5, SVG, and jQuery templates, a Visual Studio update providing ES5 intellisense support, a jQuery plug-in for data-binding, and support for writing server-side code using the IE9 Javascript engine.&amp;#160; Instead web developers got yet another templating engine for ASP.NET MVC (&lt;a href="http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx"&gt;Razor&lt;/a&gt;) which - although very nice – doesn’t really solve any new problems.&lt;/p&gt;  &lt;p&gt;One of the key reasons our developers are so loyal is that we provide them with such excellent tooling for our platforms.&amp;#160; IE9 has some great debugging and diagnostic tools but that’s not enough.&amp;#160; Developers need development tools and libraries that will fill the gaps they’ll encounter when they leave the warm embrace of the CLR and enter the realm of the browser.&amp;#160; The Javascript version of &lt;a href="http://msdn.microsoft.com/en-us/devlabs/ee794896"&gt;Reactive Extensions&lt;/a&gt; is a good start.&lt;/p&gt;  &lt;p&gt;I know the transition from Silverlight to HTML5 can be painful as I made the switch myself when I joined the Bing team.&amp;#160; The good news - and it’s something I think we can do a better job of emphasizing - is that by cobbling together frameworks like jQuery, jQuery templates, and Knockout.js it’s possible to follow a development model similar to Silverlight and consequently achieve similar levels of productivity.&amp;#160; &lt;/p&gt;  &lt;p&gt;Looking forward to tomorrow’s talks!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-7617264165102856968?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/7617264165102856968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=7617264165102856968' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/7617264165102856968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/7617264165102856968'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2011/04/impressions-of-mix-2011.html' title='Impressions of MIX 2011'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_HI1qT6wpc4w/TaXcMxsq0vI/AAAAAAAAATY/A3WJsdxVm_g/s72-c/wlEmoticon-smile2.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-5417341334943239489</id><published>2010-05-27T17:43:00.001-07:00</published><updated>2010-05-27T17:43:42.713-07:00</updated><title type='text'>Crockford on Javascript</title><content type='html'>&lt;p&gt;The web would be a better place if everyone watched “&lt;a href="http://yuiblog.com/crockford/"&gt;Douglas Crockford on Javascript&lt;/a&gt;”, a highly entertaining and informative series of lectures on the state of Javascript and the web.&amp;#160; With wit and refreshing candor he catalogs what is right and wrong with Javascript and provides the historical context to help viewers understand (where possible) how we got here.&amp;#160; You’ll almost certainly want to buy his book &lt;a href="http://oreilly.com/catalog/9780596517748"&gt;“Javascript: The Good Parts.”&lt;/a&gt;&amp;#160; The title alone is a nice taste of Crockford’s plain-spoken style. :-)&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-5417341334943239489?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/5417341334943239489/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=5417341334943239489' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/5417341334943239489'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/5417341334943239489'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2010/05/crockford-on-javascript.html' title='Crockford on Javascript'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-66340150163071355</id><published>2010-04-04T13:10:00.001-07:00</published><updated>2010-04-04T13:18:31.797-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight Toolkit'/><title type='text'>I’ve left the Silverlight team</title><content type='html'>&lt;p&gt;I recently left the Silverlight team.&amp;#160; Silverlight is a great team to work for and I have tremendous confidence in the continued success of the product.&amp;#160; However at this point in my career platform development doesn’t appeal to me very much. I’d rather be much higher up in the stack working on user-facing technology.&amp;#160; To that end I’ve joined a research team that’s developing semantic web technology for Bing (among other things).&lt;/p&gt;  &lt;p&gt;Unfortunately this will mean that I won’t be able to blog as much about what I’m doing because most of my work will be under NDA.&amp;#160; I can say that it is very exciting though!&amp;#160; If there’s one thing Microsoft does better than anyone it’s funding and productizing research (although there’s still room for improvement).&lt;/p&gt;  &lt;p&gt;Working for the Silverlight team has been a real thrill.&amp;#160; It was great to be able to fight for and contribute features to the platform that I cared about. I’m proud to have been a part of Silverlight 4 and I can’t wait to use it on my new team.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-66340150163071355?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/66340150163071355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=66340150163071355' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/66340150163071355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/66340150163071355'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2010/04/ive-left-silverlight-team.html' title='I’ve left the Silverlight team'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-6919402431797803753</id><published>2010-04-02T01:11:00.001-07:00</published><updated>2010-04-02T01:11:50.806-07:00</updated><title type='text'>A Modest Proposal: Pretty XSL</title><content type='html'>&lt;p&gt;I’ve got a question for the authors of the popular MVC frameworks: &lt;strong&gt;What’s with all the custom view languages?&lt;/strong&gt;&amp;#160; ASP.NET MVC uses ASPX files for their views.&amp;#160; Rails uses Ruby of course.&amp;#160; MonoRail has its own &lt;a href="http://www.castleproject.org/viewengines/nvelocity/variables.html"&gt;NVelocityViewEngine &lt;/a&gt;which has a python-like syntax.&amp;#160; Of course these frameworks allow you swap out these view engines.&amp;#160; However in my experience developers tend to default to using the one that ships with the framework.&lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;Why not use XSL?&lt;/strong&gt;&amp;#160; &lt;/h3&gt;  &lt;p&gt;The technical benefits of using XSL are compelling:&lt;/p&gt;  &lt;p&gt;1. Use Less Bandwidth&lt;/p&gt;  &lt;p&gt;Every major browser is capable of XSL transformations on the client.&amp;#160; After the XSL and CSS files have been cached by the browser an application server becomes responsible only for sending data and managing any application state.&amp;#160; This translates to massive bandwidth savings.&lt;/p&gt;  &lt;p&gt;2. Enforce Model/View Separation&lt;/p&gt;  &lt;p&gt;When it comes to view languages smarter is &lt;u&gt;not&lt;/u&gt; better.&amp;#160; The more powerful a view language, the easier it is to inadvertently blend concerns.&amp;#160; XSL is a dumb language that is pure by design.&amp;#160; It’s like a technical straightjacket, sending a clear message to current and future developers about exactly what type of tasks are allowed to be performed.&lt;/p&gt;  &lt;p&gt;3. W3C Standard&lt;/p&gt;  &lt;p&gt;‘Nuff said.&lt;/p&gt;  &lt;p&gt;4. Great tooling.&lt;/p&gt;  &lt;p&gt;Some .NET developers may be unaware that it’s possible to step through XSL transformations in Visual Studio.&amp;#160; The experience is roughly on par with stepping through C# code in an ASPX.&lt;/p&gt;  &lt;h3&gt;Syntax Matters&lt;/h3&gt;  &lt;p&gt;Given all these benefits why do so many developers choose a different view language?&amp;#160; Here’s my theory: XSLT is ugly&lt;strong&gt;.&lt;/strong&gt;&amp;#160; Anyone who has used XSL knows that its signal-to-noise ratio is abysmal.&amp;#160; Therefore propose a solution: &lt;strong&gt;The W3C should create PXSL&lt;/strong&gt; (“Pretty Extensible Stylesheet Language”).&amp;#160; PXSL is a hypothetical non-XML language that compiles into XSL.&amp;#160; A stripped down version of Windsor’s &lt;a href="http://www.castleproject.org/monorail/documentation/V20/viewengines/nvelocity/index.html"&gt;NVelocityEngine&lt;/a&gt; or something similar could easily be compiled into XSL.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:7e04f2ba-dd75-4fc0-947a-788af15ba0b7" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;#&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt;($person &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; $people)
#beforeall
       &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;table&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
               &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;tr&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
               &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;th&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Name&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;th&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
               &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;th&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Age&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;th&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
               &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;tr&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
#before
                  &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;tr
#odd
                       Style&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;color:gray&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
#even
                       Style&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;color:white&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;

#each
                       &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;td&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;$person.Name&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;td&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                       &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;td&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;$person.Age&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;td&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;

#after
                  &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;tr&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;

#between
                  &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;tr&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;td colspan&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;2&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;$person.bio&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;td&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;tr&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
#afterall
       &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;table&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
#nodata
       Sorry No Person Found
#end&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Some might think such an endeavor trivial or misguided.&amp;#160; I disagree.&amp;#160; There’s a relevant precedent to consider here.&amp;#160; &lt;a href="http://www.w3.org/TeamSubmission/turtle/"&gt;Turtle&lt;/a&gt; (Terse RDF Triple Language) is a non-XML language for describing XML RDF graphs that has been submitted to the W3C.&amp;#160; Although it hasn’t yet been accepted as a standard it enjoys great tooling support and is widely used.&amp;#160; Although it is no more or less expressive than RDF it’s practical syntax is so compelling that it has found a foothold in the industry.&lt;/p&gt;

&lt;h3&gt;Use XML Where it Makes Sense&lt;/h3&gt;

&lt;p&gt;Whenever a new technology is introduced we hear a lot about its supposed benefits.&amp;#160; Some of these benefits pan out and some don’t.&amp;#160; One of the touted benefits of XML was that it was supposed to be human-readable.&amp;#160;&amp;#160; While definitely an improvement on binary, many XML formats (ex. SOAP) are so complex that sifting through them in a text editor is very difficult in practice.&amp;#160; To increase productivity we are increasingly hiding XML from developers with designers, code generators, and configuration utilities. XML is a very mature data interchange language but there’s no reason to force developers to work with it directly.&amp;#160; A little syntax goes a long way.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-6919402431797803753?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/6919402431797803753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=6919402431797803753' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/6919402431797803753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/6919402431797803753'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2010/04/modest-proposal-pretty-xsl.html' title='A Modest Proposal: Pretty XSL'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-5269646029803308755</id><published>2010-03-03T08:12:00.001-08:00</published><updated>2010-03-14T05:04:14.397-07:00</updated><title type='text'>Why We Still Rely on Dynamic Casts</title><content type='html'>&lt;p&gt;*I recently updated this post as it was rather unclear.&amp;#160; By instance members I meant fields and properties, but it was pointed out that MTC was already supported on instance methods which are of course instance members.&lt;/p&gt;  &lt;p&gt;The year is 2010.&amp;#160; I program in C#, a modern and (ostensibly) strongly-typed programming language with generics.&amp;#160; So why do I find it so difficult to write a program that doesn’t rely on dynamic casts?&lt;/p&gt;  &lt;p&gt;Conventional wisdom is that reliance on dynamic casting is usually the sign of a poorly-designed framework.&amp;#160; While this is true very often the root cause of suboptimal framework design is the inability of the programming language to express certain concepts.&amp;#160; Its my aim to show you that with a simple programming language feature we can largely free our programs of dynamic casts.&amp;#160; In the process I also intend to challenge conventional notions about good interface design.&lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;Why We Need Dynamic Casts: A Typical Example&lt;/strong&gt;&lt;/h3&gt;  &lt;p&gt;Let’s take a look at a class that must rely on dynamic casts to do its job.&lt;/p&gt;  &lt;p&gt;   &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:e7b900d8-cf96-4ab3-8be9-77a6676a7f59" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; CollectionSynchronizer&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; ICollection&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; SourceCollection { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }     
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; ICollection&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; TargetCollection { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
    
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Implementation omitted&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;This CollectionSynchronizer listens to changes in a source collection and synchronizes its contents with a target collection.&amp;#160; Over the classes lifetime its SourceCollection property might be set to a variety of different concrete collection classes that implement ICollection and INotifyCollectionChanged.&amp;#160; The CollectionSynchronizer class has to rely on a dynamic cast because it must cast its source collection from an ICollection to an INotifyCollectionChanged interface in order to detect any changes to it.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:cfc9a774-5db4-434d-a377-62f348b2843f" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; CollectionSynchronizer&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; ICollection&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; sourceCollection;
    
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; ICollection&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; SourceCollection
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; sourceCollection;
        }
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        {
            sourceCollection &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; value;
            INotifyCollectionChanged notifyCollectionChanged &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; sourceCollection &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;as&lt;/span&gt;&lt;span style="color: #000000;"&gt; INotifyCollectionChanged;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (notifyCollectionChanged &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
            {
                notifyCollectionChanged &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SourceCollectionChanged;
            }
        }
    }
    
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; SourceCollectionChanged(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; source, NotifyCollectionChangedEventArgs args)
    {
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; synchronize changes with target collection.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    }
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;The SourceCollection property cannot be strongly-typed as INotifyCollectionChanged because INCC contains no members for retrieving the objects already present in the collection (INCC doesn’t inherit from IEnumerable).&amp;#160; As a result of being weakly-typed this API is not discoverable to the class consumer - who might inadvertently assign a regular collection to the SourceCollection property and then wonder why the target collection was not getting updated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Isn’t INCC just a poorly designed interface?&amp;#160; Shouldn’t it derive from IEnumerable.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No.&amp;#160; The architects made the right decision when they decided not to derive INCC from IEnumerable.&amp;#160; I’ll explain why later.&amp;#160; First I’ll demonstrate how we can get rid of this dynamic cast using a hypothetical language feature that is more flexible than interface inheritance and has fewer drawbacks.&lt;/p&gt;

&lt;h3&gt;Multiple Type Constraints&lt;/h3&gt;

&lt;p&gt;Ask yourself this question: &lt;strong&gt;Why can’t properties and fields be more than one type?&lt;/strong&gt;&amp;#160; At first this question might seem heretical at best and nonsensical at worst.&amp;#160; Is such a thing even possible?&amp;#160; Well it turns out that this feature - which I’ll refer to as Multiple Type Constraints (MTC) - is not only possible to implement, but very useful.&amp;#160; &lt;/p&gt;

&lt;p&gt;Let’s take a look at a revised version of our CollectionSynchronizer class that uses MTC (WARNING: the following code does &lt;u&gt;NOT&lt;/u&gt; compile)...&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:f989183c-88b1-4b50-b57f-3e54ecd46e1d" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; CollectionSynchronizer &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; No generic type but...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;{
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; ...we're using a generic type in a property definition&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; TCollection SourceCollection { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; } 
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;where&lt;/span&gt;&lt;span style="color: #000000;"&gt; TCollection : ICollection, INotifyCollectionChanged
        
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; ICollection TargetCollection { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
    
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Implementation omitted&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now objects assigned to the SourceCollection property are &lt;strong&gt;not restricted to being a single type but are instead constrained to be multiple types&lt;/strong&gt;.&amp;#160; If C# &lt;em&gt;were&lt;/em&gt; capable of compiling the code above we could write code like this*:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:200da1d1-222b-438b-8212-521ac8f31497" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;var sourceCollection &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ObservableCollection&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Customer&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;();

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; No generic type needed on the class&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;var synchronizer &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; CollectionSynchronizer();

synchronizer.SourceCollection &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; sourceCollection;
synchronizer.TargetCollection &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; myListBox.Items;

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Adding an item to the source collection,
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; and consequently the ListBox items&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;sourceCollection.Add(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Customer());

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Now we can change the type of SourceCollection
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; to another collection that implements 
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; ICollection and INotifyCollectionChanged.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;sourceCollection.SourceCollection &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MyCustomCustomerCollection();
&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;*Some folks pointed out in the comments that you could use a generic method setter with type constraints to write the same code as I’ve written above.&amp;#160; While this is true it would mean that I couldn’t set this property via XAML.&lt;/p&gt;

&lt;p&gt;The point I’m trying to make is that &lt;strong&gt;if a programming language supports multiple inheritance it should support multiple type constraints.&amp;#160; &lt;/strong&gt;C# does support MTC today, but not on properties and fields.&amp;#160; This causes problems.&amp;#160; I’ll explain further but first a small tangent…&lt;/p&gt;

&lt;h3&gt;Interface Inheritance is Harmful&lt;/h3&gt;

&lt;p&gt;I submit that the ability to inherit one interface from another has no place in a programming language.&amp;#160; Now I suspect you’d probably like some sort of justification for cutting a feature that pretty much every modern statically-typed, object-oriented programming language supports.&amp;#160; &lt;/p&gt;

&lt;p&gt;Tough.&amp;#160; You’ve got it backwards&lt;strong&gt;.&lt;/strong&gt;&amp;#160; Language features are expensive and risky propositions and therefore it’s the advocate’s responsibility to justify their inclusion - not the other way around.&amp;#160; So let’s ask the question…&lt;/p&gt;

&lt;h4&gt;&lt;strong&gt;Why Inherit?&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;There are two reasons to use inheritance:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Share implementation&lt;/li&gt;

  &lt;li&gt;Polymorphism &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Obviously we can’t share implementation code by inheriting one interface from another because interfaces don’t contain any implementation code.&amp;#160; That only leaves polymorphism.&lt;/p&gt;

&lt;p&gt;Polymorphism &lt;em&gt;seems&lt;/em&gt; like a good reason to enable interface inheritance.&amp;#160; After all we can use interface inheritance to create a version of the CollectionSynchronizer class that doesn’t require a dynamic cast.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:d3e77652-110b-43a6-b6cb-e811c3aae539" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Create new interface that inherits from two others&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;interface&lt;/span&gt;&lt;span style="color: #000000;"&gt; IObservableCollection: ICollection, INotifyCollectionChanged
{
}

&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; CollectionSynchronizer &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; No generic type but...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;{
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Now we don't need generic constraints!&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; IObservableCollection SourceCollection { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }         
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; ICollection TargetCollection { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
    
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Implementation omitted&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;There’s just one problem with this approach: &lt;strong&gt;There aren’t any collections that implement IObservableCollection because we just invented it&lt;/strong&gt;.&amp;#160; There’s no way of getting existing classes you don’t own to retroactively implement an interface. Even though the set of types in System.Collections.ObjectModel.ObservableCollection’s type hierarchy are a superset of the types in our IObservableCollection interface we can’t polymorph over both types.&amp;#160; Your IObservableCollection interface also won’t be compatible with semantically identical interfaces distributed by third parties.&amp;#160; This example demonstrates the inflexibility of interface inheritance.&lt;/p&gt;

&lt;p&gt;The key takeaway here is that&lt;strong&gt; if a language supports MTC then interface inheritance is useless &lt;/strong&gt;because MTC is a more flexible mechanism for achieving polymorphism.&amp;#160; In this context it makes sense to &lt;strong&gt;do away with interface inheritance because this feature encourages developers to build bigger, more coupled interfaces.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;The Case For Small Interfaces&lt;/h3&gt;

&lt;p&gt;The larger an interface the more likely it is to be broken.&amp;#160; A broken interface is a big problem because &lt;strong&gt;interfaces don’t version.&lt;/strong&gt;&amp;#160; It’s impossible to add, remove, or otherwise change members of an interface without breaking existing code.&lt;/p&gt;

&lt;p&gt;One strategy for avoiding the embarrassment and pain of deprecation is to &lt;strong&gt;design many, small interfaces&lt;/strong&gt;.&amp;#160; If we design interfaces that do one thing and do it well as well as avoid creating large interfaces indirectly via inheritance we&amp;#160; minimize the damage caused by deprecation.&lt;/p&gt;

&lt;p&gt;The strategy of designing many small interfaces is only viable with MTC.&amp;#160; The fact that MTC is missing from properties and fields is a blind spot.&amp;#160; Nowadays systems are increasingly being built with declarative languages like XAML which are oriented around property getters and setters.&lt;/p&gt;

&lt;h3&gt;An Ideal Candidate for Language Inclusion&lt;/h3&gt;

&lt;p&gt;Property type constraints are an evolutionary concept, not a revolutionary one.&amp;#160; Its already possible to build&amp;#160; methods that specify multiple type constraints (via generics constraints).&amp;#160; MTC could be added to properties and fields by reusing the existing generic constraint syntax used for methods.&lt;/p&gt;

&lt;p&gt;Tools/Designers would also benefit from multiple-type constraints on properties.&amp;#160; For example if a method was constrained to be both INotifyCollectionChanged and ICollection then the intellisense listing could include types that implement both.&lt;/p&gt;

&lt;p&gt;Under the hood things get a little more complicated.&amp;#160; Just like generics, MTC is an ideal candidate for inclusion in IL.&amp;#160; Any approach that reduces MTC types to&amp;#160; object types or uses some other form of erasure would share the same drawbacks as generic type erasure.&amp;#160; I don’t pretend making the necessary changes to the platform will be easy, but I think it is worth the effort.*&lt;/p&gt;

&lt;p&gt;*Update: Someone pointed out to me that this may actually be supported already because properties are just get/set method pairs under the hood.&amp;#160; Haven’t tried to write the IL myself.&amp;#160; Anyone know for sure?&lt;/p&gt;

&lt;h3&gt;The Way Forward&lt;/h3&gt;

&lt;p&gt;Multiple inheritance creates a combinatorial explosion of potential new types (ex. IObservableCollection, IObservableStack, IObservableEnumerableQueue, etc). MTC is an important tool for managing this complexity.&amp;#160;&amp;#160; &lt;strong&gt;Programming&lt;/strong&gt;&amp;#160;&lt;strong&gt;languages that provide multiple inheritance without also allowing for multiple type constraints are not strongly-typed in practice.&lt;/strong&gt;&amp;#160; Not allowing for constraints on properties and fields is an oversight that should be rectified.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-5269646029803308755?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/5269646029803308755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=5269646029803308755' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/5269646029803308755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/5269646029803308755'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2010/03/why-we-still-rely-on-dynamic-casts.html' title='Why We Still Rely on Dynamic Casts'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-3578333846050441026</id><published>2009-12-22T17:56:00.001-08:00</published><updated>2009-12-22T17:56:00.358-08:00</updated><title type='text'>Check me out on Channel 9 Talking about Rx and the Silverlight Toolkit</title><content type='html'>&lt;p&gt;&lt;a href="http://channel9.msdn.com/posts/J.Van.Gogh/Jafar-Husain-Silverlight-Toolkit-and-Rx-Part-1/"&gt;Have a look.&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-3578333846050441026?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/3578333846050441026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=3578333846050441026' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/3578333846050441026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/3578333846050441026'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/12/check-me-out-on-channel-9-talking-about.html' title='Check me out on Channel 9 Talking about Rx and the Silverlight Toolkit'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-4877958590529105913</id><published>2009-11-17T15:23:00.001-08:00</published><updated>2009-11-17T15:23:30.552-08:00</updated><title type='text'>The Joy of Rx: Rx Released!</title><content type='html'>&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx"&gt;Rx has been released&lt;/a&gt;.&amp;#160; Enjoy.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-4877958590529105913?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/4877958590529105913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=4877958590529105913' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/4877958590529105913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/4877958590529105913'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/11/joy-of-rx-rx-released.html' title='The Joy of Rx: Rx Released!'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-3640358982947773791</id><published>2009-10-23T01:11:00.000-07:00</published><updated>2009-11-18T12:57:45.696-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight Toolkit'/><title type='text'>Silverlight Toolkit Drag Drop (Part 2): Customizing Drag and Drop Behavior</title><content type='html'>&lt;p&gt;In &lt;a href="http://themechanicalbride.blogspot.com/2009/08/new-with-silverlight-toolkit-drag-and.html"&gt;part 1&lt;/a&gt; you were introduced to the new Silverlight DragDropTarget controls.&amp;#160; In addition to being powerful these controls are very flexible, allowing developers to customize almost every single aspect of their behavior.&amp;#160; In order to understand how to customize these controls you must first understand how they communicate.&amp;#160; The good news is that DDT’s communicate via a WPF-compatible implementation of the drag/drop events!&lt;/p&gt;  &lt;h3&gt;A WPF-Compatible (mostly) Implementation of Drag and Drop&lt;/h3&gt;  &lt;p&gt;The Silverlight Toolkit Drag and Drop Framework is a compatible subset of &lt;a href="http://msdn.microsoft.com/en-us/library/ms742859.aspx"&gt;WPF’s drag and drop methods and events&lt;/a&gt; – with a few small exceptions.&amp;#160; The diagram below demonstrates how DDTs are layered on top of this WPF-compat framework.&amp;#160; DDTs use these events and methods to communicate with each other.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_HI1qT6wpc4w/Stuz1zBwYqI/AAAAAAAAAQs/s9vyTeGMxVU/s1600-h/dragdropdiagram%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="dragdropdiagram" border="0" alt="dragdropdiagram" src="http://lh4.ggpht.com/_HI1qT6wpc4w/Stuz2W_7sbI/AAAAAAAAAQw/VAKyWaseAFU/dragdropdiagram_thumb.png?imgmax=800" width="244" height="178" /&gt;&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;The fact that the Silverlight Toolkit contains a full implementation of WPF’s drag and drop stack gives the developer tremendous flexibility.&amp;#160; They can…&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Use DDTs. &lt;/li&gt;    &lt;li&gt;Communicate with and customize DDTs by handling the drag and drop events. &lt;/li&gt;    &lt;li&gt;Choose not to use DDTs and use the WPF-compat API’s to initiate and manage their own drag operations. &lt;/li&gt;    &lt;li&gt;Add native drag and drop support to their custom controls by implementing the IAcceptDrop interface. &lt;/li&gt;    &lt;li&gt;Create new DDTs for existing controls by creating a class that inherits from DragDropTarget. &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Differences between Silverlight Toolkit and WPF Drag and Drop API’s&lt;/h3&gt;  &lt;h4&gt;Different Namespaces&lt;/h4&gt;  &lt;p&gt;The most obvious difference between the Silverlight implementation of drag and drop and that of WPF is that the Silverlight drag and drop objects are located in the Microsoft.Windows namespace rather than in the System.Windows namespace.&amp;#160; When writing drag and drop code &lt;strong&gt;it’s&lt;/strong&gt; &lt;strong&gt;good practice to insert the following code in your source file&lt;/strong&gt;:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:d48db835-609b-49d7-9204-089f79ee7d99" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;#if&lt;/span&gt;&lt;span style="color: #000000;"&gt; SILVERLIGHT&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Microsoft.Windows;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; SW &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Microsoft.Windows;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;#else&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; SW &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Windows;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;#endif&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Using an alias for the namespace with the drag/drop objects ensures that you can write&lt;/strong&gt; &lt;strong&gt;code that can be easily ported to WPF or a future version of Silverlight with core-level drag/drop support.&lt;/strong&gt;&lt;/u&gt;&amp;#160; All of the code samples in this series of blog posts assume that you’ve defined the alias “SW” as Microsoft.Windows in Silverlight and System.Windows in WPF.&lt;/p&gt;

&lt;h4&gt;Starting a Drag Operation&lt;/h4&gt;

&lt;p&gt;Keep in mind that &lt;strong&gt;if you intend to use a DDT you &lt;u&gt;don’t&lt;/u&gt; need to know how to do this&lt;/strong&gt; because DDT’s automatically initiate drag operations when an item is dragged&lt;strong&gt;.&lt;/strong&gt;&amp;#160; However if you want to initiate a drag operation yourself you’ll need to know about some subtle (but necessary) differences between the Silverlight’s and WPF’s &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dragdrop.dodragdrop.aspx"&gt;DoDragDrop&lt;/a&gt; methods.&amp;#160; &lt;/p&gt;

&lt;p&gt;In WPF the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dragdrop.dodragdrop.aspx"&gt;DoDragDrop&lt;/a&gt; method blocks until the drag operation completes.&amp;#160; In Silverlight there are no blocking UI methods so it is necessary to listen for a DragDropCompleted event if you want to perform an operation when a drag completes.&amp;#160; &lt;/p&gt;

&lt;p&gt;It is still possible to write cross-platform code if you use the following pattern:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:e8fbb8be-6319-4e4a-9892-7fd3123c8730" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Define an action to be executed when the drag completes.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;Action&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;SW.DragDropEffects&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; dragDropCompleted &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    effects &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
    {
        Console.WriteLine(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Format(“Drag finished: {&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;}”, effects)));
    };
    
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;#if&lt;/span&gt;&lt;span style="color: #000000;"&gt; SILVERLIGHT&lt;/span&gt;&lt;span style="color: #000000;"&gt;

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Create a handler for the DragDropCompleted event which invokes the action.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;EventHandler&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;DragDropCompletedEventArgs&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; dragDropCompletedHandler &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
dragDropCompletedHandler &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    (sender, args) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
    {
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Detach the handler so that this action is only executed once.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        SW.DragDrop.DragDropCompleted &lt;/span&gt;&lt;span style="color: #000000;"&gt;-=&lt;/span&gt;&lt;span style="color: #000000;"&gt; dragDropCompletedHandler;
        dragDropCompleted(args.Effects);
    };

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Attach the handler to the DragDropCompleted event.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;SW.DragDrop.DragDropCompleted &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; dragDropCompletedHandler;

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Begin the drag operation.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;SW.DragDrop.DoDragDrop(
    sourceControl, 
    data, 
    SW.DragDropEffects.All, 
    SW.DragDropKeyStates.LeftMouseButton);    

&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;#else&lt;/span&gt;&lt;span style="color: #000000;"&gt;

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; If WPF then just begin the drag operation.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;SW.DragDropEffects effects &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
    SW.DragDrop.DoDragDrop(
        sourceControl, 
        data, 
        SW.DragDropEffects.All);
        
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Code blocks until drag is finished...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;dragDropCompleted(effects);

&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;#endif&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Note that in addition to being asynchronous the Silverlight version of &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dragdrop.dodragdrop.aspx"&gt;DoDragDrop&lt;/a&gt; accepts an additional parameter: the initial &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dragdropkeystates.aspx"&gt;DragDropKeyStates&lt;/a&gt;.&amp;#160; In the example below this is SW.&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dragdropkeystates.aspx"&gt;DragDropKeyStates&lt;/a&gt;.LeftMouseButton.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:fd051ec7-dd0b-42c9-aa81-4c8a7060d6ff" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;SW.DragDrop.DoDragDrop(
    sourceControl, 
    data, 
    SW.DragDropEffects.All, 
    SW.DragDropKeyStates.LeftMouseButton);&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;In Silverlight (unlike WPF) it is not possible to sample the mouse state.&amp;#160; Therefore the developer must track the state of the mouse keys and pass it to &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dragdrop.dodragdrop.aspx"&gt;DoDragDrop&lt;/a&gt;.&amp;#160; This is straightforward if, as is commonly the case, the drag operation begins with a mouse click.&amp;#160; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:49b6d7c9-410a-48d5-9ddb-d51e1fb13474" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;button.MouseLeftButtonDown &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
    (sender, args) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    {
        SW.DragDrop.DoDragDrop(
            button, 
            &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Some text to transfer&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, 
            SW.DragDropEffects.All,
            SW.DragDropKeyStates.LeftMouseButton);
    };&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Although the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dragdropkeystates.aspx"&gt;DragDropKeyStates&lt;/a&gt; enumeration is a flags enum which includes members that track keyboard states there is no need to include these.&amp;#160; The DoDragDrop method will sample the keyboard and update the value when invoked.&lt;/p&gt;

&lt;h4&gt;Listening to Drag Source and Drag Target Events&lt;/h4&gt;

&lt;p&gt;In WPF there are two ways to attach a handler to an event.&amp;#160; The first is to attach a handler to the event on the UIElement and the second is to attach a handler to the attached event object:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:19e36f9f-47b7-4701-9ca9-5e9c7fb18eb9" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Works in WPF.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;myButton.DragOver &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; SW.DragEventHandler((o, a) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Console.Write(“button dragged over.”));

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Works in WPF and Silverlight Toolkit Drag Drop Framework.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;myButton.AttachEvent(
    SW.DragDrop.DragOverEvent, 
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; SW.DragEventHandler((o, a) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Console.Write(“button dragged over.”),
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Silverlight Toolkit’s Drag and Drop Framework supports the latter approach for all drag target and source events.&amp;#160; By using AttachEvent and RemoveEvent you can write code that will work on WPF and Silverlight.&amp;#160; For more information on attached events see the &lt;a href="http://msdn.microsoft.com/en-us/library/bb613550.aspx"&gt;Attached Events Overview&lt;/a&gt; on MSDN.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: DDTs implement the familiar WPF events so you don’t need to use the more verbose attached event approach when you’re working with them.&lt;/strong&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:d58c176b-0b81-46a4-8bef-27a45f5b0007" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; DragDropTarget's have the WPF events.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;myListBoxDragDropTarget.DragOver &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; SW.DragEventHandler(
        (o, a) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Console.Write(“DDTs make everything easier&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;”));
&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Indicating that an Element Can Accept a Drop Operation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In WPF all UIElements have an AllowDrop property which determines whether they will receive drag/drop events.&amp;#160; As it isn’t possible to add properties to existing types the Silverlight Tookit implementation of drag and drop uses an AllowDrop attached property on the static DragDrop object:&lt;/p&gt;

&lt;p&gt;&lt;u&gt;WPF&lt;/u&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:3559f2cd-c651-4c8d-82ca-1b88d1fc3895" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Rectangle &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;AllowDrop&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="True"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;u&gt;Silverlight&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:5cc3dcbb-7232-4784-9052-c029fb0cfa80" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Rectangle 
    &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;xmlns:msWindows&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="clr-namespace:Microsoft.Windows;assembly=System.Windows.Controls.Toolkit"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; 
    mswindows:DragDrop.AllowDrop&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="True"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;Customizing DragDropTarget Behavior&lt;/h3&gt;

&lt;p&gt;DDT’s do their best to determine the allowed effects of a drag operation by examining the bound collection and the items inside of them.&amp;#160; For example if a DDT’s control is bound to a ReadOnlyCollection or an array then the allowed effects of a drag will not include &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dragdropeffects.aspx"&gt;DragDropEffects&lt;/a&gt;.Move and the allowed effects of a drop will be &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dragdropeffects.aspx"&gt;DragDropEffects&lt;/a&gt;.None.&amp;#160; By default a DDT never sets the allowed effects of a drag to &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dragdropeffects.aspx"&gt;DragDropEffects&lt;/a&gt;.Copy because there is no generic way of cloning an item in Silverlight (ICloneable does not exist).&amp;#160; &lt;strong&gt;But what if we wanted the effect of a drop to be a Copy operation?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s say we have two DDT’s, one containing a ListBox and the other containing a DataGrid.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_HI1qT6wpc4w/SuEkLQ3pUvI/AAAAAAAAAQ0/97cvg7ABT7w/s1600-h/listboxanddatagrid%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="listboxanddatagrid" border="0" alt="listboxanddatagrid" src="http://lh3.ggpht.com/_HI1qT6wpc4w/SuEkLoxDznI/AAAAAAAAAQ4/uO5fxueFe_8/listboxanddatagrid_thumb.png?imgmax=800" width="244" height="110" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:46d43f14-90ca-4573-9bf9-ebd0caad58ce" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;StackPanel &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Orientation&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Horizontal"&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;controlsToolkit:ListBoxDragDropTarget &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;x:Name&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="listBoxDragDropTarget"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt;  HorizontalContentAlignment&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Stretch"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; VerticalContentAlignment&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Stretch"&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;ListBox &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;x:Name&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="listBox"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; VerticalAlignment&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Stretch"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; SelectionMode&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Extended"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt;  Height&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="300"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;ListBox.ItemTemplate&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;StackPanel &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Orientation&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Horizontal"&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Image &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Source&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding Image}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;TextBlock &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Text&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding Name}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; VerticalAlignment&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Center"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Margin&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="4,0,0,0"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;ListBox.ItemTemplate&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;ListBox.ItemsPanel&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;ItemsPanelTemplate&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;StackPanel &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Orientation&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Vertical"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;ItemsPanelTemplate&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;ListBox.ItemsPanel&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;ListBox&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;controlsToolkit:ListBoxDragDropTarget&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;dataToolkit:DataGridDragDropTarget &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;x:Name&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="dataGridDragDropTarget"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; msWindows:DragDrop.AllowDrop&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="true"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt;  HorizontalContentAlignment&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Stretch"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; VerticalContentAlignment&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Stretch"&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGrid &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;x:Name&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="dataGrid"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; AutoGenerateColumns&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="False"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt;  Height&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="300"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGrid.Columns&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGridTextColumn &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Binding&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding Name}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Header&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Name"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGridTextColumn &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Binding&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding Reputation}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Header&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Reputation"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGridTextColumn &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Binding&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding GamerScore}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Header&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="GamerScore"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGrid.Columns&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGrid&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;dataToolkit:DataGridDragDropTarget&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Each control is bound to an collection of Gamer instances.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:46f1281b-f738-476b-920b-bde6bb9ae099" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Gamer {
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; Name {&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;}
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;double&lt;/span&gt;&lt;span style="color: #000000;"&gt; Reputation {&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;}
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; GamerScore {&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;;}
    
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Our custom copy method.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; Gamer Clone()
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Gamer 
            {
                Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Name,
                Reputation &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Reputation,
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.GamerScore &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.GamerScore
            };
    }
}

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; snip...

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; No need to use an ObservableCollection.  We don't
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; want items removed from the ListBox.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;listBox.ItemsSource &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; []
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Gamer 
        { 
           Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Mark Rideout&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
           Reputation &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;82.234&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
           GamerScore &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;23432&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        },
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; etc.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;   };

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Using an observable collection ensures that changes
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; to the items source collection will be reflected 
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; in the grid immediately.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;dataGrid.ItemsSource &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ObservableCollection&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Person&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(); &lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;When the user drags Gamers from the ListBox to the DataGrid we’d like to add a &lt;em&gt;copy&lt;/em&gt; of the Gamer object to the DataGrid rather than add a reference to the object in the ListBox to the DataGrid’s bound collection (the default action).&amp;#160; In order to ensure that when an item is dragged from a ListBox the allowed effect is DragDropEffects.Copy rather than DragDropEffects.Link we set the ListBoxDragDropTarget’s AllowedSourceEffects property.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:f7eebab8-4f30-42d4-8d9d-763442e1acde" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;listBoxDragDropTarget.AllowedSourceEffects &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SW.DragDropEffects.Copy;&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Since the DataGridDragDropTarget doesn’t know how to handle a Copy operation we need to handle its Drop event.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:bdac7aae-f17c-4158-9479-4ae58af94cd9" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Collections.ObjectModel;

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;dataGridDragDropTarget.Drop &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
    (sender, args) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    {
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Only handle this event if it's a copy.  If the event is not handled
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; the DDTs base implementation of Drop will execute.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ((args.AllowedEffects &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; SW.DragDropEffects.Copy) &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; SW.DragDropEffects.Copy)
        {
            IList&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Person&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; dataSource &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; dataGrid.ItemsSource &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;as&lt;/span&gt;&lt;span style="color: #000000;"&gt; IList&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Person&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
            
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Retrieve the dropped data in the first available format.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; data &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; args.Data.GetData(args.Data.GetFormats()[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;]);
            
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; The data is the ItemDragEventArgs that was created by the DDT when
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; the drag started.  It contains a SelectionCollection.
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; SelectionCollection's are used by DDTs because they can transfer 
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; multiple objects.  The fact that they store the indexes of the 
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; objects within the source collection also makes reordering items
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; within a source possible.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;            ItemDragEventArgs dragEventArgs &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; data &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;as&lt;/span&gt;&lt;span style="color: #000000;"&gt; ItemDragEventArgs;
            SelectionCollection selectionCollection &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; dragEventArgs.Data &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;as&lt;/span&gt;&lt;span style="color: #000000;"&gt; SelectionCollection;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (selectionCollection &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
            {
                IEnumerable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Gamer&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; gamers &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; selectionCollection.Select(selection &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; selection.Item).OfType&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Gamer&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;();
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (gamers.Any())
                {
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt;(Gamer gamer &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; gamers)
                    {
                        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Invoke our custom Clone method to make a copy.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                        dataSource.Add(gamer.Clone());
                    }
                    args.Effects &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SW.DragDropEffects.Copy;
                    args.Handled &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;;                
                }
            }
        }
    };&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Now when we drag items from our ListBox to our DataGrid we will get copies of the Gamer objects and the ListBox’s contents will be unchanged.&lt;/p&gt;

&lt;p&gt;There are many more extensibility points in DDT’s.&amp;#160; I encourage you to take a close look at the events and properties.&amp;#160; I think you’ll be impressed by how flexible these controls are.&lt;/p&gt;

&lt;h3&gt;Powerful &lt;em&gt;and&lt;/em&gt; Flexible&lt;/h3&gt;

&lt;p&gt;By now it should be clear that the Silverlight Toolkit Drag and Drop Framework is more than a few DDTs that add drag and drop behavior to a certain Silverlight controls.&amp;#160; It is also a rich set of WPF-compatible events and methods that can be used with any Silverlight control - including your own!&lt;/p&gt;

&lt;p&gt;Next time: Adding Drag and Drop support to your custom controls!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-3640358982947773791?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/3640358982947773791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=3640358982947773791' title='44 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/3640358982947773791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/3640358982947773791'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/10/silverlight-drag-drop-support-part-2.html' title='Silverlight Toolkit Drag Drop (Part 2): Customizing Drag and Drop Behavior'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_HI1qT6wpc4w/Stuz2W_7sbI/AAAAAAAAAQw/VAKyWaseAFU/s72-c/dragdropdiagram_thumb.png?imgmax=800' height='72' width='72'/><thr:total>44</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-1498928332510171843</id><published>2009-10-19T18:18:00.000-07:00</published><updated>2009-10-22T18:19:04.152-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight Toolkit'/><title type='text'>New with the Silverlight Toolkit: Drag and Drop Support for all your Favorite Controls! (Part 1)</title><content type='html'>&lt;p&gt;One of the highest voted requests on the &lt;a href="http://silverlight.codeplex.com/"&gt;Silverlight Toolkit CodePlex&lt;/a&gt; page is drag and drop support for the TreeView control.&amp;#160; The good news is the Toolkit team listened and has not only delivered Drag and Drop for the TreeView, but they’ve added support for &lt;strong&gt;all the major Silverlight controls!&lt;/strong&gt;&amp;#160; In the October Toolkit refresh you’ll find controls which add Drag and Drop support to all of your favorite controls – no code required!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_HI1qT6wpc4w/StujLmOVhUI/AAAAAAAAAPM/x7jDenzHQSg/s1600-h/dd1%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="dd1" border="0" alt="dd1" src="http://lh6.ggpht.com/_HI1qT6wpc4w/StujMEAisMI/AAAAAAAAAPQ/RrE8IClECMo/dd1_thumb.png?imgmax=800" width="244" height="185" /&gt;&lt;/a&gt; &lt;a href="http://lh6.ggpht.com/_HI1qT6wpc4w/StujMhtQ7PI/AAAAAAAAAPU/GIFpvnchpFE/s1600-h/dd2%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="dd2" border="0" alt="dd2" src="http://lh6.ggpht.com/_HI1qT6wpc4w/StujMyQ3Q1I/AAAAAAAAAPY/yzfvaGu58sk/dd2_thumb.png?imgmax=800" width="244" height="185" /&gt;&lt;/a&gt; &lt;a href="http://lh6.ggpht.com/_HI1qT6wpc4w/StujNUDVlJI/AAAAAAAAAPc/0Qcnr7XMOrE/s1600-h/dd4%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="dd4" border="0" alt="dd4" src="http://lh5.ggpht.com/_HI1qT6wpc4w/StujN2S2MUI/AAAAAAAAAPg/U90aPHLmeZU/dd4_thumb.png?imgmax=800" width="244" height="188" /&gt;&lt;/a&gt;&amp;#160; &lt;a href="http://lh4.ggpht.com/_HI1qT6wpc4w/StujOQiPSqI/AAAAAAAAAPk/g6hbe6zcf7g/s1600-h/dd4%5B5%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="dd4" border="0" alt="dd4" src="http://lh6.ggpht.com/_HI1qT6wpc4w/StujOmAgmDI/AAAAAAAAAPo/UAmMQvOoVxE/dd4_thumb%5B1%5D.png?imgmax=800" width="244" height="188" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;Introducing The Drag/Drop Target Controls&lt;/h3&gt;  &lt;p&gt;&lt;strong&gt;A DragDropTarget is a Content Control that adds default drag and drop actions to the control nested inside of it.&lt;/strong&gt;&amp;#160; DragDropTarget’s provide the following functionality:&lt;/p&gt;  &lt;p&gt;1.&amp;#160; Initiates a drag operation when an item container is dragged.&lt;/p&gt;  &lt;p&gt;2.&amp;#160; Displays a snapshot of the the item container by the mouse while it is being dragged.&lt;/p&gt;  &lt;p&gt;3.&amp;#160; Handles drag target events and specifies which drag operations are possible by examining the item source bound to the nested control.&lt;/p&gt;  &lt;p&gt;4.&amp;#160; If an item is dropped onto the drag drop target, it is added to the nested control if the nested control is bound to an ObservableCollection (or any collection that implements INotifyCollectionChanged and contains the same type of items as the item that was dropped).&lt;/p&gt;  &lt;p&gt;5.&amp;#160; Where possible, scrolls vertically and horizontally when an item is dragged near the edge of the control.&lt;/p&gt;  &lt;p&gt;This release of the toolkit introduces the following implementations:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;ListBoxDragDropTarget &lt;/li&gt;    &lt;li&gt;TreeViewDragDropTarget &lt;/li&gt;    &lt;li&gt;DataGridDragDropTarget &lt;/li&gt;    &lt;li&gt;DataPointSeriesDragDropTarget &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;ListBoxDragDropTarget&lt;/h4&gt;  &lt;p&gt;In this example we have a ListBox created in XAML and bound to an observable collection.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:baeb77fe-309a-4ef3-a3e6-8f6a99fc1c6a" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;ListBox &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;x:Name&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;=”myListBox &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;To add drag and drop functionality to our ListBox we nest it inside of the ListBoxDragDropTarget control…&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:6a56e8d3-c714-47be-ba82-ce1dd4d09990" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;toolkit:ListBoxDragDropTarget
  &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;xmlns:toolkit&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="System.Windows.Controls.Toolkit"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt;
  xmlns:mswindows&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Microsoft.Windows"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt;
  mswindows:DragDrop.AllowDrop&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;=”True”&amp;gt;
     &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;&amp;lt;ListBox x:Name&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="myListBox"&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
         &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;ListBox.ItemsPanel&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;ItemsPanelTemplate&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;StackPanel &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;ItemsPanelTemplate&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;ListBox.ItemsPanel&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
     &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;ListBox&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;toolkit:ListBoxDragDropTarget&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;…and that’s it!&amp;#160; Now we can drag items to and from our ListBox.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_HI1qT6wpc4w/StujPDcS02I/AAAAAAAAAPs/gs0HrDoIToc/s1600-h/listbox1%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="listbox1" border="0" alt="listbox1" src="http://lh5.ggpht.com/_HI1qT6wpc4w/StujPXpceGI/AAAAAAAAAPw/cwPmknSlnh4/listbox1_thumb.png?imgmax=800" width="244" height="215" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If the SelectionMode of the ListBox is set to Multiple or Extended it is also possible to drag and drop several items at once.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_HI1qT6wpc4w/StujP0KqxvI/AAAAAAAAAP0/B3kYfd6PplU/s1600-h/listbox2%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="listbox2" border="0" alt="listbox2" src="http://lh5.ggpht.com/_HI1qT6wpc4w/StujQTTEMaI/AAAAAAAAAP4/cIR1VJ5pbOA/listbox2_thumb.png?imgmax=800" width="244" height="178" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Why did you need to specify the ItemPanelTemplate?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The ListBoxDragDropTarget cannot reorder items in a ListBox when it is virtualized because it cannot conclusively determine the index of each item.&amp;#160; Therefore we replace the default Panel (VirtualizedStackPanel) with a normal StackPanel.&amp;#160; If you don’t need to enable the reordering items within the ListBox then it isn’t necessary to specify the ItemPanelTemplate.&lt;/p&gt;

&lt;h4&gt;TreeViewDragDropTarget&lt;/h4&gt;

&lt;p&gt;The TreeViewDragDropTarget is used the same way as the ListBoxDragDropTarget.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:160a0304-87de-4da5-9843-63b738c0965b" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;controlsToolkit:TreeViewDragDropTarget &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;msWindows:DragDrop.AllowDrop&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="true"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt;  HorizontalContentAlignment&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Stretch"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; VerticalContentAlignment&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Stretch"&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;controlsToolkit:TreeViewDragDropTarget.Resources&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;win:HierarchicalDataTemplate &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;x:Key&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="hierarchicalTemplate"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; ItemsSource&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding Reports}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;StackPanel &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Orientation&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Horizontal"&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Image &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Source&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding Image}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Width&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="16"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Height&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="16"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;TextBlock &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Text&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding Name}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; VerticalAlignment&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Center"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Margin&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="4,0,0,0"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;win:HierarchicalDataTemplate&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;controlsToolkit:TreeViewDragDropTarget.Resources&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;controls:TreeView &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;ItemTemplate&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{StaticResource hierarchicalTemplate}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Height&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="300"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;controls:TreeView&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;controlsToolkit:TreeViewDragDropTarget&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Note that there is no need to specify the ItemPanelTemplate because in Silverlight the TreeView is not virtualized.&lt;/p&gt;

&lt;pre&gt;&lt;a href="http://lh3.ggpht.com/_HI1qT6wpc4w/StujQh6hKEI/AAAAAAAAAP8/DabLMv9Um5c/s1600-h/treeview1%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="treeview1" border="0" alt="treeview1" src="http://lh4.ggpht.com/_HI1qT6wpc4w/StujQ5W9o8I/AAAAAAAAAQA/kDouwb8Rzug/treeview1_thumb.png?imgmax=800" width="235" height="172" /&gt;&lt;/a&gt; &lt;/pre&gt;

&lt;p&gt;The TreeViewDragDropTarget provides all the functionality you’ve come to expect from Windows Explorer (and more).&amp;#160; &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;During a drag operation parent’s expand when hovered over after a short delay &lt;/li&gt;

  &lt;li&gt;Dragging a parent into itself is forbidden &lt;/li&gt;

  &lt;li&gt;The ability to drag above, below, and into a node is supported &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these actions can be overridden or cancelled using the events.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DataGridDragDropTarget&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using the DataGridDragDropTarget is straightforward:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:e6e6226c-ebcc-4ae8-9230-8ac35948caef" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;dataToolkit:DataGridDragDropTarget &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;msWindows:DragDrop.AllowDrop&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="true"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt;  HorizontalContentAlignment&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Stretch"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; VerticalContentAlignment&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Stretch"&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGrid &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;x:Name&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="dataGrid"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; AutoGenerateColumns&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="False"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt;  Height&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="300"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGrid.Columns&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGridTextColumn &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Binding&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding Name}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Header&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Name"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGridTextColumn &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Binding&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding Reputation}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Header&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Reputation"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGridTextColumn &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;Binding&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding GamerScore}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Header&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="GamerScore"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGrid.Columns&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;data:DataGrid&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;dataToolkit:DataGridDragDropTarget&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_HI1qT6wpc4w/StujRIxRohI/AAAAAAAAAQE/huLQsC2agak/s1600-h/datagrid1%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="datagrid1" border="0" alt="datagrid1" src="http://lh5.ggpht.com/_HI1qT6wpc4w/StujRuYzTTI/AAAAAAAAAQI/qp8R2WKc9gA/datagrid1_thumb.png?imgmax=800" width="244" height="107" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Like the ListBoxDragDropTarget, multiple selection is supported.&amp;#160; However the DataGridDragDropTarget has some limitations due to the fact that it is not an ItemsControl and it is virtualized, specifically that reordering items within a DataGrid is not supported.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DataPointSeriesDragDropTarget&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The DataPointSeriesDragDropTarget supports all of the series that ship with Silverlight Charts.&amp;#160; However it is used slightly differently than other DragDropTargets.&amp;#160; Instead of wrapping the individual series it is necessary to put the entire Chart in the DragDropTarget. &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:7cccfc85-c614-4a5a-8503-6c08d862cfff" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;chartingToolkit:DataPointSeriesDragDropTarget &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;msWindows:DragDrop.AllowDrop&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="true"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; HorizontalContentAlignment&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Stretch"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; VerticalContentAlignment&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Stretch"&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;chartingToolkit:Chart &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;x:Name&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="chart"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Background&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="White"&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;chartingToolkit:ColumnSeries &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;IndependentValueBinding&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding Name}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; DependentValueBinding&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding Reputation}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Title&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Reputation"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;chartingToolkit:PieSeries &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;IndependentValueBinding&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding Name}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; DependentValueBinding&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="&lt;/span&gt;&lt;span style="color: #808000;"&gt;{Binding GamerScore}&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; Title&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;="Gamer Score"&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;chartingToolkit:Chart&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;chartingToolkit:DataPointSeriesDragDropTarget&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;a href="http://lh4.ggpht.com/_HI1qT6wpc4w/StujSH2glQI/AAAAAAAAAQM/fol4Nu-vUOQ/s1600-h/chart1%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="chart1" border="0" alt="chart1" src="http://lh6.ggpht.com/_HI1qT6wpc4w/StujSThB5uI/AAAAAAAAAQQ/jb9RppAorBc/chart1_thumb.png?imgmax=800" width="244" height="110" /&gt;&lt;/a&gt; 

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“What if a Chart contains multiple series?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The DataPointSeriesDragDropTargets allows diambiguation between the series by detecting drop operations on the legend.&amp;#160; In other words, items can be dropped both onto the surface of a series or its legend items.&amp;#160; In the example below the Chart contains two series: a Pie series and a column series.&amp;#160; Items can be dragged from a list box into the column series by dropping the items on the column series’&amp;#160; legend item.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_HI1qT6wpc4w/StujSvR4MII/AAAAAAAAAQU/s35miYAFDbw/s1600-h/chart2%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="chart2" border="0" alt="chart2" src="http://lh5.ggpht.com/_HI1qT6wpc4w/StujTN6dZ5I/AAAAAAAAAQY/eD2d030ZtAY/chart2_thumb.png?imgmax=800" width="244" height="186" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_HI1qT6wpc4w/StujTpPVm-I/AAAAAAAAAQc/jtmV2HMzaqc/s1600-h/chart3%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="chart3" border="0" alt="chart3" src="http://lh4.ggpht.com/_HI1qT6wpc4w/StujT1TFCkI/AAAAAAAAAQg/AAat25JJAhA/chart3_thumb.png?imgmax=800" width="244" height="106" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;It’s also easy to drag items between series, either by dropping data directly onto a series data point or onto their legend item entries.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_HI1qT6wpc4w/StujUbqziII/AAAAAAAAAQk/8BtT2026URM/s1600-h/chart4%5B2%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="chart4" border="0" alt="chart4" src="http://lh5.ggpht.com/_HI1qT6wpc4w/StujUkJXKDI/AAAAAAAAAQo/0jZ6I0T4xYI/chart4_thumb.png?imgmax=800" width="244" height="103" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;A Labour of Love&lt;/h3&gt;

&lt;p&gt;Silverlight Drag and Drop support is a personal, off-hours project that I’ve been working on sporadically for the last few months.&amp;#160; I thought it would be a productive way of learning &lt;a href="http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html"&gt;Rx&lt;/a&gt;, the new reactive programming framework for .NET.&amp;#160; When I approached the Toolkit team and asked if they would ship it they agreed.&amp;#160; Of course, having formerly worked for the Toolkit team creating the Silverlight Chart control, ISM, and the Rating control I had some pretty good contacts ;-).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next time: Overriding the Default Actions of DragDropTargets&lt;/strong&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-1498928332510171843?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/1498928332510171843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=1498928332510171843' title='31 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/1498928332510171843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/1498928332510171843'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/08/new-with-silverlight-toolkit-drag-and.html' title='New with the Silverlight Toolkit: Drag and Drop Support for all your Favorite Controls! (Part 1)'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_HI1qT6wpc4w/StujMEAisMI/AAAAAAAAAPQ/RrE8IClECMo/s72-c/dd1_thumb.png?imgmax=800' height='72' width='72'/><thr:total>31</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-6973348406229139109</id><published>2009-08-01T18:13:00.001-07:00</published><updated>2009-08-02T09:26:16.898-07:00</updated><title type='text'>The Joy of Rx: Building an Asynchronous API with Rx and IQueryable (Updated)</title><content type='html'>&lt;p&gt;&lt;strong&gt;Updated: One of our architects expressed concerns about my original solution to this problem because it required a down-cast to IObservable.&amp;#160; In the process of explaining to him why this was unavoidable I figured out that it was, in fact, avoidable. :-) I've since updated this article with a much more elegant solution.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The IObservable interface is a true Microsoft innovation and a very significant discovery.&amp;#160; Although we've known for a long time that &lt;a href="http://www.google.com/reader/view/#stream/feed%2Fhttp%3A%2F%2Fblogs.msdn.com%2Fericlippert%2Frss.xml"&gt;iteration could be done either via push or pull&lt;/a&gt; &lt;strong&gt;we hadn't figured out how to do push iteration in a composable way until IObservable came along&lt;/strong&gt;.&amp;#160; It's interesting to speculate about how the .NET framework might've been designed differently if IObservable had been present alongside IEnumerable in .NET 1.0.&amp;#160; Here are a few questions that haunt me...&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Rather than introduce the redundant concept of an event into the CLR would we have used properties of type IObservable instead? &lt;/li&gt;    &lt;li&gt;Would all asynchronous API's return an IObservable rather than use one of any number of other patterns. &lt;/li&gt;    &lt;li&gt;Would the &amp;quot;yield&amp;quot; keyword in C# work for methods that return IObservable as well as those that return IEnumerable? &lt;/li&gt;    &lt;li&gt;Would the ItemsSource property of the Silverlight/WPF ItemsControl (which most data controls derive from or are modeled after) be of type IObservable (or object) rather than IEnumerable? &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;There's no way of knowing for sure but I like to think the answer to these questions is &amp;quot;yes.&amp;quot;&amp;#160; There is yet another question worth asking now with the benefit of hindsight:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;If IObservable had been in BCL all along would IQueryable inherit from IObservable as well as IEnumerable (or neither)?&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Probably.&amp;#160; &lt;strong&gt;The most common use of IQueryable is to execute query logic on a remote machine.&lt;/strong&gt;&amp;#160; Because they take a relatively large amount of time &lt;strong&gt;it makes sense to make remote calls asynchronously and expose a non-blocking interface.&amp;#160; &lt;/strong&gt;Ideally IQueryable wouldn't inherit from either IObservable or IEnumerable.&amp;#160; Instead it probably should've had its own implementation of the query operators and provided two conversion methods: ToEnumerable and ToObservable.&amp;#160; Unfortunately this would be a breaking change at this point and is therefore highly unlikely to happen.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&amp;quot;Okay, okay.&amp;#160; You're bumming me out.&amp;#160; How can I traverse an IQueryable asynchronously?&amp;quot;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Before we take a look at an example it might be helpful to have a look at the first part of the excellent &lt;a href="http://blogs.msdn.com/mattwar/pages/linq-links.aspx"&gt;&amp;quot;Building a Linq IQueryable Provider&amp;quot;&lt;/a&gt; series on the Wayward Weblog.&amp;#160; I'm going to use the code in that article as a starting point.&lt;/p&gt;  &lt;h4&gt;Asynchronously Querying Yahoo Finance&lt;/h4&gt;  &lt;p&gt;Yahoo Finance has a REST service that returns stock history in a CSV file.&amp;#160; We'd like to be able to query for stocks using an API like this:&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:de004a8b-38dc-4be2-920d-1f8a9aa6616b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;YahooFinance service &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; YahooFinance();

IQueryable stockInfos &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    from stock &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; service.Stocks
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;where&lt;/span&gt;&lt;span style="color: #000000;"&gt; stock.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;MSFT&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;where&lt;/span&gt;&lt;span style="color: #000000;"&gt; stock.Date &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DateTime(&lt;/span&gt;&lt;span style="color: #800080;"&gt;1999&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
    select stock;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;First we'll create a simple C# class which will wrap the REST service and expose an asynchronous API. To build it we'll use the GetDownloadString extension method we introduced to WebClient in my &lt;a href="http://themechanicalbride.blogspot.com/2009/07/developing-with-rx-part-2-converting.html"&gt;last Rx post&lt;/a&gt;.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:2bf9ff52-78ca-491b-a021-0dbfd7570517" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; YahooFinanceStockService
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; WebClient client &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; WebClient();
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; uriFormat &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://ichart.finance.yahoo.com/table.csv?s={0}&amp;amp;a={1}b={2}&amp;amp;c={3}&amp;amp;d={4}&amp;amp;e={5}&amp;amp;f={6}&amp;amp;g=d&amp;amp;ignore=.csv&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;;

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; IObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;StockInfo&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetStockInfo(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; name, DateTime from, DateTime to)
    {
         &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            client.GetDownloadString(
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Uri(
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Format(
                        uriFormat,
                        name,
                        from.Day,
                        from.Month,
                        from.Year,
                        to.Day,
                        to.Month,
                        to.Year)))
                .SelectMany(
                    text &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                        (
                        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; retrieve each line in the CSV file&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                        from line &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                            text
                                &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; remove trailing line break at end of file&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                                .Trim()
                                .Split(&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
                                &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; skip header line&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                                .Skip(&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
                        let fields &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; line.Split(&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;,&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
                        select
                            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; StockInfo
                            {
                                Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; name,
                                Date &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; DateTime.Parse(fields[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;]),
                                Open &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;double&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Parse(fields[&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]),
                                High &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;double&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Parse(fields[&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;]),
                                Low &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;double&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Parse(fields[&lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;]),
                                Close &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;double&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Parse(fields[&lt;/span&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&lt;span style="color: #000000;"&gt;]),
                                Volume &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Parse(fields[&lt;/span&gt;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&lt;span style="color: #000000;"&gt;]),
                                AdjustedClose &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;double&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Parse(fields[&lt;/span&gt;&lt;span style="color: #800080;"&gt;6&lt;/span&gt;&lt;span style="color: #000000;"&gt;])
                            }
                        ).ToObservable());
    }
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Next we'll create a YahooFinanceQueryProvider that derives from the QueryProvider class introduced in the Wayward Weblog series.&amp;#160; The query provider interprets the query expression, makes one or more calls to the service's GetStockInfo method, and returns a single IObservable when its Execute method is called.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:85812ba6-06c3-4a3b-80fb-ab5c1a95dafb" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; YahooFinanceStocksQueryProvider : QueryProvider
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; YahooFinanceStockService service &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; YahooFinanceStockService();

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetQueryText(Expression expression)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;YahooFinance.Stocks&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
    }

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; Execute(Expression expression)
    {
         &lt;/span&gt;&lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt; Normally this would contain generic logic to
          * parse the query and make the appropriate call to the
          * service.  That's outside of the scope of this article so
          * we'll just make a call to the service with constant data. &lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; service.GetStockInfo(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;MSFT&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DateTime(&lt;/span&gt;&lt;span style="color: #800080;"&gt;1999&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;), DateTime.Now);
    }
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Now that we have a query provider let's create a query object that we can expose.&amp;#160; We'll start with the Query class from the &lt;a href="http://blogs.msdn.com/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx"&gt;Webward Weblog series&lt;/a&gt; but we'll make a few small changes:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;We'll rename the class from Query to ObservableQuery. &lt;/li&gt;

  &lt;li&gt;In addition to IQueryable our ObservableQuery class will also implement IObservable. &lt;/li&gt;

  &lt;li&gt;If the ObservableQuery object is traversed synchronously (foreach) we'll convert the IObservable object returned by the query provider to an IEnumerable. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:4b915669-4cf7-429f-9e98-3028ddd209b4" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ObservableQuery&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; : IQueryable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, IQueryable, IEnumerable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, IEnumerable, IOrderedQueryable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, IOrderedQueryable, IObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;internal&lt;/span&gt;&lt;span style="color: #000000;"&gt; QueryProvider provider;

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;internal&lt;/span&gt;&lt;span style="color: #000000;"&gt; Expression expression;

        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; IEnumerator&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetEnumerator()
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; ((IObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.provider.Execute(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.expression)).ToEnumerable().GetEnumerator();
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; IDisposable Subscribe(IObserver&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; observer)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; ((IObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.provider.Execute(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.expression)).Subscribe(observer);
        }
    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&amp;quot;Hold on a second.&amp;#160; Why bother to change the query provider to return an IObservable when we can just do the reverse?&amp;#160; We could just convert the IEnumerable to an IObservable if our Query object was traversed asynchronously?&amp;quot;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We don't want to do this because converting an asynchronous operation to an IEnumerable uses a precious resource: &lt;strong&gt;a thread&lt;/strong&gt;.&amp;#160; Let's say our query provider makes several calls to our web service, one for each stock in the query.&amp;#160; We would hope that it would make these calls concurrently.&amp;#160; If the query provider had to return an IEnumerable it would need to block and wait for the results from the worker threads.&amp;#160; If we turn around and immediately convert that IEnumerable into an IObservable a thread is completely wasted. Therefore &lt;strong&gt;to conserve threads we should avoid converting an IObservable to an IEnumerable until we absolutely have to.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now we're ready to write the Yahoo Finance class that we will query against.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:edebb095-c0b6-455c-bf0d-f905769e4bba" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; YahooFinance
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; YahooFinance()
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Stocks &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ObservableQuery&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;StockInfo&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; YahooFinanceStocksQueryProvider());
    }

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; ObservableQuery&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;StockInfo&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Stocks { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;internal&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Now if we wrote a query against our Yahoo Finance class and compiled the code we would get the compiler error &amp;quot;Multiple Implementations of the Query Pattern were found for the source type.&amp;quot;&amp;#160; The C# compiler would be confused because ObservableQuery implements both IEnumerable and IObservable and it wouldn't know which set of extension methods to invoke.&amp;#160; The answer is to implement the query pattern for our concrete ObservableQuery class because the compiler will always choose the methods from the most derived class.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:9d8153c7-0fc5-4265-90c2-344cada71c98" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ObservableQuery
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; ObservableQuery&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Where&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt; ObservableQuery&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; q, Expression&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Func&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; predicateExpression)
        {
            MethodInfo method &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(ObservableQuery).GetMethods().Where(m &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; m.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Where&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; m.GetParameters().Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;).First();
            method &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; method.MakeGenericMethod(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Type[] { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(T) });

            var expression &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
                Ex.Call(method, q.expression, predicateExpression);
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ObservableQuery&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(q.provider, expression);
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; ObservableQuery&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;R&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Select&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T,R&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt; ObservableQuery&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; q, Expression&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Func&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T, R&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; predicateExpression)
        {
            MethodInfo method &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(ObservableQuery).GetMethods().Where(m &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; m.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Select&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; m.GetParameters().Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;).First();
            method &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; method.MakeGenericMethod(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Type[] { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(T), &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(R) });

            var expression &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                Ex.Call(method, q.expression, predicateExpression);
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ObservableQuery&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;R&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(q.provider, expression);
        }

        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; etc, etc, etc...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Every time an ObservableQuery extension method is called we append the method call to the expression created so far!&lt;/strong&gt;&amp;#160; In cases where a method accepts a function as a parameter (ex. Select, Where, OrderBy) we accept an expression of that function type instead.&amp;#160; This ensures that we don't lose any of the information about the query expression as we're building it.&amp;#160; The end result of our query is an ObservableQuery that knows exactly what expression it must execute.&lt;/p&gt;

&lt;h4&gt;Asynchronously Iterating our Observable Query&lt;/h4&gt;

&lt;p&gt;Query expressions against an ObservableQuery return a new ObservableQuery - which is an IObservable.&amp;#160; Iterating its results is just a matter of subscribing to it.&lt;/p&gt;

&lt;p&gt;
  &lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:e504c0dc-feba-413d-ad3b-268b60a60b1e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;YahooFinance service &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; YahooFinance();

IQueryable stockInfos &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    from stock &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; service.Stocks
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;where&lt;/span&gt;&lt;span style="color: #000000;"&gt; stock.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;MSFT&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;where&lt;/span&gt;&lt;span style="color: #000000;"&gt; stock.Date &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DateTime(&lt;/span&gt;&lt;span style="color: #800080;"&gt;1999&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
    select stock;

stockInfos.Subscribe(stock &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Debug.WriteLine(stock));&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;On the other hand if we want to traverse the results synchronously we can use foreach...&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:832000e8-d4b2-4a35-919c-4c1406c243d1" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt;(StockInfo stock &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; stockInfos)
{
    Debug.WriteLine(stock);
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;h4&gt;&lt;/h4&gt;

&lt;h4&gt;Asynchronous Queryable Services&lt;/h4&gt;

&lt;p&gt;That's it.&amp;#160; Hopefully existing query providers will be updated to use this approach so that they can support asynchronous iteration.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-6973348406229139109?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/6973348406229139109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=6973348406229139109' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/6973348406229139109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/6973348406229139109'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/08/joy-of-rx-building-asynchronous-service.html' title='The Joy of Rx: Building an Asynchronous API with Rx and IQueryable (Updated)'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-3771217239287643503</id><published>2009-07-30T10:32:00.001-07:00</published><updated>2009-08-01T18:24:32.432-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight Toolkit'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>The Joy of Rx: The Event-based Async Pattern vs. IObservable</title><content type='html'>&lt;p&gt;In part 1 we talked about how to convert events to IObservables.&amp;#160; However Rx isn't just about querying events, it's also about querying asynchronous operations.&amp;#160; &lt;/p&gt;  &lt;p&gt;There are two common asynchronous patterns in the .NET framework: the event-based asynchronous pattern and Begin/EndInvoke.&amp;#160; Currently MSDN &lt;a href="http://msdn.microsoft.com/en-us/library/ms228969.aspx"&gt;recommends using the event-based asynchronous pattern&lt;/a&gt; where possible.&amp;#160; This recommendation &lt;em&gt;may or may not change&lt;/em&gt; when IObservable is released with .NET 4.0.&amp;#160; &lt;strong&gt;I want to make clear that the opinions expressed in this post are my own personal views and are &lt;u&gt;not&lt;/u&gt; consistent with official MSDN guidance&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Don't use the event-based asynchronous pattern&lt;/u&gt;.&amp;#160; &lt;/strong&gt;Or if you &lt;em&gt;must&lt;/em&gt; use the event-based asynchronous pattern be sure to also provide a Begin/EndInvoke version of the API that uses IAsyncResult.&amp;#160; Why?&amp;#160; Because &lt;strong&gt;the event-based asynchronous pattern is deeply flawed&lt;/strong&gt;.&amp;#160; To understand why let's examine a typical piece of code that uses the event-based asynchronous pattern.&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:a2bba4f6-f1f9-4d32-8eab-4291c704cb62" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;Guid token &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Guid.NewGuid();
var webClient &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; WebClient();
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; We need to refer to the identifier within the body
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; of the method so we must first initialize it to null.
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; This means we can't use type inference to avoid
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; having to clutter our code with this absurdly long 
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; (and entirely unnecessary) delegate type.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;DownloadStringCompletedEventHandler handler &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
handler &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; (o, a) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
{
   &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (((Guid)a.UserState) &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; token)
      &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;;

   &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; unhook from the event so that we don't keep firing
   &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; after we've gotten our data asynchronously.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;   webClient.DownloadStringCompleted &lt;/span&gt;&lt;span style="color: #000000;"&gt;-=&lt;/span&gt;&lt;span style="color: #000000;"&gt; handler;
   &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (a.Error &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
   {
       &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Handle exception.  This may include throwing but
       &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; we may also have to invent some method of manually 
       &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; propagating it if we don't have the knowledge to 
       &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; handle it at this point and we are in the middle of several 
       &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;other asynchronous operations.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;   }
   &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;a.Cancelled)
   {
      Debug.WriteLine(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Format(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;The downloaded HTML is {0}.&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, a.Result));
   }
}
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Notice that the only link between the method and the event that returns
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; its data is a simple naming convention.  There's no way to know for _sure_
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; which event will return a method's data.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;client.DownloadStringCompleted &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; handler;
client.DownloadStringAsync(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Uri(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://www.jeffwilcox.com&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;), token);
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;A thoroughly awful piece of code no?&amp;#160; The good news is that by adding an &lt;a href="http://themechanicalbride.blogspot.com/2009/07/developing-with-rx-part-1-extension.html"&gt;extension event&lt;/a&gt; to the WebClient class we can wrap the event-based asynchronous pattern in an IObservable.&amp;#160; Using Rx works around all of the the issues pointed out in the comments above.&amp;#160; &lt;/p&gt;

&lt;p&gt;Of course it's rather cumbersome to create a new class that inherits from IObservable whenever we need to return the result of an asynchronous operation.&amp;#160; It also seems a little silly given that IObservable only has one method: Subscribe.&amp;#160; Given this fact it's helpful to create an AnonymousObservable class which accepts an action and invokes it when the Subscribe method is called.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:c4a1e56c-1ff0-4549-b2c8-45e86cf061c4" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;internal&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; AnonymousObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; : IObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; Func&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;IObserver&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, IDisposable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; subscribeAction;

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; AnonymousObservable(Func&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;IObserver&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, IDisposable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; subscribeAction)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.subscribeAction &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; subscribeAction;
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; IDisposable Subscribe(IObserver&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; observer)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; subscribeAction(observer);
        }
    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now that we've got our handy, reusable AnonymousObservable class we're ready to create our GetDownloadString extension event.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:99a6b1be-828e-49ae-befc-66038a73cb33" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; WebClientExtensions
    {
       &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; No need to put Async in the method title, it's implicit given that
       &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; an observable is being returned.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; IObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetDownloadString(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt; WebClient client, Uri address)
        {
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Delay action by nesting it in an observable.
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Nothing should ever happen until a client subscribes to the
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; observable, just as nothing should happen until an 
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; IEnumerable is traversed.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; AnonymousObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(
                observer &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                {
                    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Several downloads may be going on simultaneously.
                    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; The token allows us to establish that we're retrieving
                    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; the right one.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                    Guid token &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Guid.NewGuid();

                    var stringDownloaded &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                        Observable.FromEvent&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;DownloadStringCompletedEventArgs&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(client, &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;DownloadStringCompleted&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
                            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Confirm its our download using captured state variable&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                            .Where(evt &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ((Guid)evt.EventArgs.UserState) &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; token)
                            .Take(&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;implicitly unhooks handler after event is received&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt; errorOccurred &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
                    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Subscribe to the IObservable.  Under the hood Rx
                    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; creates an anonymous observer class that invokes
                    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; the three actions passed to the Subscribe method.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                    IDisposable unsubscribe &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
                        stringDownloaded.Subscribe(
                            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; OnNext action&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                            ev &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
                            {
                                &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Propagate the exception if one is
                                &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; reported.  After this, all observers
                                &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; will continue to propagate this
                                &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; exception via the OnError method call
                                &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; until it is caught.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (ev.EventArgs.Error &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
                                {
                                    errorOccurred &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
                                    observer.OnError(ev.EventArgs.Error);
                                }
                                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;ev.EventArgs.Cancelled)
                                {
                                    observer.OnNext(ev.EventArgs.Result);
                                }
                            },
                            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; OnError action (propagate exception)&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                            ex &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; observer.OnError(ex),
                            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; OnCompleted action&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                            () &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                            {
                                &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; No need to call OnCompleted if 
                                &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; there has been an exception.
                                &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; It is implicit that there will 
                                &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; be no more data.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;errorOccurred)
                                {
                                    observer.OnCompleted();
                                }
                            });
                    client.DownloadStringAsync(address, token);
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; unsubscribe;
                });
        }
    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Granted converting the event-based asynchronous pattern to IObservable requires a little bit of code, but the complexity is pushed onto the library developer.&amp;#160; Look at how easy it is to consume the IObservable API.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:afc56a90-3aeb-4679-b564-10a7e8e2f60e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;var webClient &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; WebClient();
webClient
   .GetDownloadString(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Uri(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://www.jeffwilcox.com&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;))
   .Subscribe(html &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Debug.WriteLine(html));
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;No need to fuss with event argument objects.&amp;#160; The IObservable/IObserver objects take on the concerns of cancelling and propagating exceptions.&amp;#160; The developer is given exactly what he or she expects: an asynchronously downloaded string containing the contents of a web page.&lt;/p&gt;

&lt;h4&gt;Building Complex Queries by Combining Asynchronous Operations&lt;/h4&gt;

&lt;p&gt;Now that we've got our handy GetDownloadString extension method we can build some pretty complex queries with it.&amp;#160; Let's use it to download the HTML from the first ten results pages of a Bing search at once.&amp;#160; &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:de4a4e3d-24a6-4227-bc04-bcda7b0b8f51" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; EnumerableExtensions
{
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; This is a very handy extension method missing from Linq.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; IEnumerable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Iterate&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(T initalValue, Func&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T, T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; next)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;yield&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; initalValue;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
        {
            initalValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; next(initalValue);
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;yield&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; initalValue;
        }
    }
}
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;
var client &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; WebClient();
var uri &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://www.bing.com/search?q=Rx+framework&amp;amp;first={0}&amp;amp;FORM=PERE3&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
var pageSize &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
var resultIndices &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; EnumerableExtensions.Iterate(&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, prev &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; prev &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; pageSize).Take(&lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
var pageDownloads &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    resultIndices
       .Select(
           resultIndex &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
               client
                   .GetDownloadString(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Uri(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Format(uri, resultIndex)))
                   &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; append the result index to the results so we can sort by it later&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                   .Select(html &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; { ResultIndex &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; resultIndex, Html &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; html }))
       &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Merge all of the observables into one so that we can subscribe to all of
       &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; them simultaneously.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;       .Aggregate(
           (simultaneousDownloads, currentDownload) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
               Observable.Merge(simultaneousDownloads, currentDownload));

var concatenatedHtml &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    pageDownloads
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Convert to a blocking enumerable.  It makes no sense for 
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; IObservable to have a GroupBy or OrderBy method because 
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; both these methods must block until all the data is received.
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; However all of the downloads will begin simultaneously when
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; we traverse the IEnumerable&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        .ToEnumerable()
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Order by the result index&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        .OrderBy(pageDownload &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; pageDownload.ResultIndex)
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Grab the HTML&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        .Select(pageDownload &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; pageDownload.Html)
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Concatenate the HTML strings&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        .Aggregate((accumulatedHtml, html) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; accumulatedHtml &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; html)
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Grab the first (and only) result.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        .First();&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Pretty slick right?&amp;#160; There's only one problem. &lt;strong&gt;This code doesn't work :-(.&lt;/strong&gt;&amp;#160; It will block forever.&amp;#160; The problem is that &lt;em&gt;the event-based asynchronous pattern always&lt;/em&gt; &lt;em&gt;returns on the thread it originates from and that thread is &lt;/em&gt;&lt;em&gt;blocked by the call to GetEnumerator()&lt;/em&gt;.&amp;#160; &lt;/p&gt;

&lt;p&gt;In the past returning on the UI thread was convenient because developers didn't have to worry about cross-thread accesses.&amp;#160; With Rx hopping threads is so easy that cross-thread access isn't much of a concern.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:c3a23f03-c868-47ba-b4fe-0278bbef3640" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;var uiContext &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SyncrhonizationContext.Current;
AsyncAction.Post(uiContext).Subscribe(() &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Debug.Write(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Now I'm back on the UI thread!&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;));

&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Unfortunately the fact that the event-based async pattern hops the the UI thread makes it much more difficult to compose a set of asynchronous operations together&lt;strong&gt; &lt;/strong&gt;and &lt;em&gt;block on the result&lt;/em&gt;.&amp;#160; This is why it's &lt;strong&gt;important to always provide a Begin/End Invoke version of your event-based, asynchronous API's.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;WebClient doesn't provide a Begin/End overload for DownloadStringAsync so to work around the blocking problem we'll have to create an non-blocking OrderBy method for IObservable.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:d3ed4d40-220d-471e-89eb-8f115142097a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ObservableExtensions
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; IObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; OrderBy&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T, R&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt; IObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; that, Func&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T, R&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; keySelector)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; AnonymousObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(
                observer &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                {
                    var orderBySubject &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; OrderBySubject&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T, R&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(keySelector);
                    var unsubscribe &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; orderBySubject.Subscribe(observer);
                    that.Subscribe(orderBySubject);

                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; unsubscribe;
                });
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; OrderBySubject&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T,R&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; : Subject&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; Func&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T,R&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; keySelector { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; OrderBySubject(Func&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T, R&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; keySelector)
            {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.keySelector &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; keySelector;
            }
            List&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; list &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; List&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;();
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnNext(T value)
            {
                list.Add(value);
            }
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnCompleted()
            {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (var item &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; list.OrderBy(keySelector))
                {
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;.OnNext(item);
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;.OnCompleted();
                }
            }
        }
    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Now we can rewrite the code above asynchronously.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:e7a683a8-ba08-4c99-b58c-e7b11a770966" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;var concatenatedHtml &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    pageDownloads
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Order by the result index&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        .OrderBy(pageDownload &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; pageDownload.ResultIndex)
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Grab the HTML&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        .Select(pageDownload &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; pageDownload.Html)
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Concatenate the HTML strings&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        .Aggregate((accumulatedHtml, html) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; accumulatedHtml &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; html)
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Write the first (and only) result.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        .Subscribe(html &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Debug.Write(html));&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Of course I could've avoided the blocking problem by using the WebRequest object because it has Begin/End methods.&amp;#160; However the point of this article was to show that although the event-based asynchronous pattern can be converted to an IObservable the &lt;a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html"&gt;abstraction leaks&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Think Ahead When Designing Asynchronous APIs&lt;/h4&gt;

&lt;p&gt;If Rx is embraced (which I expect it will be) existing event-based asynchronous APIs will be more cumbersome to work with than those written using the alternative Begin/End Invoke pattern.&amp;#160; I ask developers to consider this when designing asynchronous APIs today.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-3771217239287643503?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/3771217239287643503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=3771217239287643503' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/3771217239287643503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/3771217239287643503'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/07/developing-with-rx-part-2-converting.html' title='The Joy of Rx: The Event-based Async Pattern vs. IObservable'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-1653323045428908175</id><published>2009-07-30T01:45:00.001-07:00</published><updated>2009-08-25T16:14:59.044-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight Toolkit'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>The Joy of Rx: Extension Events</title><content type='html'>&lt;p&gt;Based on the logs it seems there is tremendous interest in &lt;a href="http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html"&gt;Rx&lt;/a&gt;, the new .NET 4.0 interfaces that allow you to query events and asynchronous operations.&amp;#160; I can't say I'm surprised.&amp;#160; In my opinion Rx is the big story of .NET 4.0.&amp;#160; I've been developing software using Rx for months now and I thought I'd share some tips and tricks that I've picked up with the community.&amp;#160; You can get the Sivlerlight version of Rx from the binaries folder in the &lt;a href="http://silverlight.codeplex.com/SourceControl/ListDownloadableCommits.aspx"&gt;Silverlight Toolkit sources&lt;/a&gt;.&lt;/p&gt;  &lt;h4&gt;Converting Events to IObservables&lt;/h4&gt;  &lt;p&gt;One of the cumbersome things about Rx development is that events must be converted to IObservable's before they can be queried.&amp;#160; Rx provides a static FromEvent method to help with the conversion:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:664b7326-31f0-437b-a7a4-1a2aac43f7c7" class="wlWriterSmartContent"&gt;   &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000"&gt;var mouseMove &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; Observable.FromEvent&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;MouseEventArgs&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;(Application.Current.RootVisual, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;MouseMover&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;);

mouseMove.Subscribe(() &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; Debug.WriteLine(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;the mouse has been moved.&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;);

&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Unfortunately putting event names (or any identifiers for that matter) in strings breaks our refactoring tools.&amp;#160; Rx &lt;em&gt;does&lt;/em&gt; provide another overload which accepts two actions, one that attaches the handler and another that detaches it...&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:cc936c51-e713-4491-8a51-19b692eb7d4d" class="wlWriterSmartContent"&gt;
  &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;&lt;span style="color: #000000"&gt; MyClass
{
   &lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt; EventHandler&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;RoutedEventArgs&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; MyEvent;
}

var myClass &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt; MyClass();
var myClassEvent &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; Observable.FromEvent&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;RoutedEventArgs&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;(handler &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; myClass.MyEvent &lt;/span&gt;&lt;span style="color: #000000"&gt;+=&lt;/span&gt;&lt;span style="color: #000000"&gt; handler, handler &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; myClass.MyEvent &lt;/span&gt;&lt;span style="color: #000000"&gt;-=&lt;/span&gt;&lt;span style="color: #000000"&gt; handler);
mouseMove.Subscribe(() &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; Debug.WriteLine(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;the mouse has been moved.&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;);

&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;...but not only is this overload rather more verbose, it only works if the delegate type of your event is the generic EventHandler&amp;lt;T&amp;gt;.&amp;#160; Unfortunately most events use custom delegate types because in .NET 1.0 generics did not exist.&amp;#160; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;**Updated:&amp;#160; There &lt;em&gt;is&lt;/em&gt; an overload which I missed that accepts the delegate type:&lt;/strong&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:f5a0b744-adae-4a7f-b113-40b2b6fc2676" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;var myButton &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Button();
var myButton &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Observable.FromEvent&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;RoutedEventHandler, RoutedEventArgs&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(handler &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; myClass.Click &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; handler, handler &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; myClass.Click &lt;/span&gt;&lt;span style="color: #000000;"&gt;-=&lt;/span&gt;&lt;span style="color: #000000;"&gt; handler);

&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;So what's the best way of exposing events as IObservables?&lt;/p&gt;

&lt;h4&gt;Extension Events&lt;/h4&gt;

&lt;p&gt;If you're doing Rx development in C# it's good practice to &lt;strong&gt;create extension methods for each event you would like to query&lt;/strong&gt;.&amp;#160; You can think of these methods as &lt;em&gt;extension events&lt;/em&gt;.&amp;#160; To demonstrate let's create a static class with extension methods that expose the events on Silverlight/WPF's UIElement class as IObservables.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:a8ecf757-54d7-4cfe-b8e7-e293ae868bd8" class="wlWriterSmartContent"&gt;
  &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;internal&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;&lt;span style="color: #000000"&gt; UIElementExtensions
    {
        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt;&lt;span style="color: #000000"&gt; IObservable&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;Event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;MouseButtonEventArgs&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; GetMouseLeftButtonDown(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt; UIElement that)
        {
            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt; Observable.FromEvent&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;MouseButtonEventArgs&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;(that, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;MouseLeftButtonDown&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;);
        }

        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt;&lt;span style="color: #000000"&gt; IObservable&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;Event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;MouseButtonEventArgs&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; GetMouseLeftButtonUp(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt; UIElement that)
        {
            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt; Observable.FromEvent&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;MouseButtonEventArgs&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;(that, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;MouseLeftButtonUp&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;);
        }

        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt;&lt;span style="color: #000000"&gt; IObservable&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;Event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;MouseEventArgs&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; GetMouseLeave(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt; UIElement that)
        {
            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt; Observable.FromEvent&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;MouseEventArgs&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;(that, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;MouseLeave&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;);
        }

        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt;&lt;span style="color: #000000"&gt; IObservable&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;Event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;MouseEventArgs&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; GetMouseEnter(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt; UIElement that)
        {
            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt; Observable.FromEvent&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;MouseEventArgs&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;(that, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;MouseEnter&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;);
        }
    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately our event names are stored in strings, but at least they are in one place.&amp;#160; Now that we've created extension methods that expose IObservables we can create more complex events by sequencing these primitive events.&lt;/p&gt;

&lt;h4&gt;Sequencing Events&lt;/h4&gt;

&lt;p&gt;The most exciting thing about Rx is that it enables you build complex events from a sequence of primitive events.&amp;#160; Let's create an observable that fires when the sequence of keys &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot; is pressed:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:a83d1a48-0920-4ae7-a532-5bc3ecff82d3" class="wlWriterSmartContent"&gt;
  &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; create an event that listens for key presses and returns the
&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; key pressed.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;IObservable&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;Key&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; keyPress &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; 
   Observable.FromEvent&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;KeyEventArgs&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;(Application.Current.RootVisual, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;KeyUp&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;)
      .Select(ev &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; ev.EventArgs.Key);

&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; Create a helper function for creating observables that fire
&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; when a specific key is pressed.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;Func&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;Key, IObservable&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;Key&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; pressedIs &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; 
   key &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; keyPress.Where(pressedKey &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; pressedKey &lt;/span&gt;&lt;span style="color: #000000"&gt;==&lt;/span&gt;&lt;span style="color: #000000"&gt; key);

&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; Create a helper function for creating observables that fire
&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; when a key other than a specific key is pressed.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;Func&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;Key, IObservable&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;Key&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; pressedIsNot &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; 
   key &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; keyPress.Where(pressedKey &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; pressedKey &lt;/span&gt;&lt;span style="color: #000000"&gt;!=&lt;/span&gt;&lt;span style="color: #000000"&gt; key);

IObservable&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;Unit&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; abcPressed &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;
   &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; Always listen for a key press &amp;quot;A&amp;quot; because it is the start of the sequence.  
   &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; Each time the &amp;quot;A&amp;quot; key is pressed we being matching  the sequence again.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;   from firstKeyPressEvent &lt;/span&gt;&lt;span style="color: #0000ff"&gt;in&lt;/span&gt;&lt;span style="color: #000000"&gt; pressedIs(Key.A)
   &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; After &amp;quot;A&amp;quot; is pressed when only want to wait for a single &amp;quot;B&amp;quot; key press.
   &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; If any other key is pressed we start at the beginning and wait for &amp;quot;A&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;   from secondKeyPressEvent &lt;/span&gt;&lt;span style="color: #0000ff"&gt;in&lt;/span&gt;&lt;span style="color: #000000"&gt; pressedIs(Key.B).Take(&lt;/span&gt;&lt;span style="color: #800080"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;).Until(pressedIsNot(Key.B))
   &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; After &amp;quot;B&amp;quot; is pressed when only want to wait for a single &amp;quot;C&amp;quot; key press.
   &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; If any other key is pressed we start at the beginning and wait for &amp;quot;A&amp;quot;&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;   from thirdKeyPressEvent &lt;/span&gt;&lt;span style="color: #0000ff"&gt;in&lt;/span&gt;&lt;span style="color: #000000"&gt; pressedIs(Key.C).Take(&lt;/span&gt;&lt;span style="color: #800080"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;).Until(pressedIsNot(Key.C))
   &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; I could return the string &amp;quot;abc&amp;quot; here but we know what exactly what keys    
   &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; were pressed because this event is so specific.  I really don't have anything
   &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; to return but all queries must return something.  In cases like this we return the 
   &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; Unit value.  It's like returning null, but it has a type and can't cause a null
   &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; reference exception.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;   select &lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt; Unit();

abcPressed.Subscribe(()&lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; Debug.WriteLine(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;ABC was pressed.&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;));
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Just as in Linq to Objects, multiple uses of the &amp;quot;from&amp;quot; keyword are translated into nested calls to the SelectMany extension method.&amp;#160; The abcPressed query above could also be coded this way:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:face1e0e-089b-46ff-aa11-503eb59ce4f4" class="wlWriterSmartContent"&gt;
  &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000"&gt;IObservable&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;Unit&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; abcPressed &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;
   pressedIs(Key.A)
      .SelectMany(
         firstKeyPressEvent &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; 
            pressedIs(Key.B).Take(&lt;/span&gt;&lt;span style="color: #800080"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;).Until(pressedIsNot(Key.B))
               .SelectMany(
                  secondKeyPressEvent &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; pressedIs(Key.C).Take(&lt;/span&gt;&lt;span style="color: #800080"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;).Until(pressedIsNot(Key.C))))
      .Select(_ &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt; Unit());
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;h4&gt;Building a &amp;quot;Click&amp;quot; Extension Event&lt;/h4&gt;

&lt;p&gt;Now that we know how to sequence events let's use Rx to add a &amp;quot;Click&amp;quot; extension event to all instances of UIElement - a class from which all Controls inherit.&amp;#160; The sequence of events that constitute a click event are a little more complex than one might think.&amp;#160; In a nutshell we consider a click event on UIElement &amp;quot;A&amp;quot; has occurred if we match this sequence of events...&lt;/p&gt;

&lt;p&gt;1.&amp;#160; MouseLeftButtonDown over UIElement &amp;quot;A&amp;quot;&lt;/p&gt;

&lt;p&gt;2.&amp;#160; MouseLeftButtonUp over UIElement &amp;quot;A&amp;quot;&lt;/p&gt;

&lt;p&gt;...or this sequence of events...&lt;/p&gt;

&lt;p&gt;1.&amp;#160; MouseLeftButtonDown over UIElement &amp;quot;A&amp;quot;&lt;/p&gt;

&lt;p&gt;2.&amp;#160; MouseLeave UIElement &amp;quot;A&amp;quot;&lt;/p&gt;

&lt;p&gt;3.&amp;#160; MouseEnter UIElement &amp;quot;A&amp;quot;&lt;/p&gt;

&lt;p&gt;4.&amp;#160; MouseLeftButtonUp over UIElement &amp;quot;A&amp;quot;&lt;/p&gt;

&lt;p&gt;...but &lt;strong&gt;&lt;u&gt;NOT&lt;/u&gt;&lt;/strong&gt; this sequence of events:&lt;/p&gt;

&lt;p&gt;1.&amp;#160; MouseLeftButtonDown over UIElement &amp;quot;A&amp;quot;&lt;/p&gt;

&lt;p&gt;2.&amp;#160; MouseLeave UIElement &amp;quot;A&amp;quot;&lt;/p&gt;

&lt;p&gt;3.&amp;#160; MouseEnter UIElement &amp;quot;B&amp;quot;&lt;/p&gt;

&lt;p&gt;3.&amp;#160; MouseLeftButtonUp over UIElement &amp;quot;B&amp;quot;&lt;/p&gt;

&lt;p&gt;3.&amp;#160; MouseLeftButtonDown over UIElement &amp;quot;B&amp;quot;&lt;/p&gt;

&lt;p&gt;2.&amp;#160; MouseLeave UIElement &amp;quot;B&amp;quot;&lt;/p&gt;

&lt;p&gt;3.&amp;#160; MouseEnter UIElement &amp;quot;A&amp;quot;&lt;/p&gt;

&lt;p&gt;4.&amp;#160; MouseLeftButtonUp over a UIElement &amp;quot;A&amp;quot;&lt;/p&gt;

&lt;p&gt;Let's add a GetClick extension event to the UIElementExtensions class we defined earlier.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:429342af-ada1-4737-8afe-c7e806080a42" class="wlWriterSmartContent"&gt;
  &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt;&lt;span style="color: #000000"&gt; IObservable&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;Event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;MouseButtonEventArgs&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; GetClick(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt; UIElement that)
{
    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;
        that
        &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; wait for any mouse left down event&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;            .GetMouseLeftButtonDown()
            .SelectMany(
                mouseLeftButtonDownEvent &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
                    &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; then wait for a single mouse left up event&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                    that
                        .GetMouseLeftButtonUp()
                        .Take(&lt;/span&gt;&lt;span style="color: #800080"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;)
                        .Until(
                            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; We want to merge two different stop conditions...&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                            Observable.Merge(
                                &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; stop listening if the mouse goes outside
                                &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; the silvleright plug-in&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                                Application.Current.RootVisual.GetMouseLeave()
                                    &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; We return unit so that we have the
                                    &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; same type as the other observable
                                    &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; we want to merge with&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                                    .Select(_ &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt; Unit()),
                                &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; stop listening if the mouse goes outside the
                                &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; element and the mouse is released.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                                that
                                    .GetMouseLeave()
                                    .SelectMany(
                                        mouseLeaveEvent &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
                                            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; stop waiting for a mouse left up event
                                            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; if the mouse leaves the element and the
                                            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; button is released.
                                            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; By listening for the event at the Root
                                            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; Visual we ensure that we will get all
                                            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; MouseLeftButtonUp events because this
                                            &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; event bubbles up.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                                            Application.Current.RootVisual
                                                .GetMouseLeftButtonUp()
                                                .Take(&lt;/span&gt;&lt;span style="color: #800080"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;)
                                                &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; Return unit so that we can merge&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                                                .Select(_ &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt; Unit())
                                                &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; don't cancel if the mouse enters
                                                &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; the element over which the mouse
                                                &lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt; was depressed.&lt;/span&gt;&lt;span style="color: #008000"&gt;
&lt;/span&gt;&lt;span style="color: #000000"&gt;                                                .Until(that.GetMouseEnter())))));
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;That's it!&amp;#160; Now every single instance of UIElement has a Click event we can subscribe to:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:d79b4e95-8e78-4688-a2a5-5057e88f586c" class="wlWriterSmartContent"&gt;
  &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000"&gt;var rectangle &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt; Rectangle { Width &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;100&lt;/span&gt;&lt;span style="color: #000000"&gt;, Height &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #800080"&gt;100&lt;/span&gt;&lt;span style="color: #000000"&gt;, Fill &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt; SolidColorBrush(Colors.Red) };

rectangle.GetClick().Subscribe(() &lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt; Debug.WriteLine(&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;The rectangle was clicked.&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;);
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;h4&gt;More Reliable Code, and Less of It&lt;/h4&gt;

&lt;p&gt;Rx allows you to write complex, asynchronous code declaratively.&amp;#160; If you master it you'll &lt;em&gt;never have to explicitly unhook a handler from an event again&lt;/em&gt;.&amp;#160; You also wont ever have to maintain an error-prone collection of state variables in order to ascertain whether a sequence of events has occurred in a particular order.&lt;/p&gt;

&lt;p&gt;*Edit: &lt;a href="http://cid-459b7369c1a390f3.skydrive.live.com/self.aspx/.Public/Unfold/ExtensionEvents.zip"&gt;Here's the code!&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-1653323045428908175?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/1653323045428908175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=1653323045428908175' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/1653323045428908175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/1653323045428908175'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/07/developing-with-rx-part-1-extension.html' title='The Joy of Rx: Extension Events'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-2494859081189279566</id><published>2009-07-22T14:01:00.001-07:00</published><updated>2009-07-30T12:01:18.103-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight Toolkit'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>Introducing Rx (Linq to Events)</title><content type='html'>&lt;p&gt;It’s the most wonderful time of the year: a new version of the &lt;a href="http://www.codeplex.com/Silverlight"&gt;Silverlight Toolkit&lt;/a&gt; has been released alongside Silverlight 3.&amp;#160; This release of the Toolkit has a lot of goodies including a new TreeMap control, a Rating control (written by yours truly), and a useful collection of extensions methods for TreeView.&amp;#160; That said this post is not really about the Toolkit.&amp;#160;&amp;#160; Buried deep in the bin folder of the Silverlight Toolkit Unit Tests is a hidden gem: &lt;strong&gt;The Rx Framework&lt;/strong&gt; (System.Reactive.dll).&amp;#160; If you glanced quickly you’d miss it altogether but it’s &lt;strong&gt;one of the most exciting additions to the .NET framework since Linq&lt;/strong&gt;.&lt;/p&gt;  &lt;h3&gt;Stating the Obvious: Asynchronous Programming is &lt;em&gt;Hard&lt;/em&gt;&lt;/h3&gt;  &lt;p&gt;Developers tend to avoid asynchronous programming if possible because it makes our programs non-deterministic and obscure our code’s intent in a sea of callbacks.&amp;#160; However the truth is that asynchronous programming has become an essential part of application development.&amp;#160; Client apps have always needed to use asynchronous methods to keep the user interface responsive.&amp;#160; As a matter of fact Silverlight developers don’t have any choice in the matter because Silverlight doesn’t include any blocking IO calls.&amp;#160; Connected apps also need to take advantage of asynchronous programming to improve scalability.&amp;#160; Mashups, apps cobbled together from web services, often need to retrieve data from multiple sources in a particular order.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Clearly we need to write asynchronous code to create modern, connected applications, but how to do it in such a way that our code remains clear and maintainable?&lt;/strong&gt;&lt;/p&gt;  &lt;h3&gt;Introducing the Rx Framework&lt;/h3&gt;  &lt;h4&gt;The IEnumerable Interface&lt;/h4&gt;  &lt;p&gt;We’re all familiar with the IEnumerable interface.&amp;#160; Almost every collection implements it and we use it every time we write a foreach.&amp;#160; Most of us are also pretty comfortable using Linq to query IEnumerables.&amp;#160; Linq is a series of extension methods used to manipulate sequences.&amp;#160; Here’s a simple example:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:34f43f4b-cc37-44cd-adb6-b08f5721e6d5" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] numbers &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]{&lt;/span&gt;&lt;span style="color: #800080;"&gt;20&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;31&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;16&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;22&lt;/span&gt;&lt;span style="color: #000000;"&gt;};
IEnumerable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; numbersSmallerThan20 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; numbers.Where(number &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; number &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;20&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;The resulting &lt;font face="courier new"&gt;numbersSmallerThan20&lt;/font&gt; sequence looks like this when visualized:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;5, 16, &lt;b&gt;break&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;In addition to finite sequences it can sometimes be useful to create sequences that never end.&amp;#160; Take this method that returns an infinite sequence of integers:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:dd351134-56f1-492d-afd7-7ebe11f311db" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;IEnumerable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; NaturalNumbers()
{
     &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; number &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
     &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;yield&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; number;
        number&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
    }
}&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;When visualized this sequence looks like this:&lt;/p&gt;

&lt;p&gt;&lt;font face="courier new"&gt;0,1,2,3,4,5,6…&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Enumerable’s are sequences of data that we &lt;i&gt;pull&lt;/i&gt; from a data source.&amp;#160; We don’t always pull data though.&amp;#160; Often it is &lt;i&gt;pushed&lt;/i&gt; onto us and we must react appropriately.&amp;#160; This is called “Reactive Programming.”&lt;/p&gt;

&lt;h4&gt;&lt;b&gt;Reactive Programming&lt;/b&gt;&lt;/h4&gt;

&lt;p&gt;Reactive programs are ubiquitous.&amp;#160; We use reactive programming every time we register a handler with an event or a specify a call back for an asynchronous operation.&amp;#160; In this example I register a handler for the mouse move event of a button.&amp;#160; The handler prints out the location of the mouse when it is called.&lt;/p&gt;

&lt;p&gt;&amp;#160; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:abc005c8-cdc5-4627-9e37-0209f4c6d675" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;button.MouseMove &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; (o, mouseEventArgs) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Debug.Writeline(“You moved the mouse to {&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;}”, mouseEventArgs.GetPosition(button));


&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
Every time the mouse event is fired our callback method is invoked and we are passed some information about the event.&amp;#160; &lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;“You moved the mouse to 20,3”&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;“You moved the mouse to 33,12”&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;“You moved the mouse to 44,18”&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Another form of reactive programming is running an asynchronous method and passing it a callback method to invoke when it’s finished.&amp;#160; This is how we keep our programs responsive during long-running operations.&amp;#160; Here’s an example: &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:df04e7a0-b560-49c5-9f4f-6beaa3353e3e" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;DownloadFile(“http:&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;www.jeffwilcox.com”, (byteArray) =&amp;gt; Debug.WriteLine(“This file is {0} bytes long.”, byteArray.Length);&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
When this method finishes downloading a file it passes the data to our callback function giving us the following result: 

&lt;p&gt;&lt;font face="Courier New"&gt;“This file is 12323 bytes long.”&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;We’re all used to doing reactive programming by specifying methods that are called at unpredictable times, &lt;b&gt;but what if there was a different way to think about reactive programming?&lt;/b&gt;&amp;#160; What if we thought of each piece of data passed to a reactively-called method &lt;b&gt;as an item in a&lt;/b&gt; &lt;b&gt;sequence&lt;/b&gt;?&lt;/p&gt;

&lt;h4&gt;&lt;b&gt;Events and Callbacks are Sequences of Data!&lt;/b&gt;&lt;/h4&gt;

&lt;p&gt;The data passed to event handlers and callbacks can be thought of as sequences of data that are “pushed” at you rather than “pulled.”&amp;#160; Every time an event is fired we get “pushed” a new piece of data: the EventArgs.&amp;#160; Similarly when a callback is invoked it is typically “pushed” the result of the asynchronous method.&amp;#160; You can think of an event as a sequence of EventArgs that never ends just like the NaturalNumbers sequence.&amp;#160; If you were to visualize the mouse move event as a sequence it would look like this:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:eeb23147-17f7-4bb2-a31f-036c9d85751d" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MouseEventArgs(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Point(&lt;/span&gt;&lt;span style="color: #800080;"&gt;20&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;)), &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MouseEventArgs(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Point(&lt;/span&gt;&lt;span style="color: #800080;"&gt;33&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;12&lt;/span&gt;&lt;span style="color: #000000;"&gt;)), &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MouseEventArgs(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Point(&lt;/span&gt;&lt;span style="color: #800080;"&gt;44&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;18&lt;/span&gt;&lt;span style="color: #000000;"&gt;))…

&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Similarly the asynchronous DownloadFile method can be viewed as a “push” sequence of data with only one entry:&lt;/p&gt;

&lt;p&gt;&lt;font face="courier new"&gt;new byte[]{23,211,33,23…}, &lt;b&gt;break&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;The Rx team has discovered that pull sequences and push sequences are “dual.”&amp;#160; That is to say, &lt;b&gt;any operation you can perform on “pull” sequences can also be performed on “push” sequences&lt;/b&gt;.&amp;#160; This is quite a revelation.&amp;#160; To put things in perspective it’s been 13 years since &lt;a href="http://en.wikipedia.org/wiki/Gang_of_Four_(software)"&gt;&lt;b&gt;Design Patterns&lt;/b&gt;&lt;/a&gt; was published and we’ve only now realized that the Observable pattern and the Iterator pattern are actually &lt;i&gt;the same pattern&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;Although reactive “push” sequences are fundamentally the same as “pull” sequences the IEnumerable interface can’t be used for reactive sequences because it blocks.&amp;#160; We need a new interface with non-blocking methods that correspond exactly to the blocking methods on IEnumerable.&amp;#160; We need…&lt;/p&gt;

&lt;h3&gt;&lt;b&gt;The IObservable/IObserver Interface&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;Despite the fact that they may look somewhat different on the surface the IObservable/IObserver pair of interfaces are the &lt;b&gt;non-blocking equivalents of &lt;/b&gt;IEnumerable/IEnumerator.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_HI1qT6wpc4w/Smd-H6H2hPI/AAAAAAAAANM/2SWhXby_Hk8/s1600-h/clip_image001%5B3%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://lh5.ggpht.com/_HI1qT6wpc4w/Smd-IFlBP4I/AAAAAAAAANQ/FSWGvCoILpk/clip_image001_thumb.jpg?imgmax=800" width="244" height="75" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To help you understand how they are equivalent let’s take a look at a simple example of traversing a pull sequence.&amp;#160; You enumerate an IEnumerable by requesting an IEnumerator.&amp;#160; As you call MoveNext the IEnumerator “pulls” data from the IEnumerable, usually by invoking its methods.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:284ea05d-8071-4f4b-b6dc-284c69b01010" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;IEnumerator&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; numberEnumerator &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]{&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;};
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt;(numberEnumerator.MoveNext())
{
     Debug.WriteLine(“{&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;}”, numberEnumerator.Current);
}

Debug.WriteLine(“all done.”);&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;This prints:&lt;/p&gt;

&lt;p&gt;&lt;font face="courier new"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:3797659d-b9f3-4185-b21e-de65d08cfa00" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;
all done.&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;To traverse an IObservable you go through the same actions as an IEnumerable but &lt;i&gt;in reverse&lt;/i&gt;.&amp;#160; You create an IObserver, give it to an IObservable, and the IObservable “pushes” data into the IObserver by invoking its methods.&amp;#160; When an IObservable invokes the “OnNext” method on an Observer it is equivalent to an IEnumerable method using the yield keyword to give information to an IEnumerable.&amp;#160; Similarly when an IObservable invokes the “OnCompleted” method on an Observer it is equivalent to an IEnumerable using the break keyword to indicate that there is no more data.&lt;/p&gt;

&lt;p&gt;Let’s define a NumbersObserver which converts a “pull” sequence of numbers into a “push” sequence as well as an observer that listens to our NumbersObserver and prints its contents.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:7f8c54ea-779f-43bf-8b90-5d8d2b3b1b84" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;internal&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; AnonymousDisposable : IDisposable
{

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;internal&lt;/span&gt;&lt;span style="color: #000000;"&gt; Action Action {&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;internal&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;;}

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; IDisposable.Dispose()
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Action();
    }
}

&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; NumbersObservable : IObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; NumbersObservable(IEnumerable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; numbers)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;._numbers &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; numbers;
    }

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; IEnumerable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; _numbers;

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; IDisposable Subscribe(IObserver&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; observer)
    {
         &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; number &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; _numbers)
        {
             observer.OnNext(number);
        }
        observer.OnCompleted();

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; AnonymousDisposable { Action &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; () &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; { ; &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; do nothing because we’ve already called OnCompleted() } }; &lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    }
}

&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; DebugObserver : IObserver&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnNext(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; value)
    {
        Debug.WriteLine(“{&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;}”, value);
    }

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnCompleted()
    {
        Debug.WriteLine(“all done.”);
    }

    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnError(Exception ex)
    {
        Debug.WriteLine(“Whoops exception, I’d better &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;throw&lt;/span&gt;&lt;span style="color: #000000;"&gt;.”)
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;throw&lt;/span&gt;&lt;span style="color: #000000;"&gt; ex;
    }
}&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Now let’s use these classes to create a “push” version of our “pull” example:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:d94d6d38-f621-44a3-b9dc-ba0e4ea676e8" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; NumbersObservable(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]{&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&lt;span style="color: #000000;"&gt;}).Register(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DebugObserver());&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;This prints…&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:84aad1c7-ca6b-4d82-b485-5fa3d208953d" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;
all done.&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;b&gt;“Whoa, whoa!&amp;#160; Isn’t this pretty complicated?”&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Don’t worry.&amp;#160; This example above is just to demonstrate the interplay between the interfaces.&amp;#160; Most of the time you won’t have to implement your own Observable or Observer.&amp;#160; Rx includes lots of methods for constructing observables and observers.&amp;#160; Using Rx extension methods I can rewrite the code above like so:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:a8c95b6c-1167-45b3-8f75-b23918fccc40" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]{&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;}.ToObservable().Subscribe(number &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Debug.WriteLine(“{&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;}”, number));&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;b&gt;“What’s with the IDisposable object?”&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;The IDisposable object is returned by an Observable when you register an observer with it.&amp;#160; When you invoke the&lt;b&gt;&lt;i&gt; &lt;/i&gt;&lt;/b&gt;Dispose method on the registration object the observer will stop listening to the observable for data.&amp;#160; This is the &lt;i&gt;active&lt;/i&gt; equivalent of &lt;i&gt;passive&lt;/i&gt;ly not calling MoveNext() anymore in the middle of a sequence.&amp;#160; Rather than invoke the Dispose method directly you will most often have it invoked for you by Rx.&amp;#160; In the following example the TakeWhile method will invoke Dispose under the hood to detach from an observable as soon as a number larger than 10 is returned.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:047ff246-d787-4c03-a1b1-95dcc5782276" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;var numbersSmallerThanTen &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Enumerable.Range(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;100&lt;/span&gt;&lt;span style="color: #000000;"&gt;).ToObservable().TakeWhile(x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Here’s an example of invoking Dispose explicitly to detach from an event which has been converted to an Observable:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:ce52c0fb-3a6c-42f0-9f79-6c7808f93fe4" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Use an Rx method to convert an event to an Observable&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;IObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Event&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MouseEventArgs&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; mouseMoveEventObservable &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Observable.FromEvent&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MouseEventArgs&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(myControl, “MouseMove”);

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; register a handler with the event using an overload that accepts a lambda instead of an Observer&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;IDisposable registration &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; mouseMoveEventObservable.Subscribe(mouseMoveEvent &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Debug.Write(“The mouse was moved.”));

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; stop listening to the event&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;registration.Dispose();

&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;b&gt;“What about the OnError method?&amp;#160; I don’t see an equivalent for that in IEnumerable or IEnumerator either.”&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;When errors occur in asynchronous operations the exception must be passed to the callback method so that the callback method can handle it.&amp;#160; That’s why this method exists in IObservable but seems to have no equivalent in IEnumerable.&amp;#160; In IEnumerable it is implicit because you can use try/catch.&lt;/p&gt;

&lt;h3&gt;Linq to IObservable&lt;/h3&gt;

&lt;p&gt;Now that we understand that an IObservable is just a “push” version of IEnumerable it just be obvious that &lt;b&gt;all of the familiar Linq methods apply to it&lt;/b&gt;.&amp;#160; In fact it is &lt;b&gt;equally appropriate to use query syntax on “pull” sequences and “push” sequences&lt;/b&gt;.&amp;#160; Both &lt;i&gt;are&lt;/i&gt; queries in the strictest sense and the fact that a sequence is push or pull is orthogonal.&amp;#160; Let’s analyze a typical Linq query:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:b1cb56e3-d2e4-443e-87b1-d533f6643e9e" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;IEnumerable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Point&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; points &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
     from x &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; Enumerable.Range(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
     from y &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; Enumerable.Range(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
     select &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Point(x,y);&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;A verbal description of this query might be:&lt;/p&gt;

&lt;p&gt;“For each x in the sequence [0 to 1] get each y in the sequence [0 to 1] and create a new point for each pair of values.”&lt;/p&gt;

&lt;p&gt;The result of course is:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:1aa8602e-e5ec-463f-9615-f2691baccfaa" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Now let’s contrast this with an Rx query that creates a dragging event for a Silverlight/WPF control:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:71807b5a-e543-4aa2-9b74-c6b23da8dcc0" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;IObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Event&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MouseEventArgs&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; draggingEvent &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
     from mouseLeftDownEvent &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; control.GetMouseLeftDown()
     from mouseMoveEvent &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; control.GetMouseMove().Until(control.GetMouseLeftUp())
     select mouseMoveEvent;&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;A verbal description of this query might be:&lt;/p&gt;

&lt;p&gt;“For each mouse left down event, get each mouse move event and return it until the next mouse left up event occurs.”&lt;/p&gt;

&lt;p&gt;As you can see, using &lt;strong&gt;“&lt;/strong&gt;from” allows us to &lt;strong&gt;declaratively sequence events&lt;/strong&gt;.&amp;#160; The alternative would be to create a state machine, setting a flag when the mouse button is pressed and then behaving differently when the mouse is moved and that flag is set.&amp;#160; With Rx the code for the drag event is self-contained and involves no variable mutation.&lt;/p&gt;

&lt;p&gt;With Linq to IEnumerable we transform and combine sequences of data to create a sequence containing exactly the data we need.&amp;#160; Then we traverse that sequence and do something with the data.&amp;#160; &lt;strong&gt;With&amp;#160; Linq to IObservable we can transform and combine events and async callbacks to create the precise event we’re interested in.&amp;#160; Then we register a handler and do something with the data.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;&lt;b&gt;Silverlight Toolkit Unit Test Code Written with Rx&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;The Silverlight Toolkit team is using Rx to write reliable, event-based asynchronous tests.&amp;#160; This is essential as the elements in a control’s visual tree are created asynchronously, forcing us to wait for an event in order to confirm they were created appropriately. Let’s take a look at a test for&lt;b&gt;&lt;i&gt; &lt;/i&gt;&lt;/b&gt;Rating&lt;strong&gt;&lt;em&gt; &lt;/em&gt;&lt;/strong&gt;that uses Rx.&lt;/p&gt;

&lt;p&gt;This test ensures that the Actual Value of a RatingItem is %100 when its parent Rating is %100.&amp;#160; This is tricky because when you change the value of rating it animates to the new value using an internal storyboard.&amp;#160; I have to wait for ActualValue to be animated to the Value property before I examine the RatingItem.&lt;/p&gt;

&lt;p&gt;The test creates a Rating control, places it on screen, and waits for LayoutUpdated to ensure that the rating items are generated.&amp;#160; Then it asynchronously sets the value of rating to 1.0.&amp;#160; As the ActualValue of the Rating changes, the various RatingItems will have their ActualValue’s set accordingly depending on their index.&amp;#160; The test needs to wait until the Rating’s ActualValue reaches Value before checking to make sure the ActualValue of the last rating item is 1.0.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:4ee26b79-dcd2-467f-9425-4588f2665978" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;Rating rating &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Rating();
IObservable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Unit&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; test &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;                             &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Unit is an object that represents null.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    ObservableExtensions
        .DoAsync(() &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; TestPanel.Children.Add(rating))
        .WaitFor(TestPanel.GetLayoutUpdated())     &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Extension method GetLayoutUpdated converts the event to observable&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        .DoAsync(() &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; rating.Value &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Calls the Ignite EnqueueCallback method&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        .WaitFor(                                 &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; waits for an observable to raise before going on
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; listen to all the actual value change events and filters them until ActualValue reaches Value&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;            rating                          
            .GetActualValueChanged()        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; extension method that converts ActualValueChanged event to IObservable&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;            .SkipWhile(actualValueChangedEvent &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; actualValueChangedEvent.EventArgs.NewValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; rating.Value))
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; check to make sure the actual value of the rating item is set appropriately now that the animation has completed&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        .Assert(() &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; rating.GetRatingItems().Last().ActualValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; crawls the expression tree and makes a call to the appropriate Assert method&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;
Test.Subscribe(() &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; TestPanel.Children.Remove(rating));    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;run the test and clean up at the end.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;The code above uses a variety of extension methods we built to manipulate observable objects.&amp;#160; You can use these libraries in your own unit tests by downloading the Silverlight Toolkit sources.&lt;/p&gt;

&lt;h3&gt;&lt;s&gt;&lt;u&gt;Always&lt;/u&gt;&lt;/s&gt; Us&lt;strike&gt;e&lt;/strike&gt;&lt;font color="#0000ff"&gt;ing&lt;/font&gt; IObservable for New Asynchronous APIs&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The IObservable/IObserver interfaces are in .NET framework 4.0&lt;/strong&gt;.&amp;#160; &lt;s&gt;I want to stress that IObservable is the new asynchronous programming pattern in .NET.&lt;/s&gt; &lt;s&gt;It supplants the Begin/EndInvoke pattern as well as the event-based asynchronous pattern&lt;/s&gt;.&amp;#160; &lt;s&gt;Simple run of thumb: &lt;strong&gt;if the method is asynchronous, return an IObservable.&lt;/strong&gt;&lt;/s&gt;&lt;strong&gt; *&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;*A correction here.&amp;#160; It is still perfectly acceptable to use Begin/End Invoke or the event-based asynchronous pattern.&amp;#160; Large portions of the framework use these patterns and will continue to do so for the sake of consistency.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Exposing IObservable is like putting lighting in a bottle.&amp;#160; Developers can open it up and get access to a galaxy of Linq methods they can use to combine and sequence them with other IObservables.&amp;#160; My hope is that eventually API’s exposing IObservable will be just as common as those exposing IEnumerable.&lt;/p&gt;

&lt;h3&gt;Erik Meijer Strikes Again&lt;/h3&gt;

&lt;p&gt;Rx is the brainchild of Erik Meijer, the father of Linq and recent recipient of the Outstanding Technical Leadership award at Microsoft.&amp;#160; Erik is the reason I chose to work for Microsoft.&amp;#160; With the introduction of Rx and his work on Linq and Haskell he has profoundly changed the way I approach software development &lt;em&gt;twice &lt;/em&gt;in four years – an incredible feat.&amp;#160; Thanks to Meijer, Microsoft does a better job than anyone of taking bleeding-edge functional programming research and productizing it.&amp;#160; The Rx team also includes my favorite blogger, &lt;a href="http://blogs.msdn.com/wesdyer/default.aspx"&gt;Wes Dyer&lt;/a&gt; whose blog posts opened my eyes to what an incredibly versatile language C# is.&lt;/p&gt;

&lt;p&gt;After using it for the last few months it’s now impossible to imagine doing Silverlight development without Rx.&amp;#160; As of today the only place you can get it is in the &lt;a href="http://silverlight.codeplex.com/SourceControl/ListDownloadableCommits.aspx"&gt;Silverlight Toolkit sources&lt;/a&gt;.&amp;#160; Take a look.&amp;#160; If you are comfortable with Linq programming you’ll find it to be extremely powerful.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-2494859081189279566?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/2494859081189279566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=2494859081189279566' title='47 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/2494859081189279566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/2494859081189279566'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html' title='Introducing Rx (Linq to Events)'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_HI1qT6wpc4w/Smd-IFlBP4I/AAAAAAAAANQ/FSWGvCoILpk/s72-c/clip_image001_thumb.jpg?imgmax=800' height='72' width='72'/><thr:total>47</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-36810349278487090</id><published>2009-07-09T22:42:00.001-07:00</published><updated>2009-07-10T10:37:18.173-07:00</updated><title type='text'>Introducing the Rating Control</title><content type='html'>&lt;p&gt;Boys and girls, its the most wonderful time of the year: a new version of Silverlight is shipping.&amp;#160; Silverlight 3 shipped today along with a refresh of the Silverlight Toolkit.&amp;#160; For this release I had the pleasure of writing the Rating control which is available in both the Silverlight 2 and 3 versions of the Toolkit.&amp;#160; In this post I'll give you a high level overview of how Rating works and how you can customize it.&lt;/p&gt;  &lt;h4&gt;Using Rating&lt;/h4&gt;  &lt;p&gt;The Rating control is located in the System.Windows.Controls namespace in System.Windows.Controls.Input.Toolkit.dll.&amp;#160; Once you've added a XAML namespace you can create a Rating like this...&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:fe0306b5-19ef-4346-81c7-403a92232edc" class="wlWriterSmartContent"&gt;   &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;inputToolkit:Rating &lt;/span&gt;&lt;span style="color: #ff0000"&gt;ItemCount&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;5&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;This will create a Rating control with five stars:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_HI1qT6wpc4w/Sld8QENa2cI/AAAAAAAAAMU/zo5cv25JWQQ/s1600-h/rating2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="rating" border="0" alt="rating" src="http://lh6.ggpht.com/_HI1qT6wpc4w/Sld8QbARrtI/AAAAAAAAAMY/XCuCnuUX_nE/rating_thumb.png?imgmax=800" width="108" height="28" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h4&gt;Giving Rating a Value&lt;/h4&gt;

&lt;p&gt;The Rating control has a Value property which is a ratio from 0 to 1.&amp;#160; The Value property is a nullable double.&amp;#160; In other words the Value property is either between 0% and 100% or it is null.&lt;/p&gt;

&lt;p&gt;The Rating control has two selection modes: Continuous and Individual.&amp;#160; In Continuous mode (the default) the control behaves the way most star-based Rating controls do: filling the first two stars and half of the middle one. &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:0f71e717-9a0d-4a48-b8e3-631f397f2e0b" class="wlWriterSmartContent"&gt;
  &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;inputToolkit:Rating &lt;/span&gt;&lt;span style="color: #ff0000"&gt;ItemCount&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;5&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;0.5&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt; SelectionMode&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Continuous&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_HI1qT6wpc4w/Sld8QiR7p-I/AAAAAAAAAMc/75Q53vqzyCU/s1600-h/continuous2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="continuous" border="0" alt="continuous" src="http://lh5.ggpht.com/_HI1qT6wpc4w/Sld8QyaKjrI/AAAAAAAAAMg/ff8uiUrsoZo/continuous_thumb.png?imgmax=800" width="108" height="27" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;However in individual mode, the stars leading up to the middle star are not filled:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:bf65cc55-7747-427a-a513-74cb829f3053" class="wlWriterSmartContent"&gt;
  &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;inputToolkit:Rating &lt;/span&gt;&lt;span style="color: #ff0000"&gt;ItemCount&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;5&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;0.5&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt; SelectionMode&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Individual&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_HI1qT6wpc4w/Sld8Rcfg9zI/AAAAAAAAAMk/xfZRqu_-PPw/s1600-h/individual2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="individual" border="0" alt="individual" src="http://lh4.ggpht.com/_HI1qT6wpc4w/Sld8Rgh2CeI/AAAAAAAAAMo/4vA9fC-sFc0/individual_thumb.png?imgmax=800" width="108" height="28" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Individual mode is useful when you want to offer discrete selection options:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_HI1qT6wpc4w/Sld8R6m9f5I/AAAAAAAAAMs/Js4cdr8c8so/s1600-h/individualcustom2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="individualcustom" border="0" alt="individualcustom" src="http://lh5.ggpht.com/_HI1qT6wpc4w/Sld8SM-9bKI/AAAAAAAAAMw/RvAVCXGfC8s/individualcustom_thumb.png?imgmax=800" width="244" height="65" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h4&gt;Adding Rating Items&lt;/h4&gt;

&lt;p&gt;Rating is an ItemsControl with an ItemCount convenience property which adds instances of RatingItem to the Items collection.&amp;#160; Therefore this...&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:d38b84e4-fabd-46cd-ba64-291ad059232b" class="wlWriterSmartContent"&gt;
  &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;inputToolkit:Rating &lt;/span&gt;&lt;span style="color: #ff0000"&gt;ItemCount&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;5&amp;quot;&lt;/span&gt;&lt;span style="color: #ff0000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;...is equivalent to this...&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:88f57c10-4a4f-4517-ae6b-3f3ac5a62f5d" class="wlWriterSmartContent"&gt;
  &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;inputToolkit:Rating&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
   &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;inputToolkit:Rating.Items&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;inputToolkit:RatingItem &lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;inputToolkit:RatingItem &lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;inputToolkit:RatingItem &lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;inputToolkit:RatingItem &lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;inputToolkit:RatingItem &lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
   &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;inputToolkit:Rating.Items&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;
&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;inputToolkit:Rating&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;...and this:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:1a86df5d-6fde-4833-96d6-1a7e0987032b" class="wlWriterSmartContent"&gt;
  &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000"&gt;var rating &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt; Rating { ItemsSource &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;[]{&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;} };&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;ItemCount is convenient if you don't need to bind your rating items to an underlying data source or otherwise vary their appearance.&amp;#160; However since RatingItems &lt;em&gt;are&lt;/em&gt; content controls if you do bind to a data source your data will be displayed below the RatingItem.&amp;#160; &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:f4bc110e-53fc-4a4f-8a81-dfad1658ce48" class="wlWriterSmartContent"&gt;
  &lt;pre style="background-color: white; overflow: auto"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000"&gt;var rating &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt; Rating { SelectionMode &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; RatingSelectionMode.Individual, ItemsSource &lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;[]{&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Hate&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Bored&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Good&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Great&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;, &lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000"&gt;Love&lt;/span&gt;&lt;span style="color: #800000"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000"&gt;} };&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;h4&gt;The Template&lt;/h4&gt;

&lt;p&gt;The Rating ItemsControl uses instances of the RatingItem class as its item container.&amp;#160; RatingItem inherits from ContentControl and its template contains an instance of the LinearClipper control.&amp;#160; The LinearClipper control is used to hide a portion of the star in the RatingItem template.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_HI1qT6wpc4w/SlbUyuKs-oI/AAAAAAAAAMM/NEZBaILhcpM/s1600-h/ratingtemplate%5B5%5D.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="ratingtemplate" src="http://lh4.ggpht.com/_HI1qT6wpc4w/SlbUzzwafCI/AAAAAAAAAMQ/1YWLh53RHKI/ratingtemplate_thumb%5B1%5D.png?imgmax=800" width="244" height="148" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;In addition to the common visual states the RatingItem control has a &amp;quot;Fill States&amp;quot; visual state group which contains the following states: &amp;quot;Empty&amp;quot;, &amp;quot;Partial&amp;quot;, and &amp;quot;Filled.&amp;quot;&lt;/p&gt;

&lt;p&gt;The LinearClipper has a property ExpandDirection which can be used to determine whether it expands Up, Down, Left, or Right.&amp;#160; By changing this property along with the ItemPanelTemplate property of Rating you can customize Rating to display and reveal stars vertically.&lt;/p&gt;

&lt;p&gt;As Rating is an ItemsControl all the tricks you already know to customize an ItemsControl's appearance apply.&amp;#160; I won't rehash how to style an ItemsControl here, there's plenty of information on &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.aspx"&gt;MSDN&lt;/a&gt;.&amp;#160; For comprehensive examples of re-templated Rating controls you can take a look at the Rating sample page in &lt;a href="http://www.codeplex.com/Silverlight"&gt;Silverlight Toolkit samples&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Rate Rating&lt;/h4&gt;

&lt;p&gt;Rating is being released under the &amp;quot;Preview&amp;quot; quality band.&amp;#160; That means we're looking for feedback on ways in which we can improve it.&amp;#160; Try it out and let us know what you think on the CodePlex forums.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-36810349278487090?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/36810349278487090/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=36810349278487090' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/36810349278487090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/36810349278487090'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/07/introducing-rating-control.html' title='Introducing the Rating Control'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_HI1qT6wpc4w/Sld8QbARrtI/AAAAAAAAAMY/XCuCnuUX_nE/s72-c/rating_thumb.png?imgmax=800' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-5272975444026336673</id><published>2009-06-02T12:54:00.001-07:00</published><updated>2009-06-02T12:54:25.234-07:00</updated><title type='text'>Better Unit Tests with Test.Assert() for NUnit/VSTT/SUTF</title><content type='html'>&lt;p&gt;It’s been over ten years since Kent Beck created &lt;a href="http://sunit.sourceforge.net/"&gt;SUnit&lt;/a&gt;, the first unit testing framework for SmallTalk.&amp;#160; Since then, hundreds of unit testing frameworks have been created in its image, one for nearly every platform and programming language.&amp;#160; &lt;a href="http://www.junit.org/"&gt;JUnit&lt;/a&gt;, the open-source Java unit testing framework, begat &lt;a href="http://www.nunit.org/index.php"&gt;NUnit&lt;/a&gt;, the popular .NET port, which inspired &lt;a href="http://msdn.microsoft.com/en-us/library/ms379625(VS.80).aspx"&gt;Visual Studio Team Test&lt;/a&gt;, which was ported to the &lt;a href="http://code.msdn.microsoft.com/silverlightut/"&gt;Silverlight Unit Testing Framework&lt;/a&gt;, and it was good.&amp;#160; &lt;/p&gt;  &lt;p&gt;For the most part NUnit’s and VSTT’s API’s are the same as those of JUnit. This is probably a good thing because it makes it much easier for Java developers to adopt .NET.&amp;#160; It was also a natural decision given how similar C# and Java were when NUnit was created. However .NET programming languages have evolved rapidly in the last few years.&amp;#160; &lt;strong&gt;Have you ever stopped to wonder whether the API’s for the .NET unit testing frameworks should &lt;em&gt;still&lt;/em&gt; be so similar to those of JUnit?&lt;/strong&gt;&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;Nowadays C# and VB.NET are capable of some very powerful code transformations.&amp;#160; Despite the fact that .NET developers are conditioned to think of API’s and programming languages as separate the reality is not so simple.&amp;#160; The capabilities of programming languages tend to influence the design of API’s. The question is this: &lt;strong&gt;Can we use the advanced features of .NET programming languages to create better unit testing API’s?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;“What’s wrong with Unit Testing API’s?&amp;#160; They’re pretty straightforward.”&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;There are three things wrong with the assertion API’s used by the major unit testing frameworks:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1.&amp;#160; You Can’t Use Expressions&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Let’s take a look at a typical Visual Studio Team Test.&lt;/p&gt;  &lt;p&gt;   &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:52527f2a-e898-4ec4-80f4-891dbdc9affb" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:White;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;[TestMethod]
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; TestStackIsEmptyWhenCreated()
{
    Stack emptyStack &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Stack();
    Assert.AreEqual(emptyStack.Count, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Stack is not empty.&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
}&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Ask yourself this question: Is the AreEqual method &lt;em&gt;really&lt;/em&gt; necessary?&amp;#160; Our programming languages already have a rich set of comparison operators.&amp;#160; Most of us are accustomed to writing debug assertions this way:&lt;/p&gt;

&lt;p&gt;
  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:feacec12-741d-4105-b3b2-6700acff6847" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:White;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;Debug.Assert(emptyStack.Count &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Stack is not empty.&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Operators make common operations more recognizable to the human eye&lt;/strong&gt;. If comparison operators are easier to read than the Assert methods why do we use the latter in our unit tests?&amp;#160; &lt;/p&gt;

&lt;p&gt;The reason is that &lt;strong&gt;we want&lt;/strong&gt; &lt;strong&gt;descriptive failure messages&lt;/strong&gt; in the event our test fails. If we fail the test above by adding an item to the stack we get a failure message much like this:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;TestStackIsEmptyWhenCreated failed.&amp;#160; Values are not equal. Expected 0, got 1. Stack is not empty.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice that in addition to including what type of comparison operation that failed the framework also provides the values being tested.&amp;#160; If we were to specify an expression (as in the Debug.Assert example above) it would get compiled into executable code and by the time the UT framework got our expression it would be a black box.&amp;#160; As a result it would be impossible to determine what kind of comparison we were attempting or the values of the arguments.&amp;#160; Therefore Assert methods are necessary, despite the fact that they are ugly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.&amp;#160; Assert.AreEqual vs. Assert.AreSame&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another problem caused by the inability to use expressions is that we must be explicit about whether we want to use value or reference comparisons.&amp;#160; Have you ever used Assert.AreEqual when you should’ve used Assert.AreSame or vice versa?&amp;#160; In some circumstances this can lead to false positives or negatives.&amp;#160; It is especially annoying for C# and F# developers as &lt;strong&gt;we are used to our compilers choosing the appropriate comparison type for us&lt;/strong&gt; based on context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.&amp;#160; Redundant Assertion Messages&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is generally considered good practice to add a custom assertion message to provide more context in the event a test fails.&amp;#160; This is especially important if a test makes multiple calls to the same Assert method.&amp;#160; Let’s say we left the assertion message out of our unit test:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:6bbed16f-93a0-4b09-91b7-88268b54b397" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:White;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;[TestMethod]
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; TestStackIsEmptyWhenCreated()
{
    Stack emptyStack &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Stack();
    Assert.AreEqual(emptyStack.Count, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
}&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;The resulting message would be:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;TestStackIsEmptyWhenCreated failed.&amp;#160; Values are not equal. Expected 0, got 1.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Of course this is a very simple test so you could probably infer what went wrong.&amp;#160; It is a little cryptic though.&amp;#160; In a larger test it would be much more difficult to isolate the issue.&lt;/p&gt;

&lt;p&gt;So what’s wrong with assertion messages?&amp;#160; They’re superfluous.&amp;#160; Ask yourself this question: If you didn’t have to specify a message for the Unit Test Framework to display on failure,&lt;strong&gt; would you add that message as a comment above the line of code?&lt;/strong&gt;&amp;#160; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:1ee12c7e-edc2-4ddb-9665-b0bcd280e2c3" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:White;overflow: auto;"&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Testing whether stack is empty&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;Assert.AreEqual(emptyStack.Count, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;The answer is usually no.&amp;#160; Assuming you’ve properly named your variables it is rarely necessary to comment assertions.&amp;#160; &lt;strong&gt;In an ideal world&lt;/strong&gt; &lt;strong&gt;our Unit Testing Framework would output the line of code that failed&lt;/strong&gt;, just as our compilers do when they encounter syntax errors.&amp;#160; This would make most assertion messages redundant.&lt;/p&gt;

&lt;h4&gt;The Root Problem&lt;/h4&gt;

&lt;p&gt;All of these issues are caused by the same root problem.&amp;#160; Conceptually&lt;strong&gt; Unit Testing frameworks are an extension of your compiler&lt;/strong&gt;.&amp;#160; Compilers report static errors such as malformed code and type mismatches and unit testing frameworks report run-time errors such as unexpected values.&amp;#160; The reason why Unit Testing API’s are so clunky is that &lt;strong&gt;our Unit Testing frameworks don’t have access to as&lt;/strong&gt; &lt;strong&gt;much information as our compiler does&lt;/strong&gt;.&amp;#160; Compilers have access to the expression trees generated by our code.&amp;#160; They can analyze the code and determine what type of comparison we are attempting, and whether it is a value or reference comparison.&amp;#160; If the compiler encounters an error it can print the exact line of code or expression responsible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if there was a way to make our Unit Testing Frameworks as smart as our compilers?&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;Introducing Test.Assert()&lt;/h3&gt;

&lt;p&gt;Turns out it&lt;strong&gt; &lt;u&gt;is&lt;/u&gt; possible to express assertions as expressions and get all the feedback provided by the Assert methods when a test fails&lt;/strong&gt; (and even more).&lt;/p&gt;

&lt;h4&gt;Assertions as Expressions&lt;/h4&gt;

&lt;p&gt;Let’s rewrite our unit test using the Test.Assert() method:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:852bcd99-7b22-4915-a932-f3e840324f78" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:White;overflow: auto;"&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Unfold.Testing.VSTT;

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;
[TestMethod]
&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; TestStackIsEmptyWhenCreated()
{
    Stack emptyStack &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Stack();
    emptyStack.Push(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;an item that shouldn't be here.&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
    Test.Assert(() &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; emptyStack.Count &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
}&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;When we run this test and it fails we’ll get a message resembling this:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="geor"&gt;TestStackIsEmptyWhenCreated failed.&amp;#160; Values are not equal. Expected 0, got 1. &lt;strong&gt;emptyStack.Count = 0&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice that we get &lt;strong&gt;the same failure message as Assert.AreEqual&lt;/strong&gt; &lt;strong&gt;in addition to the expression responsible for the failure&lt;/strong&gt;!&lt;/p&gt;

&lt;h4&gt;Compound Expressions&lt;/h4&gt;

&lt;p&gt;Now that we can express assertions as expressions you may be wondering whether it is possible to express several assertions in a single compound expression.&amp;#160; With Test Extensions it’s as easy as using the “and” operator.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:ab422011-9bb1-4c2b-93ef-7303cc83122c" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;Test.Assert(() &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; customer.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; customer.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; “”);&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now our assertions are much easier to read as well as shorter!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Hold on.&amp;#160; Won’t using compound expressions make it harder to figure out which expression failed?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No.&amp;#160; Test.Assert doesn’t display the line of code that fails, it displays the &lt;em&gt;expression&lt;/em&gt; that fails.&amp;#160; For example if, in the test above, the customer’s name was an empty string we’d get the following failure messages:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;TestCustomerDefaultPropertyValues failed.&amp;#160; Values are same.&amp;#160; Expected not “”, got “”.&amp;#160; &lt;strong&gt;customer.Name != “”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;“Okay, but what if I still want to specify a custom assertion message?”&lt;/h4&gt;

&lt;p&gt;No problem.&amp;#160; Test Assert has an overload for that:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:6fbe0dd2-7b39-4420-93d8-bbe908a49f9c" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;Test.Assert(() &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; customer.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; customer.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; “”, &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Customer name is null or empty.&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);


&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;h4&gt;“Is it available for my Unit Testing Framework?”&lt;/h4&gt;

&lt;p&gt;Yes – assuming you’re using NUnit or VSTT :-).&amp;#160; I’m making the &lt;a href="http://themechanicalbride.com/unfold.testing.zip"&gt;source available under MS-PL&lt;/a&gt; so you’re free to port it to your unit testing framework of choice.&amp;#160; You’ll find the port is trivial if your unit testing framework uses the familiar Assert methods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“What about the Silverlight Unit Testing Framework?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don’t worry, I haven’t forgotten about Silverlight developers :-).&amp;#160; In fact Test.Assert() has been integrated into the &lt;a href="http://code.msdn.microsoft.com/silverlightut/"&gt;Silverlight Unit Testing Framework&lt;/a&gt; and will ship with the next version.&lt;/p&gt;

&lt;h4&gt;“How does it work?”&lt;/h4&gt;

&lt;p&gt;Test.Assert() improves your Unit Testing Framework by giving it access to the same information your compiler has: the expression tree.&amp;#160; Test.Assert is similar to Linq to SQL.&amp;#160; It converts your assertion expression into data, analyzes it, and then invokes the appropriate Assert methods.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_HI1qT6wpc4w/SiWDbugBhEI/AAAAAAAAAME/892wYzbYWVE/s1600-h/howitworks%5B5%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="howitworks" border="0" alt="howitworks" src="http://lh5.ggpht.com/_HI1qT6wpc4w/SiWDcMZ3NHI/AAAAAAAAAMI/xMmljfn8Tp8/howitworks_thumb%5B1%5D.png?imgmax=800" width="244" height="197" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Like Linq to SQL, Test.Assert() only supports a subset of the functionality provided by the underlying API.&amp;#160; For certain assertions, particularly those that don’t use operators, you will still need to use the Assert methods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Which Assert Methods are supported?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here’s a table that shows which expressions map to which Test.Assert methods.&lt;/p&gt;

&lt;table border="1" cellspacing="0" cellpadding="2" width="654"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="189"&gt;
        &lt;p align="center"&gt;&lt;strong&gt;Expression&lt;/strong&gt;&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top" width="263"&gt;
        &lt;p align="center"&gt;&lt;strong&gt;NUnit&lt;/strong&gt;&lt;/p&gt;
      &lt;/td&gt;

      &lt;td valign="top" width="203"&gt;
        &lt;p align="center"&gt;&lt;strong&gt;VSTT/Silverlight Unit Testing Framework&lt;/strong&gt;&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="188"&gt;&lt;font size="2" face="Courier New"&gt;value == true&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.IsTrue&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;Assert.IsTrue&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="187"&gt;&lt;font size="2" face="Courier New"&gt;value == false&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.IsFalse&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;Assert.IsFalse&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="187"&gt;&lt;font size="2" face="Courier New"&gt;value == 2&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.AreEqual&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;Assert.AreEqual&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="186"&gt;&lt;font size="2" face="Courier New"&gt;value != 2&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.AreNotEqual&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;Assert.AreNotEqual&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="186"&gt;&lt;font size="2" face="Courier New"&gt;value == “Jim”&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.AreSame&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;Assert.AreSame&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="186"&gt;&lt;font size="2" face="Courier New"&gt;value != “John”&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.AreNotSame&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;Assert.AreNotSame&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="186"&gt;&lt;font size="2" face="Courier New"&gt;“Jim” is string&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.IsInstanceOf&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;Assert.IsInstanceOfType&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="186"&gt;&lt;font size="2" face="Courier New"&gt;!(“Jim” is string)&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.IsNotInstanceOf&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;Assert.IsNotInstanceOfType&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="186"&gt;&lt;font size="2" face="Courier New"&gt;value &amp;lt; 2&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.Less&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;N/A&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="186"&gt;&lt;font size="2" face="Courier New"&gt;value &amp;lt;= 2&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.LessOrEqual&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;N/A&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="186"&gt;&lt;font size="2" face="Courier New"&gt;value &amp;gt; 2&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.Greater&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;N/A&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="186"&gt;&lt;font size="2" face="Courier New"&gt;value &amp;gt;= 2&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.GreaterOrEqual&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;N/A&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="186"&gt;&lt;font size="2" face="Courier New"&gt;double.IsNaN(value)&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.IsNaN&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;N/A&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="186"&gt;&lt;font size="2" face="Courier New"&gt;string.IsNullOrEmpty(“Jim”)&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.IsNullOrEmpty(“Jim”)&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;N/A&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="186"&gt;&lt;font size="2" face="Courier New"&gt;!string.IsNullOrEmpty(“Jim”)&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="263"&gt;&lt;font size="2" face="Courier New"&gt;Assert.IsNotNullOrEmpty(“Jim”)&lt;/font&gt;&lt;/td&gt;

      &lt;td valign="top" width="203"&gt;&lt;font size="2" face="Courier New"&gt;N/A&lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;If Test.Assert doesn’t recognize any patterns in your expression it will fallback to the Assert.IsTrue method and pass it your entire expression.&amp;#160; Often this - in addition including the expression in the failure message - is adequate.&amp;#160; If you want to ensure a specific Assert method is used you can always call that method directly as you would have before.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“What about VB.NET support?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The expression in the failure message is actually language agnostic and is the produced by calling the ToString() method of the System.Linq.Expressions.Expression object.&amp;#160; Sometimes it looks like VB.NET, sometimes it looks like C#.&amp;#160; There is no reason why you can’t use Test.Assert() in VB.NET.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“What about F# support?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Although the F# compiler is not capable of converting code into Linq expression trees, F# does have it’s own expression tree format which can be produced using the quotations language syntax.&amp;#160; &lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:7a112666-bf00-4a7e-9861-f22c9b39d4c8" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow: auto;"&gt;&lt;span style="color: #000000;"&gt;let expressionTree &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;@@ value &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; “” @@&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;You can convert F# expression trees to Linq expression trees using the F# Power Pack available with the &lt;a href="http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/"&gt;latest version of F#&lt;/a&gt;.&amp;#160; It should be trivial to write a wrapper method which does the conversion and forwards it to Test.Assert().&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Okay, okay.&amp;#160; Where can I get it?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can &lt;a href="http://themechanicalbride.com/unfold.testing.zip"&gt;download the source project (MS-PL) here&lt;/a&gt;.&amp;#160; It includes the VSTT and NUnit versions.&amp;#160; Test.Assert() will be integrated into the next release of the &lt;a href="http://code.msdn.microsoft.com/silverlightut/"&gt;Silverlight Unit Testing Framework&lt;/a&gt;.&amp;#160; Enjoy.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-5272975444026336673?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/5272975444026336673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=5272975444026336673' title='28 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/5272975444026336673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/5272975444026336673'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/06/better-unit-tests-with-testassert-for.html' title='Better Unit Tests with Test.Assert() for NUnit/VSTT/SUTF'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_HI1qT6wpc4w/SiWDcMZ3NHI/AAAAAAAAAMI/xMmljfn8Tp8/s72-c/howitworks_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/><thr:total>28</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-2624656947096906592</id><published>2009-05-24T11:29:00.001-07:00</published><updated>2009-05-24T11:34:08.734-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight Toolkit'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>Better WPF/Silverlight Development in F#: Attached Dependency Properties</title><content type='html'>&lt;p&gt;A very common idiom in WPF/Silverlight is the attached property.&amp;#160; Attached properties are properties that only have meaning in certain contexts, usually in relation to another class.&amp;#160; Attached properties are everywhere in WPF/Silverlight.&amp;#160; Although they are widely useful they are most commonly used with layout panels.&amp;#160; By introducing the notion of attached properties the architects of WPF were able to avoid having to add every conceivable property for every conceivable layout panel to each control (Top, Left, Grid Column, Grid Row, Rotation, and so on).&lt;/p&gt;  &lt;p&gt;Of course neither the CLR nor C# has any notion of attached properties.&amp;#160;&amp;#160; Therefore attached properties are typically implemented using a pair of static set and get methods on the Layout class.&amp;#160; These static setter/getter methods use a static dictionary to link a control to its attached property value.&amp;#160; As an example the Canvas panel lays controls out in a Cartesian coordinate system and has a Left attached property and a Top attached property.&amp;#160; Specifying these properties on a control looks something like this in C#:&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:eedab107-243f-4824-8963-803e3a1632fd" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;Canvas.SetLeft(myTextBox, &lt;/span&gt;&lt;span style="color: #800080;"&gt;23.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
Canvas.SetTop(myTextBox,&lt;/span&gt;&lt;span style="color: #800080;"&gt;24.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
myCanvas.Children.Add(myTextBox);&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;This works but it isn't ideal.&amp;#160; For one thing attached properties are not discoverable because they do not show up in the control&amp;#8217;s intellisense list. However the real issue though is that the code is too low-level, exposing the developer to the implementation of attached properties rather than simply letting them express their intent.&lt;/p&gt;

&lt;p&gt;F# has the notion of extension properties.&amp;#160; Like extension methods in C#, extension properties can be defined on a class outside of the class definition.&amp;#160; So with the smallest dab of code...&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:7901af85-393b-45ee-ba1b-cfb72de10e6f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;type UIElement with
   member &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Left
     with &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;() &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Canvas.GetLeft(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
     and &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;(value) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Canvas.SetLeft(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;, value)
   member &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Top
      with &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;() &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Canvas.GetTop(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
      and &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;(value) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Canvas.SetTop(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;, value)&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&amp;#8230;I can do this&amp;#8230;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:2ec9f50f-3112-466c-9ab9-ac89ec3c6b91" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;myTextBox.Left &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;23.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;
myTextBox.Top &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;24&lt;/span&gt;&lt;span style="color: #000000;"&gt;
myCanvas.Children.Add(myTextBox)&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Much better.&amp;#160; Now the properties belong to the control but like extension methods they only appear when the assembly with Canvas is imported.&amp;#160; Unfortunately with the current build of F# you can't use attached properties in object expressions like this...&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:3b758e6f-2cfe-4cf0-9c94-9f4fa4a7fddd" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;Image(Uri &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Uri(“test.png”), Left &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;20&lt;/span&gt;&lt;span style="color: #000000;"&gt;, Top &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;40&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;...however I've been assured by Don Syme himself that this will be fixed by VS 2010 Beta 2.&amp;#160; &lt;/p&gt;

&lt;p&gt;So there you have it.&amp;#160; An admittedly small, but very nice trick.&amp;#160; More to follow.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-2624656947096906592?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/2624656947096906592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=2624656947096906592' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/2624656947096906592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/2624656947096906592'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/05/better-wpfsilverlight-development-in-f.html' title='Better WPF/Silverlight Development in F#: Attached Dependency Properties'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-5392497130138894719</id><published>2009-05-24T11:03:00.001-07:00</published><updated>2009-05-24T11:10:18.274-07:00</updated><title type='text'>.NET Language Evolution: Do you care?</title><content type='html'>&lt;p&gt;Luca Bolognese recently announced that C# and VB.NET will now be co-evolved.&amp;#160; That is to say, no feature will be introduced to one without being added to the other.&amp;#160; I can't deny that this makes sense but as a language geek its certainly not very exciting news.&amp;#160; More ominously Luca hinted language evolution was going to &amp;quot;slow down.&amp;quot;&amp;#160; Yikes.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_HI1qT6wpc4w/ShmL3nLEJ_I/AAAAAAAAAL8/ujsjlmZMLmc/s1600-h/ida_fossil_images%5B5%5D.jpg"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="162" alt="ida_fossil_images" src="http://lh6.ggpht.com/_HI1qT6wpc4w/ShmL4rXSonI/AAAAAAAAAMA/AI8U44tzac8/ida_fossil_images_thumb%5B3%5D.jpg?imgmax=800" width="244" align="right" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Apparently some of our customers are having difficulty ramping up on language features introduced alongside .NET 2.0.&amp;#160; Although I sympathize with these customers Microsoft made the right call when they took an aggressive approach towards language evolution, adding very significant new features inspired by functional languages.&amp;#160; Increasingly their customers are having to write scalable, asynchronous code to leverage multi-core processors.&amp;#160; These are hard problems and learning to think about them differently is essential to success.&amp;#160; There is a parallel here to the introduction of VB.NET and the phasing out of Visual Basic.&lt;/p&gt;  &lt;p&gt;The news that C# and VB.NET evolution is going to taper off should not come as a surprise.&amp;#160; You can't keep adding features to a programming languages forever and it's especially hard when they have such a long heritage.&amp;#160; Under the circumstances Anders has done an admirable job.&amp;#160; Unfortunately there are certain functional algorithms that developers cannot, and will likely never be able to, express cleanly in either C# or VB.NET.&lt;/p&gt;  &lt;p&gt;Enter F#.&amp;#160; &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=922B4655-93D0-4476-BDA4-94CF5F8D4814&amp;amp;displaylang=en"&gt;Visual Studio 2010 Beta 1&lt;/a&gt; is here and if you take the plunge you'll find that F# has finally been elevated to a first-class .NET language along-side C# and VB.NET.&amp;#160; We have every reason to believe F# will continue to evolve.&amp;#160; For starters it's just the first version.&amp;#160; Don Syme has also expressed interest in adding language features from Haskell as well.&amp;#160; The interesting question is: Does Language Evolution Matter?&lt;/p&gt;  &lt;p&gt;There is some controversy over the importance of programming languages.&amp;#160; Some believe that it's primarily a developers knowledge of the existing class libraries that matters.&amp;#160; It's hard to deny this given the massive size of our libraries today.&amp;#160; However my personal experience is that in recent years learning the new language features introduced in C# has significantly improved my productivity, as well as the quality of my code.&amp;#160; It still fills me with such a sense of wonder that simply thinking about a problem differently can have such a profound effect.&amp;#160; It is for this reason that I've already made F# my primary language for play.&amp;#160; I hope to get the opportunity to use it at work at some point as well.&amp;#160; There are some very compelling reasons to use it to solve certain types of problems we face in WPF/Silverlight development. After all if not at Microsoft, then where? :-)&lt;/p&gt;  &lt;p&gt;You can expect more Silverlight/WPF-related F# blog posts from me in the future.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-5392497130138894719?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/5392497130138894719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=5392497130138894719' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/5392497130138894719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/5392497130138894719'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/05/net-language-evolution-do-you-care.html' title='.NET Language Evolution: Do you care?'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_HI1qT6wpc4w/ShmL4rXSonI/AAAAAAAAAMA/AI8U44tzac8/s72-c/ida_fossil_images_thumb%5B3%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-4501432784908675435</id><published>2009-04-27T17:28:00.001-07:00</published><updated>2009-04-27T17:28:15.636-07:00</updated><title type='text'>Rx Framework: Asynchronous Programming Made Easy</title><content type='html'>&lt;p&gt;A few weeks ago, to little fanfare Erik Meijer gave a presentation on the Rx Framework at the Lang.NET symposium.&amp;#160; You probably missed it.&amp;#160; Don't worry though.&amp;#160; It's no big deal.&amp;#160; It's only the culmination of one the most significant discoveries about the fundamental nature of asynchronous programming.&amp;#160; Oh yeah, and it's coming soon to the .NET Framework.&lt;/p&gt;  &lt;p&gt;The Rx Framework uses Linq to build asynchronous code declaratively.&amp;#160; One of the perks of working at Microsoft is that I've been using it for months now.&amp;#160; Now that it has finally been talked about publicly I fully intend to start blogging about it but I'm waiting for the folks responsible, notably Wes Dyer, to take the plunge .&amp;#160; In the meantime here's a link to the presentation.&amp;#160; Watch it &lt;a href="http://www.langnetsymposium.com/2009/talks/23-ErikMeijer-LiveLabsReactiveFramework.html"&gt;here&lt;/a&gt; while it's still on-line.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-4501432784908675435?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/4501432784908675435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=4501432784908675435' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/4501432784908675435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/4501432784908675435'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/04/rx-framework-asynchronous-programming.html' title='Rx Framework: Asynchronous Programming Made Easy'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-259349011119905589</id><published>2009-04-16T00:06:00.001-07:00</published><updated>2009-04-16T00:44:08.018-07:00</updated><title type='text'>An F# Solution to Eric Lippert's Challenge</title><content type='html'>&lt;p&gt;&lt;a href="http://blogs.msdn.com/delay/"&gt;David Anson&lt;/a&gt; recently brought &lt;a href="http://blogs.msdn.com/ericlippert/archive/2009/04/15/comma-quibbling.aspx"&gt;Eric Lippert's challenge&lt;/a&gt; to my attention. I can't resist an opportunity to showcase F#'s strengths so I thought I'd throw my hat into the ring with a solution.&lt;/p&gt;  &lt;p&gt;I'll briefly summarize the problem for those too lazy to follow the link :-):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Given a sequence of strings, concatenate them in a way similar to natural language.&amp;#160; For example the sequence &amp;quot;ABC&amp;quot;, &amp;quot;DEF&amp;quot;, &amp;quot;G&amp;quot;, and &amp;quot;H&amp;quot; should be output as:&lt;/p&gt;    &lt;p&gt;{ABC, DEF, G and H}&lt;/p&gt;    &lt;p&gt;&amp;quot;ABC&amp;quot; and &amp;quot;DEF&amp;quot; should be output as...&lt;/p&gt;    &lt;p&gt;{ABC and DEF}&lt;/p&gt;    &lt;p&gt;...and finally an empty sequence should yield the following output:&lt;/p&gt;    &lt;p&gt;{}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Of course this problem is simple enough to solve.&amp;#160; The real challenge is creating a solution which is declarative &lt;em&gt;and&lt;/em&gt; efficient.&amp;#160; In order to achieve the desired result we must determine if each item is the first, the last, or is in the center &lt;em&gt;without&lt;/em&gt; relying on random access. The typical approach in C# or VB.NET would be to get an enumerator from the sequence, step through it, and create a state machine that keeps track of the last two values.&amp;#160; Unfortunately this approach wouldn't scale and would be full of corner cases to handle.&amp;#160; &lt;/p&gt;  &lt;p&gt;Let's see if we can do better with F#.&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:8c03e4bb-9364-44fb-a8c5-4e666d2d6c75" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;open System
open System.Text

let concat_string (list: &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; seq) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    let tripleWise &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
        Seq.append list [&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;]
        &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Seq.scan
            (fun (_, previousPrevious, previous) current &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                (previousPrevious, previous, current)
            )
            (&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)

    let contents &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
        tripleWise
        &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Seq.map 
            (function
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; _, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, _ &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; String.Empty
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, curr, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; curr            
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, first, _ &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; first
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; _, last, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; sprintf &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt; and %s&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; last
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; prev, curr, next &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; sprintf &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;, %s&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; curr)

    let builder &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; StringBuilder()
    contents &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Seq.iter (fun item &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; (builder.Append(item) &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ignore))
    sprintf &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;{%s}&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; (builder.ToString())

&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; prints &amp;quot;{ABC, DEF, G and H}&amp;quot;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;printf &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;%s&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; (concat_string [&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;ABC&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;DEF&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;G&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;H&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;])
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; prints &amp;quot;{ABC and DEF}&amp;quot;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;printf &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;%s&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; (concat_string [&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;ABC&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;DEF&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;])
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; prints &amp;quot;{ABC}&amp;quot;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;printf &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;%s&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; (concat_string [&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;ABC&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;])
&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; prints &amp;quot;{}&amp;quot;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;printf &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;%s&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; (concat_string [])&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Let's take a look at the program step by step.&lt;/p&gt;

&lt;h3&gt;Type Inference, Whitespace Awareness, and Type Aliases&lt;/h3&gt;

&lt;p&gt;
  &lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:fac51978-d789-4e28-a458-c97ebef745b4" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; width: 763px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;let concat_string (list: &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; seq) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;The first line of code contains the &lt;u&gt;only type declaration in the entire program&lt;/u&gt;&lt;em&gt;.&lt;/em&gt; Not too shabby.&amp;#160; For those that don't know &amp;quot;string seq&amp;quot; is a type alias for IEnumerable&amp;lt;string&amp;gt;.&amp;#160; Having a type alias for sequences is really nice because sequence processing is so common in both C# and F#.&amp;#160; Notice that like Python, F# is also whitespace aware.&amp;#160; These three features help F# achieve Python-like terseness without sacrificing performance or type safety.&lt;/p&gt;

&lt;h3&gt;Structural Types&lt;/h3&gt;

&lt;p&gt;My solution leverages F#'s native support for structural types, that is types that can be used to group arbitrary values together.&amp;#160; The following code creates a sequence of triples, which is a group of three values.&amp;#160; Notice that pattern matching is used to introduce descriptive identifiers for each element in the triple.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:d5cfd8ab-3a65-4a7a-8920-a724c2925ca6" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    let tripleWise &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
        Seq.append list [&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;]
        &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Seq.scan
            (fun (_, previousPrevious, previous) current &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                (previousPrevious, previous, current)
            )
            (&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;The &amp;quot;tripleWise&amp;quot; identifier refers to a sequence of triples containing the previous, the current, and the next item.&amp;#160; For example if the input list is defined as &amp;quot;ABC&amp;quot; and &amp;quot;DEF&amp;quot; then tripleWise will be:&lt;/p&gt;

&lt;p&gt;(null,null,null), (null,null,&amp;quot;ABC&amp;quot;), (null,&amp;quot;ABC&amp;quot;,&amp;quot;DEF&amp;quot;), (&amp;quot;ABC&amp;quot;,&amp;quot;DEF&amp;quot;,null)&lt;/p&gt;

&lt;p&gt;The scan function works in a way very similar to System.Linq.Enumerable.Aggregate.&amp;#160; Here's a C# example that uses Aggregate to sum a sequence of numbers.&amp;#160; &lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:a32e3da4-fcf6-4e4c-bc1e-35821e26fae5" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]{&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;}.Aggregate((accumulatedValue, current) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; accumulatedValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; current, &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)

&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;The difference between scan and Aggregate is that scan returns the intermediary accumulated values as a sequence.&amp;#160; Given the example above scan would return a sequence of the following values:&lt;/p&gt;

&lt;p&gt;0, 2, 6, 10, 12&lt;/p&gt;

&lt;p&gt;An empty triple is used as the initial value and scan is passed a function which shifts each item in the sequence through the triple from the right to left. Each time it returns the resulting triple. Now we have a sequence of triples containing the previous, current, and next values.&amp;#160; For each triple we can determine if the middle item is the first item or the last item by checking whether the left or right items are null respectively.&amp;#160; Note that by appending null to the end of the original sequence in the first line we can be sure that the rightmost item in the last triple will be null.&lt;/p&gt;

&lt;h3&gt;Parallelizing the Code&lt;/h3&gt;

&lt;p&gt;We've successfully avoided state and mutation and we now have a sequence of snapshots of each value and its previous and next values.&amp;#160; &lt;strong&gt;This is very important&lt;/strong&gt;.&amp;#160; Now we can process each triple in the sequence in any order we like: last to first, first to last, or &lt;em&gt;first and last at the same time.&lt;/em&gt;&amp;#160;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:5f5b7a2f-0bea-4bff-8d25-de3a0025afb0" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    let contents &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
        tripleWise
        &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Seq.map 
            (function
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; _, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, _ &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; String.Empty
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, curr, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; curr            
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, first, _ &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; first
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; _, last, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; sprintf &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt; and %s&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; last
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; prev, curr, next &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; sprintf &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;, %s&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; curr)&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;The code above introduces a function that uses pattern matching to declaratively transform each possible triple into a string.&amp;#160; It just doesn't get much more readable than this.&amp;#160; This function is applied to each element using map (equivalent to System.Linq.Enumerable.Select) which yields a sequence of strings.&lt;/p&gt;

&lt;p&gt;Just for fun let's see how much work it would take to parallelize the code above using &lt;a href="http://weblogs.asp.net/podwysocki/archive/2009/02/23/adding-parallel-extensions-to-f.aspx"&gt;Matthew Podwasaki's F# parallel extensions library&lt;/a&gt; and the latest CTP of the Parallel Extensions.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:21565602-ac69-4a3f-949b-d096d97bc332" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    let contents &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
        tripleWise.AsParallel()
        &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; PSeq.map 
            (function
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; _, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, _ &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; String.Empty
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, curr, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; curr            
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, first, _ &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; first
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; _, last, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; sprintf &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt; and %s&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; last
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; prev, curr, next &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; sprintf &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;, %s&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; curr)&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Notice that &lt;strong&gt;all I had to do was add 14 characters!&lt;/strong&gt;&amp;#160; Now the code above should increase in speed at a linear rate with the number of cores on the processor.&amp;#160; Just try that with a state machine. :-)&amp;#160; &lt;/p&gt;

&lt;p&gt;In the next five years its very possible we will see processors with over 50 cores on a desktop.&amp;#160; This is one of the reasons I get so frustrated when I see developers unnecessarily using state in their computations.&amp;#160; State is the new GOTO.&amp;#160; It should have to be justified.&lt;/p&gt;

&lt;h3&gt;State When it Makes Sense&lt;/h3&gt;

&lt;p&gt;Notice that at the end the strings are concatenated using a StringBuilder.&amp;#160; &lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:f07d2efb-6531-4652-9ea4-8bbff547a194" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    let builder &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; StringBuilder()
    contents &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Seq.iter (fun item &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; (builder.Append(item) &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ignore))
    sprintf &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;{%s}&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; (builder.ToString())&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;This operation is decidedly &lt;em&gt;impure&lt;/em&gt;.&amp;#160; This demonstrates another wonderful F# feature: the ability to perform stateful operations when it makes sense. It's important to understand there's nothing preventing us from writing C#-style imperative code in F#.&amp;#160; &lt;/p&gt;

&lt;p&gt;An alternate, pure approach to the problem above would've involved using reduce (equivalent to System.Linq.Enumerable.Aggregate) to concatenate all the strings together using the + operator.&amp;#160; Although reduce, like map, can be parallelized it is unlikely that this would improve performance because concatenating strings creates so much extra work.&amp;#160; Each time two strings are concatenated a new one must be created and the contents of both strings must be copied to a new memory location.&amp;#160; Under the circumstances it makes sense to add a dash of state and use a StringBuilder.&lt;/p&gt;

&lt;h3&gt;Learn F#&lt;/h3&gt;

&lt;p&gt;The entire program is 25 lines including whitespace and imports and I'm very comfortable with its trade-offs.&amp;#160; I look forward to seeing what the other developers come up with but I'm confident that no one will do better in C#.&amp;#160; F# really shines when it comes to computation.&amp;#160; Learning it is a must if you consider yourself a sharp Elvis or an Einstein and you make your living with .NET.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3761674922653685009-259349011119905589?l=themechanicalbride.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://themechanicalbride.blogspot.com/feeds/259349011119905589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3761674922653685009&amp;postID=259349011119905589' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/259349011119905589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3761674922653685009/posts/default/259349011119905589'/><link rel='alternate' type='text/html' href='http://themechanicalbride.blogspot.com/2009/04/f-solution-to-eric-lippert-challenge.html' title='An F# Solution to Eric Lippert&amp;#39;s Challenge'/><author><name>Jafar Husain</name><uri>http://www.blogger.com/profile/15444397760399385108</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://profile.ak.facebook.com/profile2/733/9/t814805555_25626.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3761674922653685009.post-7895530956067933369</id><published>2009-03-25T12:22:00.001-07:00</published><updated>2009-03-25T12:31:56.858-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight Toolkit'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>Writing Your Own Silverlight Chart Series (Part 2): Implementing the Series</title><content type='html'>&lt;p&gt;This is the second part in a series of three that explains how you can add series to Silverlight Charts.&amp;#160;&amp;#160; We'll look at how Silverlight Chart's rich hierarchy of interfaces allow developers to create series that can play well with all the built-in series and axes, as well as custom series and axes written by other parties.&amp;#160; Once again...&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Beware&lt;/strong&gt;:&amp;#160; &lt;strong&gt;Silverlight charts is still in preview mode and there may be breaking changes in the future despite our best efforts to avoid them.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Last time we learn how to structure our series in such a way that designers can customize its appearance.&amp;#160; Now we can get down to the business of implementing our stock series.&amp;#160; The StockSeries class is responsible for the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Acquiring a data point style &lt;/li&gt;    &lt;li&gt;Adding a legend item &lt;/li&gt;    &lt;li&gt;Binding data points to a data source &lt;/li&gt;    &lt;li&gt;Acquiring axes &lt;/li&gt;    &lt;li&gt;Plotting the Data Points &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Acquiring a Data Point Style&lt;/h3&gt;  &lt;p&gt;When we plot multiple series in the same Chart we want each of them to have different colors so that we can tell them apart. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_HI1qT6wpc4w/ScqES-IiFmI/AAAAAAAAAKU/rbnUHdM3kX4/ChartingIntroductionMar09LineSeriesO.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="196" alt="ChartingIntroduction-Mar09-LineSeriesOnCategoryAxis" src="http://lh6.ggpht.com/_HI1qT6wpc4w/ScqETXGuoZI/AAAAAAAAAKY/HYkXcIWmvhI/ChartingIntroductionMar09LineSeriesO%5B1%5D.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;To ensure that our StockSeries uses a different color than the other series in the chart it must retrieve the next available style from its series host.&amp;#160; A series host contains series and provides them with various services.&amp;#160; Currently the only object that implements the ISeriesHost interface in Silverlight Charts is the Chart object.&amp;#160; Let's take a look at the Chart hierarchy.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_HI1qT6wpc4w/ScqET14X9oI/AAAAAAAAAKc/lClq2Ie9jRk/blogimage122.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="155" alt="blogimage12" src="http://lh5.ggpht.com/_HI1qT6wpc4w/ScqEUBjCd3I/AAAAAAAAAKg/QqXMWiEEIck/blogimage12_thumb.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;When a series is inserted into a Chart the SeriesHost property of the series is set to that Chart.&amp;#160; Conversely when a series is removed from a chart its SeriesHost property is set to null.&amp;#160; When the SeriesHost property changes a protected method OnSeriesHostPropertyChanged is invoked.&amp;#160; We can override this method in our StockSeries class if we want to do something when the series is added or removed from a Chart.&amp;#160; &lt;/p&gt;  &lt;p&gt;We should acquire a style from our series host when...&lt;/p&gt;  &lt;p&gt;1.&amp;#160; The series host changes&lt;/p&gt;  &lt;p&gt;2.&amp;#160; The RefreshStyles method of the base &amp;quot;Series&amp;quot; class is called&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:00fae0e8-2080-4225-aae6-2e8ba5afebb9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; StockSeries : Series, IRequireGlobalSeriesIndex
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; Style DataPointStyle { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnSeriesHostPropertyChanged(ISeriesHost oldValue, ISeriesHost newValue)
        {
            AcquireDataPointStyle();
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;.OnSeriesHostPropertyChanged(oldValue, newValue);
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; RefreshStyles()
        {
            AcquireDataPointStyle();
            Refresh();
        }
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; AcquireDataPointStyle()
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (SeriesHost &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
            {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; (IEnumerator&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Style&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; styleEnumerator &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SeriesHost.GetStylesWithTargetType(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(StockDataPoint), &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;))
                {
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (styleEnumerator.MoveNext())
                    {
                        DataPointStyle &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; styleEnumerator.Current;
                    }
                }
            }
        }

        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;In the example above we're using the IStyleDispenser's extension method GetStylesWithTargetType (in System.Windows.Controls.DataVisualization) to retrieve an IEnumerator of styles appropriate for our data point type.&amp;#160; &lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:bd3a7945-aac6-44b4-830f-3c549973ba89" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;newValue.GetStylesWithTargetType(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(StockDataPoint), &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;))&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;The &amp;quot;true&amp;quot; indicates that we are willing to accept styles with a target type that is an ancestor of our data point's type.&amp;#160; Due to the fact that all of the styles in the Chart's default style palette target Control - which StockDataPoint inherits from - we can be sure our series will get a style when we insert it into a Chart.&lt;/p&gt;

&lt;h3&gt;Adding a Legend Item&lt;/h3&gt;

&lt;p&gt;Now that we've acquired a style we can use for our data points the time is right to insert a legend item into the Legend.&amp;#160; We'll add a private property to store an instance of the LegendItem class and initialize it in the constructor.&amp;#160; In order to ensure that it is inserted into the Legend we'll add it to the series LegendItems collection (inherited from base class Series). UI elements inserted into the legend items collection of a series are automatically inserted into the legend by the series host.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:cca12479-1dfe-4034-9206-89ad8eef66d1" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; StockSeries : Series
    {
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; LegendItem LegendItem { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; StockSeries()
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.DefaultStyleKey &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(StockSeries);
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.LegendItem &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; LegendItem();
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.LegendItems.Add(LegendItem);
        }

    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;A well-behaved series ensures the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If it does &lt;u&gt;not&lt;/u&gt; have a title its legend item should display the series index &lt;/li&gt;

  &lt;li&gt;If it &lt;u&gt;has&lt;/u&gt; a title the legend item should display it &lt;/li&gt;

  &lt;li&gt;Its legend item should have a visual appearance similar to its data points &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Displaying the Series Index&lt;/h4&gt;

&lt;p&gt;If the series does not have a title it should display its series index in the LegendItem. Therefore we must determine what the index of our series is.&amp;#160; We can try and figure out our index by counting the series in our series host collection, but this approach is complicated because we would also have to monitor the series collection of our series host for any changes.&lt;/p&gt;

&lt;p&gt;Thankfully we can let the series host do the work for us by implementing IRequireGlobalSeriesIndex.&amp;#160; This is our way of signaling to the series host that this series uses an index and needs to be informed when that index changes. In addition to implementing this interface we'll also add a property to store the global series index value.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:1066ad8b-0b49-47ee-8580-021226d586d1" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; StockSeries : Series, IRequireGlobalSeriesIndex
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; GlobalSeriesIndex { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; LegendItem LegendItem { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; GlobalSeriesIndexChanged(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; globalIndex)
        {
            GlobalSeriesIndex &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; globalIndex;
            UpdateLegendItem();
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; UpdateLegendItem()
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (GlobalSeriesIndex &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
            {
                LegendItem.Content &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Format(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Series {0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, GlobalSeriesIndex &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
            }
        }

        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Now if we add our series to a chart we should be able to see our legend item!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_HI1qT6wpc4w/ScqEUpXKLKI/AAAAAAAAAKk/XJ9ufKRq3qY/blogimage158.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="186" alt="blogimage15" src="http://lh3.ggpht.com/_HI1qT6wpc4w/ScqEVJwc7QI/AAAAAAAAAKo/58C257Ou_pA/blogimage15_thumb2.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h4&gt;Displaying the Series Title in the Legend Item&lt;/h4&gt;

&lt;p&gt;If a series title is set it's good practice to display it in the legend item instead of the index.&amp;#160; We could set the content of our legend item to the series Title property when we create the legend item, but we also need to update our legend item if the title changes.&amp;#160; We can listen for changes to the title property by overriding the protected OnTitleChanged method.&amp;#160; Let's also modify our private UpdateLegendItem method to check if the Title property is set before resorting to using the series index.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:ed68af74-58f6-4df4-ac23-1420ce5b3dcb" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; StockSeries : Series, IRequireGlobalSeriesIndex
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; UpdateLegendItem()
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Title &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
            {
                LegendItem.Content &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Title;
            }
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (GlobalSeriesIndex &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
            {
                LegendItem.Content &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Format(&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Series {0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, GlobalSeriesIndex&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
            }
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnTitleChanged(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; oldValue, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; newValue)
        {
            UpdateLegendItem();
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;.OnTitleChanged(oldValue, newValue);
        }

        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Now if we specify a custom series title we can see it in the Legend!&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:c0a8118e-d849-44ad-93ca-53dd4a477ee2" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;charting:Chart&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;local:StockSeries Title&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;My First Series&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;charting:Chart&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_HI1qT6wpc4w/ScqEVo0PoDI/AAAAAAAAAKs/AEPpoHi8FKA/myfirstseries2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="my first series" src="http://lh5.ggpht.com/_HI1qT6wpc4w/ScqEWI_GRJI/AAAAAAAAAKw/UZE_f3kWIO8/myfirstseries_thumb.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h4&gt;Styling the Legend Item&lt;/h4&gt;

&lt;p&gt;Ideally we'd like our legend item to be the same color as our data points.&amp;#160; We can accomplish this by creating an instance of StockSeriesDataPoint, applying the data point style we retrieved from the series host, and setting the data point to be the data context of our legend item.&amp;#160; The best place to do this is in our AcquireDataPointStyle method.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:a2c4b711-1392-466e-aece-821e79be2ba9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; AcquireDataPointStyle()
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (SeriesHost &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; (IEnumerator&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Style&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; styleEnumerator &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SeriesHost.GetStylesWithTargetType(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(StockDataPoint), &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;))
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (styleEnumerator.MoveNext())
            {
                DataPointStyle &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; styleEnumerator.Current;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.LegendItem.DataContext &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; StockDataPoint { Style &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; DataPointStyle };
            }
        }
    }
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Now we can see that the legend item has a color.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_HI1qT6wpc4w/ScqEWdlg8SI/AAAAAAAAAK0/W45FIV6fjss/myfirstseriesincolor2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="my first series in color" src="http://lh6.ggpht.com/_HI1qT6wpc4w/ScqEWxDANCI/AAAAAAAAAK4/WqLMehvlro0/myfirstseriesincolor_thumb.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;So how does this work?&amp;#160; The default template for the LegendItem binds to the background color and border brush properties of its DataContext.&amp;#160; This approach means that we can expose a LegendItemStyle property and give designers the ability to replace our legend item's template while still retaining certain aspects of the data point style (such as the color).&amp;#160; I'll leave that as an exercise for the reader.&lt;/p&gt;

&lt;h3&gt;Binding Data Points to a Data Source&lt;/h3&gt;

&lt;p&gt;We'd like to be able to bind our series directly to objects in our data source.&amp;#160; Let's add string properties for the DatePath, HighPath, LowPath, and ClosePath to our series.&amp;#160; We'll store the path's in binding objects which we'll use to bind the properties in our data points to the properties in our data source objects.&amp;#160; We expose string properties for our paths instead of bindings because strings are easier to work with in Blend.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:6611f871-1c70-4850-b617-b60bdc091bb2" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; Binding dateBinding &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Binding();

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; DateBinding
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; dateBinding.Path.Path;
            }
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            {
                dateBinding.Path &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; PropertyPath(value);
            }
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; Binding lowBinding &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Binding();

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; LowPath
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; lowBinding.Path.Path;
            }
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            {
                lowBinding.Path &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; PropertyPath(value);
            }
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; Binding highBinding &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Binding();

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; HighPath
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; highBinding.Path.Path;
            }
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            {
                highBinding.Path &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; PropertyPath(value);
            }
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; Binding closeBinding &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Binding();

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; ClosePath
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; closeBinding.Path.Path;
            }
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            {
                closeBinding.Path &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; PropertyPath(value);
            }
        }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Let's follow the ItemsControl model and add an ItemsSource dependency property of type IEnumerable.&amp;#160; When the ItemsSource property changes we'll create a data point for each object and add the data points to a dictionary using the object as the key.&amp;#160; We'll use a helper method called CreateStockDataPoint to create the data point, apply our data point style, and add the bindings to it.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:cb75ae58-5169-47b1-9898-e1d3c51e7f71" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; StockDataPoint CreateStockDataPoint(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; value)
        {
            var stockDataPoint &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; StockDataPoint { DataContext &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; value };
            stockDataPoint.Style &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; DataPointStyle;
            stockDataPoint.SetBinding(StockDataPoint.DateProperty, dateBinding);
            stockDataPoint.SetBinding(StockDataPoint.HighProperty, highBinding);
            stockDataPoint.SetBinding(StockDataPoint.LowProperty, lowBinding);
            stockDataPoint.SetBinding(StockDataPoint.CloseProperty, closeBinding);
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; stockDataPoint;
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; Dictionary&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;, StockDataPoint&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; _dataPoints &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Dictionary&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;, StockDataPoint&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;();

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; IEnumerable ItemsSource
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt; { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetValue(ItemsSourceProperty) &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;as&lt;/span&gt;&lt;span style="color: #000000;"&gt; IEnumerable; }
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt; { SetValue(ItemsSourceProperty, value); }
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000;"&gt; DependencyProperty ItemsSourceProperty &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            DependencyProperty.Register(
                &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;ItemsSource&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(IEnumerable),
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(StockSeries),
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; PropertyMetadata(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, OnItemsSourcePropertyChanged));

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            StockSeries source &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; (StockSeries)d;
            IEnumerable oldValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; (IEnumerable)e.OldValue;
            IEnumerable newValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; (IEnumerable)e.NewValue;
            source.OnItemsSourcePropertyChanged(oldValue, newValue);
        }
        
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;virtual&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnItemsSourcePropertyChanged(IEnumerable oldValue, IEnumerable newValue)
        {
            Refresh();
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Refresh()
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (ItemsSource &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
            {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.PlotArea.Children.Clear();
                _dataPoints &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                    ItemsSource
                        .Cast&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;()
                        .Select(obj &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; CreateStockDataPoint(obj))
                        .ToDictionary(dataPoint &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; dataPoint.DataContext);
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (StockDataPoint dataPoint &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; _dataPoints.Values)
                {
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.PlotArea.Children.Add(dataPoint);
                }
            }
        }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;That's all it takes to create our data points and bind them to an underlying data source!&lt;/p&gt;

&lt;h4&gt;&lt;/h4&gt;

&lt;h4&gt;Creating Some Sample Data To Plot&lt;/h4&gt;

&lt;p&gt;We'll need some sample data if we want to see our series in action.&amp;#160; First we'll need a class to hold our sample data.
  &lt;p&gt;&lt;/p&gt;

  &lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:e5c129ca-eb31-4f99-a380-6c6e496cb07e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; HighLowClose
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; DateTime Date { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;double&lt;/span&gt;&lt;span style="color: #000000;"&gt; High { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;double&lt;/span&gt;&lt;span style="color: #000000;"&gt; Low { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;double&lt;/span&gt;&lt;span style="color: #000000;"&gt; Close { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
        }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;That was easy.&amp;#160; Thanks automatic properties!&amp;#160; Now let's create a set of data and set it to the ItemsSource property of our series.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:b44d6b7f-aa84-4930-8b30-563567a57c83" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;            var date &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DateTime(&lt;/span&gt;&lt;span style="color: #800080;"&gt;2008&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
            StockSeries stockSeries &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; chart.Series[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;] &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;as&lt;/span&gt;&lt;span style="color: #000000;"&gt; StockSeries;
            stockSeries.DatePath &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Date&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
            stockSeries.HighPath &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;High&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
            stockSeries.LowPath &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Low&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
            stockSeries.ClosePath &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Close&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
            stockSeries.ItemsSource &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]
                {
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HighLowClose 
                    { 
                        Date &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; date,
                        High &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;23.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                        Low &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;18.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                        Close &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;22.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                    },
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HighLowClose 
                    { 
                        Date &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; date.AddDays(&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;),
                        High &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;26.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                        Low &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;22.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                        Close &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;22.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                    },
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HighLowClose 
                    { 
                        Date &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; date.AddDays(&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;),
                        High &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;33.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                        Low &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;30.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                        Close &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;32.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                    },
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HighLowClose 
                    { 
                        Date &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; date.AddDays(&lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;),
                        High &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;44.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                        Low &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;42.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                        Close &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;43.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                    },
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HighLowClose 
                    { 
                        Date &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; date.AddDays(&lt;/span&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&lt;span style="color: #000000;"&gt;),
                        High &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;37.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                        Low &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;35.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                        Close &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;36.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                    },
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HighLowClose 
                    { 
                        Date &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; date.AddDays(&lt;/span&gt;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&lt;span style="color: #000000;"&gt;),
                        High &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;49.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                        Low &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;43.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,
                        Close &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;48.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                    },
                };&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Now we're ready to starting plotting our data points.&lt;/p&gt;

&lt;h3&gt;Acquiring Axes&lt;/h3&gt;

&lt;h4&gt;Listening for Changes&lt;/h4&gt;

&lt;p&gt;To plot our data points we'll need axes, but first we need to ensure that our series can receive messages from them.&amp;#160; The series needs to be able to listen for changes in the axes such as a change in the range or size.&amp;#160; This way it can respond to these changes by updating the positions of its data points accordingly.&amp;#160; A series can listen for axis changes by implementing the IAxisListener interface.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:cd31d2d2-e21d-4203-aa1e-ebab3408c173" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    [TemplatePart(Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;PlotArea&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;, Type &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(Canvas))]
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; StockSeries : Series, IAxisListener, IRequireGlobalSeriesIndex
    {
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; AxisInvalidated(IAxis axis)
        {
        }
    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;The AxisInvalidated method is called by an axis when it changes.&amp;#160; Eventually we will add some code to update our data points to this method.&amp;#160; For the time being we'll leave it empty though. &lt;/p&gt;

&lt;h4&gt;Acquiring Axes&lt;/h4&gt;

&lt;p&gt;Now that we can listen for changes in an axis we want to acquire axes that we can use.&amp;#160; Where do get them from though?&amp;#160; &lt;/p&gt;

&lt;p&gt;A well-behaved series does the following when it is added to a series host:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Looks for suitable axes in its series host's axes collection&lt;/li&gt;

  &lt;li&gt;If no axes are found it creates the axes it needs and adds them to its series host's collection of axes&lt;/li&gt;

  &lt;li&gt;Adds itself to each axes' collection of registered listeners&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A well-behaved series does the following when it is removed from a series host:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Removes itself from each axes' collection of registered listeners&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we follow the steps above our stock series can share the same axes with other series.&amp;#160; We will also ensure that developers won't have to explicitly add appropriate axes to the chart's axes collection before they can use our series.&amp;#160; &lt;/p&gt;

&lt;p&gt;There are three axes available in Silverlight Charts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;LinearAxis &lt;/li&gt;

  &lt;li&gt;DateTimeAxis &lt;/li&gt;

  &lt;li&gt;CategoryAxis &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One approach would be too look for a horizontal DateTimeAxis and a vertical LinearAxis in the series host's axes collection when the SeriesHost property changes.&amp;#160; While this approach &lt;em&gt;would&lt;/em&gt; work it would be sub-optimal.&amp;#160; In addition to allowing custom series, Silverlight Charts also allows custom axes.&amp;#160; We'd like our series to be able to use any axes added in the future (ex. LogarithmicAxis) as well as axes added by third-parties.&amp;#160; Let's take a look at the axis hierarchy.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_HI1qT6wpc4w/ScqEXUj3IVI/AAAAAAAAAK8/GTzyRQII65E/blogimage108.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="243" alt="blogimage10" src="http://lh3.ggpht.com/_HI1qT6wpc4w/ScqEX4T5PSI/AAAAAAAAALA/ft55xzYjo_4/blogimage10_thumb2.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;You might be feeling a little overwhelmed but &lt;strong&gt;don't worry&lt;/strong&gt; :-).&amp;#160; We're primarily interested in the interfaces and I'll explain those one by one.&amp;#160; &lt;/p&gt;

&lt;p&gt;Let's take a look at the axes acquisition code in our StockSeries class.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:2c3c3584-905a-4286-9428-88733e1a5bba" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; IAxis IndependentAxis { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; IRangeAxis DependentAxis { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnSeriesHostPropertyChanged(ISeriesHost oldValue, ISeriesHost newValue)
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (newValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.IndependentAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            newValue.Axes
                .OfType&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;IAxis&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;()
                .Where(axis &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; axis.CanPlot(DateTime.Now) &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; axis.Orientation &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; AxisOrientation.X)
                .FirstOrDefault();

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.IndependentAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
        {
            IndependentAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DateTimeAxis { Orientation &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; AxisOrientation.X };
            newValue.Axes.Add(IndependentAxis);
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.IndependentAxis.RegisteredListeners.Add(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;);

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.DependentAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            newValue.Axes
                .OfType&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;IRangeAxis&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;()
                .Where(rangeAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; rangeAxis.CanPlot(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; rangeAxis.Orientation &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; AxisOrientation.Y)
                .FirstOrDefault();

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.DependentAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
        {
            DependentAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; LinearAxis { Orientation &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; AxisOrientation.Y };
            newValue.Axes.Add(DependentAxis);
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.DependentAxis.RegisteredListeners.Add(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
    }
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;
    {
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.IndependentAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.IndependentAxis.RegisteredListeners.Remove(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
        }

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.DependentAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.DependentAxis.RegisteredListeners.Remove(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
        }
    }
    AcquireDataPointStyle();
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;base&lt;/span&gt;&lt;span style="color: #000000;"&gt;.OnSeriesHostPropertyChanged(oldValue, newValue);
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;One immediate side-effect of this general approach is that we can use a CategoryAxis on the horizontal in addition to a DateTimeAxis because category axes can plot dates as well.&lt;/p&gt;

&lt;p&gt;When we acquire an axis we add ourselves to its registered listeners collection.&amp;#160; When the axis changes it will call the AxisInvalidated method on all its registered and we'll get the opportunity to update our data points.&amp;#160; Now we're ready for the main event...&lt;/p&gt;

&lt;h3&gt;Plotting the Data Points&lt;/h3&gt;

&lt;p&gt;When the &amp;quot;Refresh&amp;quot; method of the base Series class is called our series is expected to retrieve data from its data source and plot its data points.&amp;#160; Let's create an &amp;quot;UpdateDataPoints&amp;quot; method which will plot a sequence of data points and invoke it in the &amp;quot;Refresh&amp;quot; method.&amp;#160; &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:c46ca632-c4ad-43bd-b99e-3124bca8132b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Refresh()
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (IndependentAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; DependentAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; PlotArea &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ItemsSource &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
            {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.PlotArea.Children.Clear();
                _dataPoints &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                    ItemsSource
                        .Cast&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;()
                        .Select(obj &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; CreateStockDataPoint(obj))
                        .ToDictionary(dataPoint &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; dataPoint.DataContext);
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (StockDataPoint dataPoint &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; _dataPoints.Values)
                {
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.PlotArea.Children.Add(dataPoint);
                }

                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Dispatcher.BeginInvoke(() &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; UpdateDataPoints(_dataPoints.Values));
            }
        }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Notice that instead of updating the data points synchronously we use BeginInvoke.&amp;#160; This will delay the process until after a layout pass has occurred.&amp;#160; This gives Silverlight/WPF the opportunity to apply the template to our data point controls.&amp;#160; This is important as we will need to know the final width of the data points in order to center them along the X axis.&amp;#160; Now let's write the methods that do the important work of positioning the data points.&amp;#160; &lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:98839bf1-7dc3-4526-afa9-608e68c46788" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; UpdateDataPoints(IEnumerable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;StockDataPoint&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; dataPoints)
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (var dataPoint &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; dataPoints)
    {
        UpdateDataPoint(dataPoint);
    }
}

&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; UpdateDataPoint(StockDataPoint dataPoint)
{
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; GetPlotAreaCoordinate returns a nullable value because the value 
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; may or may not be present on the axis.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    var dateCoordinateUnitValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; IndependentAxis.GetPlotAreaCoordinate(dataPoint.Date);
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (dateCoordinateUnitValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; dateCoordinateUnitValue.Value.Unit &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; Unit.Pixels)
    {
        
        var nullableHighCoordinateUnitValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; DependentAxis.GetPlotAreaCoordinate(dataPoint.High);
        var nullableLowCoordinateUnitValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; DependentAxis.GetPlotAreaCoordinate(dataPoint.Low);
        var nullableCloseCoordinateUnitValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; DependentAxis.GetPlotAreaCoordinate(dataPoint.Close);

        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (nullableHighCoordinateUnitValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; nullableHighCoordinateUnitValue.Value.Unit &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; Unit.Pixels
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; nullableLowCoordinateUnitValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; nullableLowCoordinateUnitValue.Value.Unit &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; Unit.Pixels
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; nullableCloseCoordinateUnitValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; nullableCloseCoordinateUnitValue.Value.Unit &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; Unit.Pixels)
        {
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Subtract all Y coordinates from the height of the plot
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; area canvas to invert the Y axis.  The ensures that 
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; larger values appear higher than smaller ones.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;            var highPixelValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; PlotArea.ActualHeight &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; nullableHighCoordinateUnitValue.Value.Value;
            var lowPixelValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; PlotArea.ActualHeight &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; nullableLowCoordinateUnitValue.Value.Value;
            var closePixelValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; PlotArea.ActualHeight &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; nullableCloseCoordinateUnitValue.Value.Value;

            var dataPointHeight &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; lowPixelValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; highPixelValue;
            var closeCoordinate &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; closePixelValue &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; highPixelValue;
            dataPoint.CloseCoordinate &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; closeCoordinate;
            dataPoint.Height &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; dataPointHeight;

            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; center our stock data point on the X point&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;            Canvas.SetLeft(dataPoint, dateCoordinateUnitValue.Value.Value &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; (dataPoint.ActualWidth &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;));
            Canvas.SetTop(dataPoint, highPixelValue);
        }
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;The GetPlotAreaCoordinate method of the IAxis type is important to understand.&amp;#160; Rather than a double this method returns a nullable UnitValue object.&amp;#160; This value is nullable because a given value may not exist on an axis.&amp;#160; For example negative values cannot exist on a logarithmic axis.&amp;#160; Also certain values may or may not be present on a category axis.&lt;/p&gt;

&lt;p&gt;The UnitValue object is composed of a double Value property and an enum Unit property value which can be either Pixels or Degrees.&amp;#160; Although there aren't current any axes in Silverlight Charts that return Degree values this may change in the future to support radial axes.&amp;#160; For the time being our series will only render pixel values.&lt;/p&gt;

&lt;p&gt;Now we're ready to implement our AxisInvalidated method.&amp;#160; All we need to do is call UpdateDataPoints!&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:c164d56e-88f7-4506-b29c-c77268366e11" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; AxisInvalidated(IAxis axis)
{
    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;Refresh();&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    UpdateDataPoints(_dataPoints.Values);
}
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Given the following XAML...&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:f4ae1da7-c44e-41c3-8d38-b69eed592516" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;charting:Chart x:Name&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;chart&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;charting:Chart.Axes&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;charting:DateTimeAxis Orientation&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;X&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;charting:LinearAxis Orientation&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;Y&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;charting:Chart.Axes&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
            &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;local:StockSeries Title&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;My First Series&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;charting:Chart&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;...we should be able to see our series.&amp;#160; Drumroll please...&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_HI1qT6wpc4w/ScqEYcHGSNI/AAAAAAAAALE/me_uUVLFL4k/emptyseries2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="185" alt="emptyseries" src="http://lh4.ggpht.com/_HI1qT6wpc4w/ScqEYzPiZoI/AAAAAAAAALI/Zde_YeG41W4/emptyseries_thumb.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Oops.&amp;#160; So what went wrong?&amp;#160; Why didn't our data points get plotted?&lt;/p&gt;

&lt;p&gt;In fact our data points &lt;em&gt;were&lt;/em&gt; plotted, it's just that they are outside of the visible range of the Y axis.&amp;#160; Notice that the range on the Y axis is 0 to 1.&amp;#160; Turns out that just as an axis needs to communicate with a series when it changes, a series must also communicate information to its axes.&amp;#160; In this case the series must communicate its data range to the axes so that the axes can select an appropriate range.&lt;/p&gt;

&lt;h4&gt;Helping the Axis Pick a Better Range&lt;/h4&gt;

&lt;p&gt;In order to get the axis to choose a range that is appropriate for our data we'll implement IRangeProvider.&amp;#160; Let's take a look at how an IRangeProvider interacts with an IRangeAxis.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_HI1qT6wpc4w/ScqEZYLZNnI/AAAAAAAAALM/inVxaWi9K4M/rangeaxis2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="78" alt="rangeaxis" src="http://lh5.ggpht.com/_HI1qT6wpc4w/ScqEZmOcPpI/AAAAAAAAALQ/PuiEmTtwrxQ/rangeaxis_thumb.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We implement the IRangeProvider.GetRange method so the axis can query the series to determine an appropriate range to display.&amp;#160; When a range consumer requests a range it passes itself to the GetRange method.&amp;#160; This allows us to determine which axis is requesting the range, the dependent axis or the independent axis.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:e3bfe473-f944-4685-80d7-fbf647deedbb" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; StockSeries : Series, IRequireGlobalSeriesIndex, IAxisListener, IRangeProvider
    {
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; Range&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;IComparable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetRange(IRangeConsumer rangeConsumer)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (_dataPoints.Any())
            {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (rangeConsumer &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; IndependentAxis)
                {
                    DateTime minimum &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; _dataPoints.Values.Select(dataPoint &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; dataPoint.Date).Min();
                    DateTime maximum &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; _dataPoints.Values.Select(dataPoint &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; dataPoint.Date).Max();
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Range&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;IComparable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(minimum, maximum);
                }
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (rangeConsumer &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; DependentAxis)
                {
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;double&lt;/span&gt;&lt;span style="color: #000000;"&gt; minimum &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; _dataPoints.Values.Select(dataPoint &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; dataPoint.Low).Min();
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;double&lt;/span&gt;&lt;span style="color: #000000;"&gt; maximum &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; _dataPoints.Values.Select(dataPoint &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; dataPoint.High).Max();
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Range&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;IComparable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(minimum, maximum);
                }
            }
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Range&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;IComparable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;();
        }

    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now the range axis can determine the best range to use to display our series data.&amp;#160; That's only half of the equation though.&amp;#160; The series also needs to be able to inform the axis that its range has changed.&amp;#160; The best time to do this is in the Refresh method after we load our data.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:17c98562-e642-454d-b26a-efa29938263e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Refresh()
{
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (IndependentAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; DependentAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; PlotArea &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ItemsSource &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
    {
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Dispatcher.BeginInvoke(
            () &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
            {
                UpdateDataPoints(_dataPoints.Values);
                {
                    {
                        IRangeConsumer rangeConsumer &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; IndependentAxis &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;as&lt;/span&gt;&lt;span style="color: #000000;"&gt; IRangeConsumer;
                        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (rangeConsumer &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
                        {
                            rangeConsumer.RangeChanged(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;, GetRange(rangeConsumer));
                        }
                    }
                    {
                        IRangeConsumer rangeConsumer &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; DependentAxis &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;as&lt;/span&gt;&lt;span style="color: #000000;"&gt; IRangeConsumer;
                        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (rangeConsumer &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
                        {
                            rangeConsumer.RangeChanged(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;, GetRange(rangeConsumer));
                        }
                    }
                }
            });
    }
}
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Now&lt;/em&gt; we should be able to see our series in action...&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_HI1qT6wpc4w/ScqEaDW_l4I/AAAAAAAAALU/PFzYJ7n36sU/seriesinaction2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="seriesinaction" src="http://lh5.ggpht.com/_HI1qT6wpc4w/ScqEag2EjHI/AAAAAAAAALY/sGKDn5GhUBo/seriesinaction_thumb.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Hmmm, looks &lt;em&gt;okay&lt;/em&gt;.&amp;#160; Our data points have got a nice looking gradient and they've been plotted properly.&amp;#160; &lt;/p&gt;

&lt;p&gt;The problem is that our far left and far right data points stretch outside of the chart.&amp;#160; The axis is doing its job and picking a range that encompasses all our data.&amp;#160; The problem is that our data points have a display width in addition to a data value.&amp;#160; &lt;/p&gt;

&lt;p&gt;What we'd really like is for the axis to pick a range large enough so that both our data and our visual objects will fit inside of the series.&amp;#160; So how do we do that?&lt;/p&gt;

&lt;h4&gt;Making Room With ValueMargins&lt;/h4&gt;

&lt;p&gt;In order to help an axis balance display concerns and data concerns Silverlight Charts provides a ValueMargin object.&amp;#160; A value margin is a data value with a high and low margin value in pixels.&amp;#160; When an axis is provided with value margins in addition to a range it will try and find a range large enough such that a series data &lt;em&gt;and&lt;/em&gt; its graphical objects can be displayed inside of the Chart.&lt;/p&gt;

&lt;p&gt;The IValueMarginProvider and IValueMarginConsumer interfaces work in a way very similar to the IRangeProvider and IRangeConsumer interfaces:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_HI1qT6wpc4w/ScqEbHkQOKI/AAAAAAAAALc/0ayl5GXKwIU/valuemargins%5B2%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="74" alt="valuemargins" src="http://lh4.ggpht.com/_HI1qT6wpc4w/ScqEbUyMXvI/AAAAAAAAALg/9yHC2serbjs/valuemargins_thumb.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Let's implement IValueMarginProvider.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:63ba96cf-7da0-44e9-aa51-ef378fea3fd2" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; StockSeries : Series, IRequireGlobalSeriesIndex, IAxisListener, IRangeProvider, IValueMarginProvider
    {
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;snip...&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; IEnumerable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;ValueMargin&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetValueMargins(IValueMarginConsumer consumer)
        {
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; We only need to worry about value margins on the X axis.
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; On the Y axis the top and bottom of the data point always 
            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; correspond to the value location on the axis.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (consumer &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; IndependentAxis &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; consumer &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;is&lt;/span&gt;&lt;span style="color: #000000;"&gt; IRangeAxis)
            {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (_dataPoints.Values.Any())
                {
                    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; We return the width of only minimum and maximum data 
                    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; points.  The other information is unnecessary.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;                    StockDataPoint minimumStockDataPoint &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; EnumerableFunctions.Min(_dataPoints.Values, dataPoint &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; dataPoint.Date);
                    StockDataPoint maximumStockDataPoint &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; EnumerableFunctions.Max(_dataPoints.Values, dataPoint &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; dataPoint.Date);
                    var halfWidth &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; minimumStockDataPoint.Width &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]
                    {
                        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ValueMargin(minimumStockDataPoint.Date, halfWidth, halfWidth),
                        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ValueMargin(maximumStockDataPoint.Date, halfWidth, halfWidth),
                    };

                }
            }
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ValueMargin[] { };
        }
    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Notice that we're only worried about returning value margins to the independent (X) axis.&amp;#160; That's because the top and bottom of a data point on a stock chart always line up with a value on the axis (lest they be misleading).&lt;/p&gt;

&lt;p&gt;To make life easier I've written some helper functions: Min and Max.&amp;#160; These functions work by accepting a function that they apply to each data point.&amp;#160; The function returns a value wh
