<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>mwinkle.blog</title><link>http://blogs.msdn.com/b/mwinkle/</link><description /><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>Microsoft HDInsight Installation &amp; Dependency Management</title><link>http://blogs.msdn.com/b/mwinkle/archive/2012/12/16/microsoft-hdinsight-installation-amp-dependency-management.aspx</link><pubDate>Sun, 16 Dec 2012 21:58:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10378509</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=10378509</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2012/12/16/microsoft-hdinsight-installation-amp-dependency-management.aspx#comments</comments><description>&lt;p&gt;It’s a rainy Saturday afternoon here in Seattle, and the kids are keeping themselves busy running around the Christmas tree, so I’ve got a little time to put together a post that addresses some questions that have come up a few times in the &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/hdinsight"&gt;forums&lt;/a&gt; as well as in our internal discussion aliases for our on-premises install of HDInisght.&lt;/p&gt;  &lt;p&gt;We currently use the &lt;a href="http://www.microsoft.com/web/downloads/platform.aspx"&gt;Web Platform Installer&lt;/a&gt; to take care of dependency management of the installation.&amp;#160; &lt;/p&gt;  &lt;p&gt;It’s important to point out that there are actually two key pieces that get installed&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The installation of the &lt;a href="http://hortonworks.com/products/hortonworksdataplatform/"&gt;Hortonworks Data Platform&lt;/a&gt; for Windows&lt;/li&gt;    &lt;li&gt;The installation for &lt;a href="http://blogs.technet.com/b/serverandtools/archive/2012/10/24/microsoft-hdinsight-server-for-windows-and-windows-azure-hdinsight-service-announced.aspx"&gt;Microsoft HDInsight&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The second has a dependency on the first.&amp;#160; The WebPI feed also contains a number of pre-requisites required to set up IIS and a few other things for the HDInsight dashboard.&amp;#160; Here’s what it looks like on a completely fresh Windows Server 2012 machine.&amp;#160; Most developer machines likely have some or most of the IIS pre-reqs installed.&amp;#160; We’re also working to clean up some of this to minimize installation &amp;amp; setup. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-62-69-metablogapi/6545.image_5F00_09C1BA4B.png"&gt;&lt;img title="image" style="display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-62-69-metablogapi/5481.image_5F00_thumb_5F00_344D755B.png" width="566" height="718" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Let’s talk a little bit about what’s in each one.&lt;/p&gt;  &lt;h1&gt;Hortonworks Data Platform installer&lt;/h1&gt;  &lt;p&gt;This msi includes the core Hadoop bits (Map/Reduce, HDFS), as well as a number of other Apache projects in the Hadoop ecosystem.&amp;#160; The full list included in the current installer are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Map Reduce&lt;/li&gt;    &lt;li&gt;HDFS&lt;/li&gt;    &lt;li&gt;Hive&lt;/li&gt;    &lt;li&gt;Pig&lt;/li&gt;    &lt;li&gt;HCatalog&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Each of these projects is packaged into a zip file that contains a PowerShell script that automates the installation and setup of the component.&amp;#160; There are more components in Hortonworks Data Platform, and the teams are working to get these packaged and included.&lt;/p&gt;  &lt;h1&gt;Microsoft HDInisght Installer&lt;/h1&gt;  &lt;p&gt;This msi contains bits that are Microsoft specific, and may also contain additional Hadoop projects.&amp;#160; The current install (as of today) contains:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;HDInsight dashboard&lt;/li&gt;    &lt;li&gt;Sqoop&lt;/li&gt;    &lt;li&gt;Isotope.js&lt;/li&gt;    &lt;li&gt;Getting Started content &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;These are packaged the same way as the Hadoop projects above.&amp;#160; Additionally, there is an installation PowerShell script here which will do some initialization of the single node installer, such as starting the services for the Hadoop components.&lt;/p&gt;  &lt;h1&gt;Alternate Approaches&lt;/h1&gt;  &lt;p&gt;The team discussed a number of potential factorings, and we very much welcome feedback here.&amp;#160; A few ideas that we’ve thought about:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Stable and Experimental packages.&amp;#160; This would allow us to set expectations around quality and stability of the bits.&amp;#160; &lt;/li&gt;    &lt;li&gt;Decomposing every project into an individual msi&lt;/li&gt;    &lt;li&gt;Integrating and building a &lt;a href="http://chocolatey.org/"&gt;Chocolatey package&lt;/a&gt; for these      &lt;br /&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;What Does This Mean For Me?&lt;/h1&gt;  &lt;p&gt;What this means is that when you install HDInsight out of WebPI, you are installing two different msi’s.&amp;#160; We are revving the Microsoft msi every two weeks to pull in bug fixes (and very shortly include some experimental features).&amp;#160; The Hortonworks msi will be revved on a different schedule, as the team there decides to release an update.&amp;#160; We are partnering closely with the team there and so we will coordinate releases so that the combined installation will always work. &lt;/p&gt;  &lt;p&gt;More directly, this implies that if you want to uninstall completely, you will need to uninstall both packages from Add/Remove Programs:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-62-69-metablogapi/0513.image_5F00_71FA5D17.png"&gt;&lt;img title="image" style="display: inline; background-image: none;" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-62-69-metablogapi/0284.image_5F00_thumb_5F00_231997B8.png" width="780" height="182" /&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;This also means that when we issue an update for the Microsoft HDInsight package, you don’t have to “lose” your cluster by uninstalling both products.&amp;#160; You should be able to simply uninstall &amp;amp; update the Microsoft HDInsight package.&amp;#160; &lt;/p&gt;  &lt;p&gt;The team would love to get more feedback on this approach, so, let us know what you think!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10378509" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/Hadoop/">Hadoop</category></item><item><title>Updating HDInsight Preview</title><link>http://blogs.msdn.com/b/mwinkle/archive/2012/12/04/updating-hdinsight-preview.aspx</link><pubDate>Tue, 04 Dec 2012 16:50:24 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10374525</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=10374525</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2012/12/04/updating-hdinsight-preview.aspx#comments</comments><description>&lt;p&gt;Today we’ve shipped an update to the single node HDInsight Server Preview that is installable via &lt;a href="http://www.microsoft.com/web/handlers/webpi.ashx/getinstaller/HDINSIGHT-PREVIEW.appids"&gt;Web Platform Installer&lt;/a&gt;.&amp;#160;&amp;#160; &lt;/p&gt;  &lt;h3&gt;What Are We Doing? &lt;/h3&gt;  &lt;p&gt;Every two weeks, we’re going to take a snapshot of the work in progress and update the public installer with this (provided it passes a basic level of validation).&amp;#160; This gives us the opportunity to rapidly get new bits in front of customers, experiment with new features, and address bugs in a timely fashion.&amp;#160; &lt;/p&gt;  &lt;p&gt;We’ve also snapped versions such that releases of the &lt;a href="http://hadoopsdk.codeplex.com/"&gt;SDK&lt;/a&gt; as well as the One-Box installer will all share the same version.&amp;#160; As such, we’ve versioned the msi as 0.2.0.0. &lt;/p&gt;  &lt;h3&gt;How do I Get This?&lt;/h3&gt;  &lt;p&gt;Simply by installing HDInisght out of WebPI onto a new machine after uninstalling (in place upgrade is not currently supported).&amp;#160; To completely uninstall previous versions, you will want first uninstall “Microsoft HDInsight Community Technology Preview” and then the “Hortonworks Data Platform”.&amp;#160; &lt;b&gt;We will not preserve data in HDFS using uninstall/reinstall&lt;/b&gt;, so archive that prior to uninstalling. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-62-69-metablogapi/1641.clip_5F00_image002_5F00_3B740D48.jpg"&gt;&lt;img title="clip_image002" style="display: inline; background-image: none;" border="0" alt="clip_image002" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-62-69-metablogapi/8507.clip_5F00_image002_5F00_thumb_5F00_3454D0D0.jpg" width="691" height="150" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;What’s New?&lt;/h3&gt;  &lt;p&gt;There are no new features in this release, we’ve worked to improve some of the install and setup experience to address some bugs that have been reported on this alias as well as the forums. &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;IIS / Dashboard setup issues experienced on certain OS SKU’s&lt;/li&gt;    &lt;li&gt;Addition of HDInsight Dashboard link into Start Menu&lt;/li&gt;    &lt;li&gt;Fix to Hive console for multiple line input errors&lt;/li&gt;    &lt;li&gt;Clean up some uninstall issues&lt;/li&gt;    &lt;li&gt;Minor changes to getting started content &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Hortonworks has also shipped an update to the &lt;a href="http://hortonworks.com/products/hortonworksdataplatform/"&gt;HDP&lt;/a&gt; installation to address the bug encountered on Friday (documented &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/hdinsight/thread/28a57efb-082b-424b-8d9e-731b1fe135de"&gt;here&lt;/a&gt;).&amp;#160; By removing both installations above and re-installing, you will get updated bits here.&lt;/p&gt;  &lt;h3&gt;What if Something Doesn’t Work?&lt;/h3&gt;  &lt;p&gt;Please report issues on the &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/hdinsight/thread/28a57efb-082b-424b-8d9e-731b1fe135de"&gt;forums&lt;/a&gt;.&amp;#160; We’re also tracking a set of known issues via the &lt;a href="http://gettingstarted.hadooponazure.com/releaseNotes.html"&gt;release notes&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;When Will These Bits Be Updated In Azure?&lt;/h3&gt;  &lt;p&gt;We’re using this as an opportunity to ship these bits early and often, and they will find their way into future service updates to &lt;a href="http://www.hadooponazure.com/"&gt;Azure HDInsight&lt;/a&gt;, typically in the next monthly update.&lt;/p&gt;  &lt;h3&gt;What’s Next?&lt;/h3&gt;  &lt;p&gt;We’ll continue to address common issues as they are reported.&amp;#160; From a feature perspective, we hope the next update will include updates to the dashboard to include a new and improved Hive console. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10374525" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/Hadoop/">Hadoop</category></item><item><title>Getting Up and Running with Piggybank on HDInsight</title><link>http://blogs.msdn.com/b/mwinkle/archive/2012/11/02/getting-up-and-running-with-piggybank-on-hdinsight.aspx</link><pubDate>Sat, 03 Nov 2012 00:17:41 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10365438</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=10365438</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2012/11/02/getting-up-and-running-with-piggybank-on-hdinsight.aspx#comments</comments><description>&lt;p&gt;It’s been a fun couple of weeks launching HDInsight, and I’m going to be getting back into doing some more technical blogging.&amp;#160; There are a few easy topics off the bat that we’ve heard requested from customers.&amp;#160; The first one involves &lt;a href="https://cwiki.apache.org/confluence/display/PIG/PiggyBank"&gt;Piggybank&lt;/a&gt;, which is a user contributed collection of useful &lt;a href="http://pig.apache.org/"&gt;Pig&lt;/a&gt; user defined functions (UDF’s).&lt;/p&gt;  &lt;p&gt;This assumes your machine is set up with:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;HDInsight (grab from WebPI &lt;a href="http://www.microsoft.com/web/handlers/webpi.ashx?command=GetInstallerRedirect&amp;amp;appid=HDINSIGHT-PREVIEW&amp;amp;mode=new"&gt;here&lt;/a&gt;)&lt;/li&gt;    &lt;li&gt;Java build tools (&lt;a href="http://ant.apache.org/manual/install.html"&gt;Ant&lt;/a&gt; and &lt;a href="http://ant.apache.org/ivy/history/latest-milestone/install.html"&gt;Ivy&lt;/a&gt; on your command path)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Next, let’s build Piggybank by grabbing the Pig source code and checking out the 0.9 branch&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;font face="Consolas"&gt;git clone &lt;/font&gt;&lt;a href="https://github.com/apache/pig.git"&gt;&lt;font face="Consolas"&gt;https://github.com/apache/pig.git&lt;/font&gt;&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;font face="Consolas"&gt;git checkout -b branch-0.9 remotes/origin/branch-0.9&lt;/font&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;At this point, you should now have a pig directory, move to that and type &lt;font face="Consolas"&gt;ant&lt;/font&gt; in order to build.&lt;/p&gt;  &lt;p&gt;Next, navigate to .\contrib\piggybank\java, and again, type ant in order to build.&amp;#160; This will produce piggybank.jar.&lt;/p&gt;  &lt;p&gt;Next, open your HDInsight console window and type pig.&amp;#160; This brings up Grunt, the interactive pig shell. &lt;/p&gt;  &lt;p&gt;At this point, you can now use the following in your script:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Consolas"&gt;REGISTER C:\Your\Path\To\piggybank.jar ;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Consolas"&gt;foo = FOREACH entry GENERATE org.apache.pig.piggybank.evaluation.string.UPPER(item_name);&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;At this point, you can now take advantage of all of the functions in piggybank, and if you’re interested in contributing your own, details are &lt;a href="http://wiki.apache.org/pig/UDFManual"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10365438" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/Hadoop/">Hadoop</category></item><item><title>Every Day is a Good Day When You Paint</title><link>http://blogs.msdn.com/b/mwinkle/archive/2012/07/30/every-day-is-a-good-day-when-you-paint.aspx</link><pubDate>Mon, 30 Jul 2012 16:37:57 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10334850</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=10334850</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2012/07/30/every-day-is-a-good-day-when-you-paint.aspx#comments</comments><description>&lt;p&gt;Slightly off-topic, but a friend of mine posted a video on Facebook that struck me as being very relevant to our space.&amp;#160; &lt;/p&gt;  &lt;div id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:61225bc1-ff2b-492d-8e7e-33f4e89030e3" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; float: none; display: inline;"&gt;&lt;div&gt;&lt;object width="448" height="252"&gt;&lt;param name="movie" value="http://www.youtube.com/v/YLO7tCdBVrA?hl=en&amp;amp;hd=1"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/YLO7tCdBVrA?hl=en&amp;amp;hd=1" type="application/x-shockwave-flash" width="448" height="252"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;At the same time I saw this, another friend and co-worker was having a fairly crummy day with lots of crazy meetings and requests from co-workers, but that day was made a lot better by sitting down and solving a fun little deployment script problem.&amp;#160; The deployment script is neither here nor there, it was more that so many of the folks in this industry love solving a problem, whether that is getting a query right, chasing down a pesky bug, or getting that a-ha moment when you are trying to design something.&amp;#160; That’s “painting” for a lot of us.&amp;#160; &lt;/p&gt;  &lt;p&gt;Every day is a good day when you paint.&lt;/p&gt;  &lt;p&gt;[and working auto-tuned Bob Ross into a blog post was just too good to pass up]&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10334850" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/work_2F00_life+balance/">work/life balance</category></item><item><title>Writing a Map/Reduce Job for Hadoop using Windows PowerShell</title><link>http://blogs.msdn.com/b/mwinkle/archive/2012/07/20/writing-a-map-reduce-job-for-hadoop-using-windows-powershell.aspx</link><pubDate>Sat, 21 Jul 2012 01:25:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10332149</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=10332149</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2012/07/20/writing-a-map-reduce-job-for-hadoop-using-windows-powershell.aspx#comments</comments><description>&lt;p&gt;I had a little bit of time on my hand and wanted to whip up a quick sample using PowerShell for a Hadoop job.&lt;/p&gt;  &lt;p&gt;This uses the Hadoop &lt;a href="http://hadoop.apache.org/common/docs/r1.0.3/streaming.html"&gt;streaming&lt;/a&gt; capability, which essentially allows for mappers and reducers to be written as arbitrary executables that operate on standard input and output.&lt;/p&gt;  &lt;p&gt;The .ps1 scripts are pretty simple, these operate over a set of airline data that looks like this:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;0,EV,18,0,MIA,2011-12-18T00:00:00,12,TPA,1227859,2011    
0,EV,17,0,MIA,2011-12-17T00:00:00,12,TPA,1227860,2011    
6,EV,17,4,CLE,2011-12-17T00:00:00,12,ATL,1227861,2011&lt;/pre&gt;


&lt;p&gt;The schema here is a comma separated set of US flights with delays. &lt;/p&gt;

&lt;p&gt;The goal of my job is to pull out the airlines, the number of flights, and then some very basic (min and max) statistics on the arrival and departure delays.&amp;#160; &lt;/p&gt;

&lt;p&gt;My mapper:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; Map-Airline &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    [Console]::Error.WriteLine( &lt;span class="str"&gt;&amp;quot;reporter:counter:powershell,invocations,1&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    $line = [Console]::ReadLine()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt; ($line &lt;span class="preproc"&gt;-ne&lt;/span&gt; $null) &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        [Console]::WriteLine($line.Split(&lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;)[1] + &lt;span class="str"&gt;&amp;quot;`t&amp;quot;&lt;/span&gt; + $line)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        [Console]::Error.WriteLine(&lt;span class="str"&gt;&amp;quot;reporter:counter:powershell,record,1&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        $line = [Console]::ReadLine()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    }  &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;}&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;Map-Airline &lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;My reducer:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; Reduce-Airlines&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    $line = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    $oldLine = &lt;span class="str"&gt;&amp;quot;&amp;lt;initial invalid row value&amp;gt;&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    $count = 0&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    $minArrDelay = 10000&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    $maxArrDelay = 0&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    $minDepDelay = 10000 &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    $maxDepDelay = 0 &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    $line = [Console]::ReadLine()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt;  ($line &lt;span class="preproc"&gt;-ne&lt;/span&gt; $null)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (($oldLine &lt;span class="preproc"&gt;-eq&lt;/span&gt; $line.Split(&lt;span class="str"&gt;&amp;quot;`t&amp;quot;&lt;/span&gt;)[0]) -or ($oldLine &lt;span class="preproc"&gt;-eq&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;&amp;lt;initial invalid row value&amp;gt;&amp;quot;&lt;/span&gt;))&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            $flightRecord = $line.Split(&lt;span class="str"&gt;&amp;quot;`t&amp;quot;&lt;/span&gt;)[1].Split(&lt;span class="str"&gt;','&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; ([Int32]::Parse($flightRecord[0]) &lt;span class="preproc"&gt;-ne&lt;/span&gt; 0) &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;                $minArrDelay = [Math]::Min($minArrDelay, $flightRecord[0])&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; ([Int32]::Parse($flightRecord[3]) &lt;span class="preproc"&gt;-ne&lt;/span&gt; 0) &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;                $minDepDelay = [Math]::Min($minDepDelay, [Int32]::Parse($flightRecord[3]))&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;            $maxArrDelay = [Math]::Max($maxArrDelay, $flightRecord[0])&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;            $maxDepDelay = [Math]::Max($maxDepDelay, $flightRecord[3])&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;            $count = $count+ 1&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;            [Console]::Error.WriteLine( &lt;span class="str"&gt;&amp;quot;reporter:counter:powershell,&amp;quot;&lt;/span&gt;+$oldLine + &lt;span class="str"&gt;&amp;quot;,1&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;        &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;            [Console]::WriteLine($oldLine + &lt;span class="str"&gt;&amp;quot;`t&amp;quot;&lt;/span&gt; + $count + &lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt; + $minArrDelay + &lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt; +$maxArrDelay + &lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt; + $minDepDelay +&lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;+ $maxDepDelay)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;            $count = 1&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;            $minArrDelay = 10000&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;            $maxArrDelay = 0&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;            $minDepDelay = 10000 &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;            $maxDepDelay = 0 &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;            [Console]::Error.WriteLine(&lt;span class="str"&gt;&amp;quot;reporter:counter:powershell,&amp;quot;&lt;/span&gt;+$oldLine + &lt;span class="str"&gt;&amp;quot;,1&amp;quot;&lt;/span&gt;)           &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;        $oldLine = $line.Split(&lt;span class="str"&gt;&amp;quot;`t&amp;quot;&lt;/span&gt;)[0]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;        $line = [Console]::ReadLine()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;    [Console]::WriteLine($oldLine + &lt;span class="str"&gt;&amp;quot;`t&amp;quot;&lt;/span&gt; + $count + &lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt; + $minArrDelay + &lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt; +$maxArrDelay + &lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt; + $minDepDelay +&lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;+ $maxDepDelay)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;}&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  46:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  47:  &lt;/span&gt;Reduce-Airlines&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;One thing to note on the reducer is that we use the $oldLine variable in order to keep tabs on when our group of results is moving to the next one.&amp;#160; When using Java, your reduce function will be invoked once per group and so you can reset the state at the beginning of each of those.&amp;#160; With streaming, you will never have groups that split reducers, but your executable will only be spun up once per reducer (which, in the sample here, is one).&amp;#160; You can also see that I’m writing out to STDERR in order to get a few counters recorded as well. &lt;/p&gt;

&lt;p&gt;The next trick is to get these to execute.&amp;#160; The process spawned by the Streaming job does not know about .ps1 files, it’s basically just cmd.exe.&amp;#160; To get around that we will also create a small driver .cmd file and upload the file with the –file directive from the command line.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;AirlineMapperPs.cmd&lt;/p&gt;

&lt;pre class="csharpcode"&gt;@call c:\windows\system32\WindowsPowerShell\v1.0\powershell -file ..\..\jars\AirlineMapper.ps1&lt;/pre&gt;


&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;AirlineReducerPs.cmd&lt;/p&gt;

&lt;pre class="csharpcode"&gt;@call c:\windows\system32\WindowsPowerShell\v1.0\powershell -file ..\..\jars\AirlineReducer.ps1&lt;/pre&gt;


&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The ..\..\jars directory is where the –file directive will place the files when they execute&lt;/p&gt;

&lt;p&gt;And now we execute:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;hadoop jar %HADOOP_HOME%\lib\hadoop-streaming.jar 
    -mapper d:\dev\_full_path_\AirlineMapperPs.cmd 
    -reducer d:\dev\_full_path_\AirlineReducerPs.cmd 
    -input fixed_flights 
    -output psMapReduce3 
    -file d:\dev\_full_path_\AirlineMapper.ps1 
    -file d:\dev\_full_path_\AirlineReducer.ps1&lt;/pre&gt;


&lt;p&gt;And we get our results.&lt;/p&gt;

&lt;p&gt;There is still some work to be done here, I’d like to make it a little easier to get these running (so possibly wrapping submission in a script which takes care of the wrapping for me).&amp;#160; Also, on Azure, we either need to sign the scripts, or log into each of the machines and allow script execution.&amp;#160; As I get that wrapped up, I’ll drop it along side our other samples.&amp;#160; We’ll also work to make this easier to get up and running on Azure if that’s interesting for folks.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10332149" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/PowerShell/">PowerShell</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/Hadoop/">Hadoop</category></item><item><title>Talking About Hadoop on Windows</title><link>http://blogs.msdn.com/b/mwinkle/archive/2012/06/09/talking-about-hadoop-on-windows.aspx</link><pubDate>Sat, 09 Jun 2012 17:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10317901</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=10317901</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2012/06/09/talking-about-hadoop-on-windows.aspx#comments</comments><description>&lt;p&gt;A few folks have asked, so I decided to put the data in one place. &amp;nbsp;We'll be talking more about Hadoop at &lt;a href="http://channel9.msdn.com/Events/TechEd/NorthAmerica/2012"&gt;TechEd North America&lt;/a&gt; and &lt;a href="http://hadoopsummit.org/"&gt;Hadoop Summit&lt;/a&gt; next week, and then later in the month at&lt;a href="http://europe.msteched.com/"&gt; TechEd Europe&lt;/a&gt;. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here are the sessions we're presenting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TechEd (&lt;a href="http://channel9.msdn.com/Events/TechEd/NorthAmerica/2012?sort=sequential&amp;amp;direction=desc&amp;amp;term=Hadoop"&gt;NA&lt;/a&gt; and &lt;a href="http://europe.msteched.com/Sessions?q=hadoop"&gt;Europe&lt;/a&gt;, links are to NA sessions)&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://channel9.msdn.com/Events/TechEd/NorthAmerica/2012/AZR325"&gt;Learn Big Data Application Development on Windows Azure&lt;/a&gt; -- Wenming Ye&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Web 2.0 companies have been fully taking advantage of Hadoop based open source tools to tackle Big Data needs. Microsoft now offers the best of both worlds with its own Hadoop solution on Windows Azure with full compatibility and additional rich toolsets. This session is a "getting-started" tutorial on developing Big Data applications on Windows Azure. We cover application scenarios, Hadoop on Azure, tools, and applied data analytics. More importantly, we show you how to put everything together with a couple of sample applications&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;a href="http://channel9.msdn.com/Events/TechEd/NorthAmerica/2012/DBI209"&gt;Big Data, Big Deal?&lt;/a&gt; -- Gert Drapers&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Are you ready for the exploding world of big data? Do you know the difference between Hive and Pig? Do you know why MapReduce is being taught in many universities rather than SQL? If not, pay attention because this talk will help get you started in understanding this new world. While sometimes the Hadoop toolkit (which includes HDFS, MapReduce, Hive, Pig, and Sqoop) is used as an alternative to relational database systems such as SQL Server, more frequently customers are using it as a complementary tool. Sometimes it may be used as an ETL tool or to perform an initial analysis of a freshly acquired data set to determine whether or not it is worth loading into the data warehouse, and sometimes to process massive data sets that are too big to even contemplate loading into all but the very largest data warehouses. In addition to covering the basics of the various parts of the Hadoop stack, this talk discusses the strengths and weakness of the Hadoop approach compared to that provided by relational database systems and explores how the two technologies can be used productively in conjunction with one another.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;a href="http://channel9.msdn.com/Events/TechEd/NorthAmerica/2012/DBI210"&gt;Harnessing Big Data With Hadoop&lt;/a&gt;&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Attend this session to learn about the Hadoop Big Data solution from Microsoft that unlocks insights on all your data, including structured and unstructured data of any size. Accelerate your analytics with a Hadoop service that offers integration with Microsoft BI and the ability to enrich your models with publicly available data. Finally, learn about our roadmap for Hadoop on Windows Server and Windows Azure and for broadening access to Hadoop through simplified deployment, management and programming, including JavaScript integration&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;li&gt;Hadoop Summit&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Unleash Insights On All Data With Microsoft Big Data -- Tim Mallalieu&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Do you plan to extract insights from mountains of data, including unstructured data that is growing faster than ever? Attend this session to learn about Microsoft&amp;rsquo;s Big Data solution that unlocks insights on all your data, including structured and unstructured data of any size. Accelerate your analytics with a Hadoop service that offers deep integration with Microsoft BI and the ability to enrich your models with publicly available data from outside your firewall. Come and see how Microsoft is broadening access to Hadoop through dramatically simplified deployment, management and programming, including full support for JavaScript.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;How Klout is changing the landscape of social media with Hadoop and BI --&lt;a href="http://dennyglee.com/"&gt; Denny Lee&lt;/a&gt;, David Mariani (VP of Engineering, Klout)&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;In this age of Big Data, data volumes grow exceedingly larger while the technical problems and business scenarios become more complex. Compounding these complexities, data consumers are demanding faster analysis to common business questions asked of their Big Data. This session provides concrete examples of how to address this challenge. We will highlight the use of Big Data technologies&amp;mdash;including Hadoop and Hive &amp;mdash;with classic BI systems such as SQL Server Analysis Services.&lt;br /&gt;&lt;br /&gt;Session takeaways:&lt;br /&gt;&amp;bull; Understand the architectural components surrounding Hadoop, Hive, Classic BI, and the Tier-1 BI ecosystem&lt;br /&gt;&amp;bull; Get strategies for addressing the technical issues when working with extremely large cubes&lt;br /&gt;&amp;bull; See how to address the technical issues when working with Big Data systems from the DBA perspective&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;p&gt;I think that there is a pretty nice mix of Hadoop, Microsoft plans, and applications across these sessions. &amp;nbsp;Hope you get a chance to see them (or watch them after the events!)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10317901" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/presentations/">presentations</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/Hadoop/">Hadoop</category></item><item><title>Tap, tap, tap, is this thing on? </title><link>http://blogs.msdn.com/b/mwinkle/archive/2012/05/08/tap-tap-tap-is-this-thing-on.aspx</link><pubDate>Tue, 08 May 2012 21:25:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10302602</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=10302602</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2012/05/08/tap-tap-tap-is-this-thing-on.aspx#comments</comments><description>&lt;p&gt;I'll be back to bloging here in a bit. &amp;nbsp;Since you last visited, I've had a fun journey working further on Workflow, Azure and now I've landed in the SQL team working on Hadoop, in particular, the developer story.&lt;/p&gt;
&lt;p&gt;Not a lot to say right now, but make sure to check out &lt;a href="http://www.hadooponAzure.com"&gt;hadoopOnAzure.com&lt;/a&gt; !&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10302602" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/Hadoop/">Hadoop</category></item><item><title>Thoughts on Flowchart</title><link>http://blogs.msdn.com/b/mwinkle/archive/2010/08/13/thoughts-on-flowchart.aspx</link><pubDate>Fri, 13 Aug 2010 22:45:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10050038</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=10050038</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2010/08/13/thoughts-on-flowchart.aspx#comments</comments><description>&lt;p&gt;Last night I saw that Maurice had a few tweets that caught my attention about flowchart, but this is the one that I want to talk about:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a&gt;&lt;em&gt;&lt;font color="#d16349"&gt;&lt;/font&gt;&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&lt;font color="#d16349"&gt;Come to think of it I also really mis a parallel execution in a flowchart. But other than that flowcharts rock! &lt;/font&gt;&lt;/em&gt;&lt;a href="http://twitter.com/search?q=%23wf4"&gt;&lt;em&gt;&lt;font color="#d16349"&gt;#wf4&lt;/font&gt;&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&lt;font color="#d16349"&gt; &lt;/font&gt;&lt;/em&gt;&lt;a href="http://twitter.com/search?q=%23dm"&gt;&lt;em&gt;&lt;font color="#d16349"&gt;#dm&lt;/font&gt;&lt;/em&gt;&lt;/a&gt;&lt;a href="http://twitter.com/mauricedb/status/21049127741"&gt;&lt;em&gt;&lt;font color="#d16349"&gt;about 13&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&lt;font color="#d16349"&gt;hours ago&lt;/font&gt;&lt;/em&gt;&lt;em&gt;&lt;font color="#d16349"&gt; via web&lt;/font&gt;&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I thought about replying on twitter, but it’s a bit of a longer topic.&amp;#160;&amp;#160; When we were building the flowchart for VS2010, we considered a number of possible capabilities, but ultimately the capabilities customers were looking for fell into two categories:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Arbitrary rework patterns&lt;/li&gt;    &lt;li&gt;Coordination patterns&lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;&lt;/h1&gt;  &lt;h1&gt;&lt;strong&gt;&lt;em&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/h1&gt;  &lt;h1&gt;Arbitrary Rework&lt;/h1&gt;  &lt;p&gt;We can describe the model of execution in the current flowchart to be one that supports arbitrary rework.&amp;#160; You could also refer to this as GOTO.&amp;#160;&amp;#160; One benefit (and downside) of breaking out of the tightly scoped, hierarchical execution model that we see with the Sequential style of workflows (and in most procedural languages) is the fact there exists more freedom in terms of defining the “next” step to be taken.&amp;#160; The simplest way to think about this is the following flowchart:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-62-69-metablogapi/4578.image_5F00_4E51B0FE.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-62-69-metablogapi/4643.image_5F00_thumb_5F00_1F1FC567.png" width="597" height="387" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now, this isn’t particularly interesting, and most folks who look at this will simply ask “why not a loop?”&amp;#160; which in this case is a valid question.&amp;#160; As a process gets more sophisticated (or if humans tend to be involved), the number of possible loops required gets rather tricky to manage in a sequential flow (consider the following rework scenario which includes “next steps” across conditional boundaries, and from some branches but not others. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-62-69-metablogapi/7128.image_5F00_73DB2E5F.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="image" border="0" alt="image" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-62-69-metablogapi/4478.image_5F00_thumb_5F00_4CA0E52A.png" width="579" height="604" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; Now, mathematically, we can describe the machinery in both of these machines as a set of valid transitions, and it is likely possible that there exists a complete mapping from any flowchart into procedural.&lt;/p&gt;  &lt;h1&gt;Coordination&lt;/h1&gt;  &lt;p&gt;The second pattern we consistently saw was the use of a free form style of execution in order to build complex coordination patterns.&amp;#160; The example I consistently return to (pointing back to a &lt;a href="http://blogs.msdn.com/b/mwinkle/archive/2007/05/24/different-execution-patterns-with-wf-or-going-beyond-sequential-and-state-machine.aspx"&gt;blog post&lt;/a&gt; I made back in the WF3 days)&lt;/p&gt;  &lt;p&gt;&lt;img alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DifferentExecutionPatternswithWForGoingb_CCEE/image_thumb.png" /&gt;    &lt;br /&gt;&lt;/p&gt;    &lt;br /&gt;  &lt;p&gt;Here I want to be able to coordinate a few different things, namely that 3 executes when 1 completes, 5 when 2, 4 when 1 &lt;strong&gt;AND&lt;/strong&gt; 2, 6 when 3 &lt;strong&gt;AND&lt;/strong&gt; 4 &lt;strong&gt;AND&lt;/strong&gt; 5 complete.&amp;#160; Here we’ve created a dependency graph that can’t be handled with the procedural constructs that we have.&amp;#160; How could this happen? Imagine we’re trying to model the ranking process for a series of horse races.&amp;#160; Task 3 can happen when Race 1 completes, as Task 5 can happen when Race 2 completes.&amp;#160; Task 4 represents some work that requires the data from both Races.&amp;#160; When those 3 tasks (3, 4, and 5) complete, I can move forward and take some action (like bet on the next race).&amp;#160; &lt;/p&gt;  &lt;p&gt;This type of pattern can be very powerful, and is often described by &lt;a href="http://en.wikipedia.org/wiki/Petri_net"&gt;petri-nets&lt;/a&gt;.&amp;#160; There exists a multitude of join semantics from simple AND joins to conditional joins (ranging from a simple “count” to a condition based on data).&amp;#160; &lt;/p&gt;  &lt;h1&gt;How’d we get to where we are today?&lt;/h1&gt;  &lt;p&gt;Today, the flowchart in the .NET framework only supports the former pattern, that of arbitrary rework.&amp;#160; How’d we get there.&amp;#160; While we found a lot of value in both patterns what we found when we tried to compose them, we often got into places that became very hard to have predictable execution semantics.&amp;#160;&amp;#160; The basic crux of the design issue gets to the “re-arming” of a join.&amp;#160; If I decide to jump back to task 3 at some point, what does it mean for 3 to complete?&amp;#160; Do I execute 6 again right away, do I wait for 4 and 5 to complete a second time?&amp;#160; What happens if I jump to 3 a second time?&amp;#160; Now, there certainly exist formal models for this, and things like Petri-net define a set of semantics for these things.&amp;#160; What we found though was that any expression of the model that took these things into account required a pretty deep understanding of the process model, and we lost one of the key benefits we see from a flowchart, which is that it is a simple, approachable model.&amp;#160; This is not to say that we don’t think that the Coordination pattern is useful, or that petri-nets don’t ultimately hold the unified approach,&amp;#160; we just did not have the time to implement a coordination pattern in VS 2010, and creating an approachable petri-net backed flowchart modeling style was something we’d need more time to get correct.&amp;#160; &lt;/p&gt;  &lt;h1&gt;Where does this leave us? &lt;/h1&gt;  &lt;p&gt;If you’re looking at this and saying, “but I want coordination (or a full blown petri-net)”, there are a couple of options:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Roll up your sleeves and write that activity.&amp;#160; In the blog &lt;a href="http://blogs.msdn.com/b/mwinkle/archive/2007/05/24/different-execution-patterns-with-wf-or-going-beyond-sequential-and-state-machine.aspx"&gt;post&lt;/a&gt; above, I outline how you could go about building the coordination pattern, and with the new activity model, this would be simpler.&amp;#160; The harder part is still writing a designer, and there is now some good guidance on free form designers in the source of the &lt;a href="http://wf.codeplex.com/releases/view/43586"&gt;state machine&lt;/a&gt; on codeplex.&amp;#160; &lt;/li&gt;    &lt;li&gt;Provide feedback on &lt;a href="http://connect.microsoft.com/wf"&gt;connect&lt;/a&gt;, when you do this it opens a bug in our bug database that our team is looking at daily.&amp;#160; Describe your scenario, what you’re trying to do, and what you’d like to see.&amp;#160; This type of customer feedback is vital to helping us plan the right features for the next release.&amp;#160;&amp;#160; &lt;/li&gt; &lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10050038" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/activities/">activities</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/wf4/">wf4</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/flowchart/">flowchart</category></item><item><title>Improving ModelItem with Dynamic</title><link>http://blogs.msdn.com/b/mwinkle/archive/2010/08/11/improving-modelitem-with-dynamic.aspx</link><pubDate>Wed, 11 Aug 2010 17:22:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10048993</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=10048993</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2010/08/11/improving-modelitem-with-dynamic.aspx#comments</comments><description>&lt;p&gt;Hi all, I’m back, and apologize for the delay, things have been crazy here and I’ve taken a little time off following shipping VS2010, so I’m getting back into it.&amp;#160; I’d like to talk about one of my favorite late additions to the WF4 designer programming model.&amp;#160; We added this change sometime in the RC/RTM timeframe in response to some feedback that we had gotten about the verbose-ness of programming against ModelItem. &lt;/p&gt;  &lt;p&gt;If you recall from this &lt;a href="http://bit.ly/bkUKuP"&gt;post&lt;/a&gt;, ModelItem exists to serve as a INotifyPropertyChanged (INPC) aware proxy to the underlying instance being edited within the designer. In exchange for this fairly flexible proxy layer, you get in return a pretty verbose way in which one has to interact to actually get to the data.&amp;#160; Often times there are fairly long incantations of myModelItem.Properties[“foo”].Value.Properties[“bar”].Value.GetCurrentValue() in order to actually return the data (or be able to set the value).&amp;#160; From the beginning, we had decided we wanted to optimize for the WPF XAML consumer of the model item, and so we chose to implement &lt;a href="http://bit.ly/acrBuh"&gt;ICustomTypeDescriptor&lt;/a&gt; so that WPF binding would be pretty simple (the above would result in a binding syntax of ModelItem.foo.bar).&amp;#160; &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;One quick note, looking at the definition of ModelItem itself will show that only the INPC interface is implemented.&amp;#160; However, ModelItem is an abstract type, and the implementation subclass ModelItemImpl contains the definition and implementation of the following interfaces ModelItem, IModelTreeItem, ICustomTypeDescriptor, IDynamicMetaObjectProvider&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;As we worked with some of our customers, it became clear that they were frequently using ModelItem in code as well, and so the programming model was becoming more of a problem (we had somewhat hoped that the majority of customers would be using XAML).&amp;#160; We initially went with the idea that we would create a series of Design time peers to all of the common types in WF (making a SequenceDesign, ParallelDesign, etc) which provided an identical programming surface to its peer, but under the covers in the property getters and setters would redirect to an underlying ModelItem.&amp;#160; This has the advantage that we could create the appearance of a strongly typed API surface, but has the downside that it introduces an extra type for every activity we ship, and it requires customers to create two types as well, and not just for activities, you would want one for customer too.&amp;#160; The other approach we kicked around was using the Dynamic capabilities introduced in .NET 4.&lt;/p&gt;  &lt;p&gt;It’s important to note that these are ultimately complimentary approaches, that is, it’s possible in a future framework release (or in a codeplex project if anyone is looking to for a little fun on the side) you could release the strongly typed design time peers. From a timing perspective, it was not likely that we could introduce 30+ new types in the RC/RTM release, and we had questions about the long term sustainability of requiring an additional type for activities.&amp;#160; So, we went ahead with the plan for dynamic support.&amp;#160;&amp;#160; In order to do this, we had to add an implementation of IDynamicMetaObjectProvider.&amp;#160; &lt;a href="http://srtsolutions.com/public/blog/243888"&gt;Bill Wagner&lt;/a&gt; has a good article &lt;a href="http://bit.ly/dzWh1v"&gt;here&lt;/a&gt; on the basics of doing this.&amp;#160; This requires us to implement one method, &lt;a href="http://bit.ly/ct47dp"&gt;GetMetaObject&lt;/a&gt;.&amp;#160; In our case, we have an internal, nested ModelItemMetaObject type which inherits from System.Dynamic.DynamicMetaObject.&amp;#160; &lt;/p&gt;  &lt;p&gt;In our case, there are basically two important methods that we care about, BindGetMember and BindSetMember.&amp;#160; These wire up to two methods on ModelItemImpl to get and set based on the property name.&amp;#160; The net result of this is that the following code&lt;/p&gt;  &lt;pre class="brush: csharp; gutter: false; toolbar: false;"&gt;root.Properties[&amp;quot;Residence&amp;quot;].
        Value.
        Properties[&amp;quot;StreetAddress&amp;quot;].
        Value.GetCurrentValue()&lt;/pre&gt;

&lt;p&gt;Can now be written as&lt;/p&gt;

&lt;pre class="brush: csharp; gutter: false; toolbar: false;"&gt;dynamic mi = root;
Console.WriteLine(root.Residence.StreetAddress)&lt;/pre&gt;

&lt;p&gt;Now, with anything there are some tradeoffs, the biggest one is that this is dynamic, I don’t get compile time checking, and I could have a type that will result in an exception being thrown (that said, that problem exists in the verbose form as well).&amp;#160; This does let me write much more succinct code when programming the model item tree though for both gets and sets.&amp;#160; As an added bonus, we found there is actually a decent perf improvement from the WPF XAML data binding that now leverages the IDynamicMetaObjectProvider (mentioned in ScottGu’s post &lt;a href="http://bit.ly/d8zn1Z"&gt;here&lt;/a&gt;) in the way that the runtime will only compute the way to resolve the property once (as opposed to every time when it goes through the ICustomTypeDescriptor code path). &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Enjoy! &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10048993" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/designer/">designer</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/wf4/">wf4</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/vs2010/">vs2010</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/dynamic/">dynamic</category></item><item><title>VS 2010 RC Is Available</title><link>http://blogs.msdn.com/b/mwinkle/archive/2010/02/09/vs-2010-rc-is-available.aspx</link><pubDate>Tue, 09 Feb 2010 22:09:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9960812</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9960812</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2010/02/09/vs-2010-rc-is-available.aspx#comments</comments><description>&lt;p&gt;We’ve been hard at work here in Redmond (and with our team in Shanghai) working on getting WF ready for release.&amp;#160; We’ve made a ton of progress in the RC build that was made &lt;a href="http://blogs.msdn.com/jasonz/archive/2010/02/09/announcing-vs2010-net-framework-4-release-candidate-rc.aspx"&gt;available yesterday&lt;/a&gt;, please &lt;a href="http://go.microsoft.com/fwlink/?LinkID=151797"&gt;download it&lt;/a&gt; and check it out.&amp;#160; Also, and in important bold text, &lt;strong&gt;if you have feedback, please, please, please file an issue on Connect so that the team can look at it right away.&lt;/strong&gt;&amp;#160; One thing that I want to point out about &lt;a href="http://connect.microsoft.com/VisualStudio"&gt;Connect&lt;/a&gt; is that it is not a vacuum, the entries there go directly into our bug tracking system, which we look at daily in our various shiproom meetings.&amp;#160; If something isn’t working right, please let us know!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkId=183244"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/jasonz/WindowsLiveWriter/VS2010Beta2FeedbackSurvey_C49A/image_3.png" width="198" height="76" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We’ve fixed a number of issues that came directly from Connect in this last milestone, including some areas that revealed some gaps in our testing.&amp;#160; Your feedback is making this better.&amp;#160; For bugs that we’ve marked as postponed, as we start planning for vNext, we will start going through those to figure out the areas we need to improve on.&amp;#160; &lt;/p&gt;  &lt;p&gt;It’s cool the home stretch, this morning I presented to our support team to get them prepared to handle any PSS incidents that occur.&amp;#160; It’s great to see the release coming together. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9960812" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/wf4/">wf4</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/vs2010/">vs2010</category></item><item><title>Making Swiss Cheese Look Good, or Designers for ActivityAction in WF4</title><link>http://blogs.msdn.com/b/mwinkle/archive/2010/01/15/making-swiss-cheese-look-good-or-designers-for-activityaction-in-wf4.aspx</link><pubDate>Fri, 15 Jan 2010 00:06:54 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9948718</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9948718</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2010/01/15/making-swiss-cheese-look-good-or-designers-for-activityaction-in-wf4.aspx#comments</comments><description>&lt;p&gt;In my last &lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/24/swiss-cheese-and-wf4-or-an-introduction-to-activityaction.aspx"&gt;post&lt;/a&gt;, I covered using ActivityAction in order to provide a schematized callback, or hole, for the consumers of your activity to supply.&amp;#160; What I didn’t cover, and what I intend to here, is how to create a designer for that.&lt;/p&gt;  &lt;p&gt;If you’ve been following along, or have written a few designers using WorkflowItemPresenter, you may have a good idea how we might go about solving this.&amp;#160; There are a few gotcha’s along the way that we’ll cover as we go through this.&lt;/p&gt;  &lt;p&gt;First, let’s familiarize ourselves with the Timer example in the previous post: &lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Activities;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Diagnostics;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; WorkflowActivitiesAndHost&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;sealed&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TimerWithAction : NativeActivity&amp;lt;TimeSpan&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Activity Body { get; set; }&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Variable&amp;lt;Stopwatch&amp;gt; Stopwatch { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; ActivityAction&amp;lt;TimeSpan&amp;gt; OnCompletion { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; TimerWithAction()&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            Stopwatch = &lt;span class="kwrd"&gt;new&lt;/span&gt; Variable&amp;lt;Stopwatch&amp;gt;();&lt;/pre&gt;

  &lt;pre&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; CacheMetadata(NativeActivityMetadata metadata)&lt;/pre&gt;

  &lt;pre class="alt"&gt;        {&lt;/pre&gt;

  &lt;pre&gt;            metadata.AddImplementationVariable(Stopwatch);&lt;/pre&gt;

  &lt;pre class="alt"&gt;            metadata.AddChild(Body);&lt;/pre&gt;

  &lt;pre&gt;            metadata.AddDelegate(OnCompletion);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Execute(NativeActivityContext context)&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            Stopwatch sw = &lt;span class="kwrd"&gt;new&lt;/span&gt; Stopwatch();&lt;/pre&gt;

  &lt;pre&gt;            Stopwatch.Set(context, sw);&lt;/pre&gt;

  &lt;pre class="alt"&gt;            sw.Start();&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="rem"&gt;// schedule body and completion callback&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            context.ScheduleActivity(Body, Completed);&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Completed(NativeActivityContext context, ActivityInstance instance)&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!context.IsCancellationRequested)&lt;/pre&gt;

  &lt;pre&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;                Stopwatch sw = Stopwatch.Get(context);&lt;/pre&gt;

  &lt;pre&gt;                sw.Stop();&lt;/pre&gt;

  &lt;pre class="alt"&gt;                Result.Set(context, sw.Elapsed);&lt;/pre&gt;

  &lt;pre&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (OnCompletion != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre class="alt"&gt;                {&lt;/pre&gt;

  &lt;pre&gt;                    context.ScheduleAction&amp;lt;TimeSpan&amp;gt;(OnCompletion, Result.Get(context));&lt;/pre&gt;

  &lt;pre class="alt"&gt;                }&lt;/pre&gt;

  &lt;pre&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Cancel(NativeActivityContext context)&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            context.CancelChildren();&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (OnCompletion != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre class="alt"&gt;            {&lt;/pre&gt;

  &lt;pre&gt;                context.ScheduleAction&amp;lt;TimeSpan&amp;gt;(OnCompletion, TimeSpan.MinValue);&lt;/pre&gt;

  &lt;pre class="alt"&gt;            }&lt;/pre&gt;

  &lt;pre&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;    }&lt;/pre&gt;

  &lt;pre&gt;}&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;So, let’s build a designer for this.&amp;#160; First we have to provide a WorkflowItemPresenter bound to the .Body property.&amp;#160; This is pretty simple.&amp;#160; Let’s show the “simple” XAML that will let us easily drop something on the Body property&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sap:ActivityDesigner&lt;/span&gt; &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;actionDesigners.ActivityDesigner1&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:sap&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:sapv&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sap:WorkflowItemPresenter&lt;/span&gt; 
                 &lt;span class="attr"&gt;HintText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Drop the body here&amp;quot;&lt;/span&gt; 
                 &lt;span class="attr"&gt;BorderBrush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Black&amp;quot;&lt;/span&gt; 
                 &lt;span class="attr"&gt;BorderThickness&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;2&amp;quot;&lt;/span&gt; 
                 &lt;span class="attr"&gt;Item&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding Path=ModelItem.Body, Mode=TwoWay}&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Rectangle&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;80&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;6&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Fill&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Black&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Margin&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;10&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;sap:ActivityDesigner&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;Not a whole lot of magic here yet.&amp;#160; What we want to do is add another WorkflowItemPresenter, but what do I bind it to? Well, let’s look at how ActivityDelegate is defined [the root class for ActivityAction and ActivityFunc (which I’ll get to in my next post).:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/MakingSwissCheeseLookGoodorDesignersforA_15109/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/MakingSwissCheeseLookGoodorDesignersforA_15109/image_thumb.png" width="387" height="153" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;hmmm, Handler is an Activity, that looks kind of useful.&amp;#160;&amp;#160;&amp;#160; Let’s try that: &lt;/p&gt;

&lt;p&gt;[warning, this XAML won’t work, you will get an exception, this is by design :-) ]&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sap:ActivityDesigner&lt;/span&gt; &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;actionDesigners.ActivityDesigner1&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:sap&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:sapv&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sap:WorkflowItemPresenter&lt;/span&gt; &lt;span class="attr"&gt;HintText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Drop the body here&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;BorderBrush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Black&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;BorderThickness&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Item&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding Path=ModelItem.Body, Mode=TwoWay}&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Rectangle&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;80&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;6&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Fill&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Black&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Margin&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;10&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;&amp;lt;!-- this next line will not work like you think it might --&amp;gt;&lt;/span&gt; 
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sap:WorkflowItemPresenter&lt;/span&gt; &lt;span class="attr"&gt;HintText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Drop the completion here&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;BorderBrush&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Black&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;BorderThickness&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Item&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding Path=ModelItem.OnCompletion.Handler, Mode=TwoWay}&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;sap:ActivityDesigner&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;While this gives us what we want visually, there is a problem with the second WorkflowItemPresenter (just try dropping something on it):&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/MakingSwissCheeseLookGoodorDesignersforA_15109/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/MakingSwissCheeseLookGoodorDesignersforA_15109/image_thumb_1.png" width="242" height="239" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now, if you look at the XAML after dropping, the activity you dropped is not present.&amp;#160; What’s happened here:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The OnCompletion property is null, so binding to OnCompletion.Handler will fail&lt;/li&gt;

  &lt;li&gt;We (and WPF) are generally very forgiving of binding errors, so things appear to have succeeded.&amp;#160; &lt;/li&gt;

  &lt;li&gt;The instance was created fine, the ModelItem was created fine, and the it was put in the right place in the ModelItem tree, but there is no link in the underlying object graph, basically, the activity that you dropped is not connected &lt;/li&gt;

  &lt;li&gt;Thus, on serialization, there is no reference to the new activity in the actual object, and so it does not get serialized.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How can we fix this?&lt;/p&gt;

&lt;p&gt;Well, we need to patch things up in the designer, so we will need to write a little bit of code, using the OnModelItemChanged event.&amp;#160; This code is pretty simple, it just means that if something is assigned to ModelItem, if the value of “OnCompletion” is null, initialize it.&amp;#160; If it is already set, we don’t need to do anything (for instance, if you used an IActivityTemplateFactory to initialize).&amp;#160; One important thing here (putting on the bold glasses) &lt;strong&gt;YOU MUST GIVE THE DELEGATEINARGUMENT A NAME&lt;/strong&gt;.&amp;#160; VB expressions require a named token to reference, so, please put a name in there (or bind it, more on that below). &lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Activities;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; actionDesigners
{
    &lt;span class="rem"&gt;// Interaction logic for ActivityDesigner1.xaml&lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ActivityDesigner1
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; ActivityDesigner1()
        {
            InitializeComponent();
        }

        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnModelItemChanged(&lt;span class="kwrd"&gt;object&lt;/span&gt; newItem)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.ModelItem.Properties[&lt;span class="str"&gt;&amp;quot;OnCompletion&amp;quot;&lt;/span&gt;].Value == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                &lt;span class="kwrd"&gt;this&lt;/span&gt;.ModelItem.Properties[&lt;span class="str"&gt;&amp;quot;OnCompletion&amp;quot;&lt;/span&gt;].SetValue(
                    &lt;span class="kwrd"&gt;new&lt;/span&gt; ActivityAction&amp;lt;TimeSpan&amp;gt;
                    {
                        Argument = &lt;span class="kwrd"&gt;new&lt;/span&gt; DelegateInArgument&amp;lt;TimeSpan&amp;gt;
                        {
                            Name = &lt;span class="str"&gt;&amp;quot;duration&amp;quot;&lt;/span&gt;
                        }
                    });
            }
            &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnModelItemChanged(newItem);

        }
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Well, this works :-)&amp;#160; Note that you can see the duration DelegateInArgument that was added.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/MakingSwissCheeseLookGoodorDesignersforA_15109/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/MakingSwissCheeseLookGoodorDesignersforA_15109/image_thumb_2.png" width="585" height="414" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now, you might say something like the following “Gosh, I’d really like to not give it a name and have someone type that in” (this is what we do in our ForEach designer, for instance).&amp;#160; In that case, you would need to create a text box bound to OnCompletion.Argument.Name, which is left as an exercise for the reader. &lt;/p&gt;

&lt;p&gt;Alright, now you can get out there and build activities with ActivityActions, and have design time support for them!&lt;/p&gt;

&lt;p&gt;One question brought up in the comments on the last post was “what if I want to not let everyone see this” which is sort of the “I want an expert mode” view.&amp;#160; You have two options.&amp;#160; Either build two different designers and have the right one associated via metadata (useful in rehosting), or you could build one activity designer that switches between basic and expert mode and only surfaces these in expert mode. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9948718" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/wf/">wf</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/wf4/">wf4</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/xaml/">xaml</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/vs2010/">vs2010</category></item><item><title>Swiss Cheese and WF4, or, An Introduction to ActivityAction</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/12/24/swiss-cheese-and-wf4-or-an-introduction-to-activityaction.aspx</link><pubDate>Thu, 24 Dec 2009 01:46:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9940807</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9940807</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/12/24/swiss-cheese-and-wf4-or-an-introduction-to-activityaction.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/myklroventine/497322721/"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="swiss cheese" border="0" alt="swiss cheese" align="right" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/SwissCheeseandWF4UsingActivityAction_150D8/swiss%20cheese_3.jpg" width="217" height="298" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;One common scenario that was often requested by customers of WF 3 was the ability to have templated or “grey box” or “activities with holes” in them (hence the Swiss cheese photo above).&amp;#160; In WF4 we’ve done this in a way that way we call &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.activityaction(VS.100).aspx"&gt;ActivityAction&lt;/a&gt;&lt;/p&gt;  &lt;h1&gt;Motivation&lt;/h1&gt;  &lt;p&gt;First I’d like to do a little bit more to motivate the scenario.&amp;#160; &lt;/p&gt;  &lt;p&gt;Consider an activity that you have created for your ERP system called CheckInventory.&amp;#160; You’ve gone ahead and encapsulated all of the logic of your inventory system, maybe you have some different paths of logic, maybe you have interactions with some third party systems, but you want your customers to use this activity in their workflows when they need to get the level of inventory for an item.&amp;#160; &lt;/p&gt;  &lt;p&gt;Consider more generally an activity where you have a bunch of work you want to get done, but at various, and specific, points throughout that work, you want to allow the consumer of that activity to receive a callback and provide their own logic to handle that.&amp;#160; The mental model here is one of delegates.&lt;/p&gt;  &lt;p&gt;Finally, consider providing the ability for a user to specify the work that they want to have happen, but also make sure that you can strongly type the data that is passed to it.&amp;#160; In the first case above, you want to make sure that the Item in question is passed to the action that the consumer supplies.&amp;#160; &lt;/p&gt;  &lt;p&gt;In wf3, we had a lot of folks want to be able to do something like this. It’s a very natural extension to wanting to model things as activities and composing into higher level activities.&amp;#160; We like being able to string together 10 items as a black box for reuse, but we really want the user to specify exactly what should happen between steps 7 and 8.&amp;#160; &lt;/p&gt;  &lt;p&gt;A slide that I showed at PDC showed it this way (the Approval and Payment boxes represent the places I want a consumer to supply additional logic):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/SwissCheeseandWF4UsingActivityAction_150D8/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/SwissCheeseandWF4UsingActivityAction_150D8/image_thumb_1.png" width="486" height="360" /&gt;&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Introducing ActivityAction&lt;/h2&gt;  &lt;p&gt;Very early on the release, we knew this was one of the problems that we needed to tackle. The mental model that we are most aligned with is that of a delegate/ callback in C#.&amp;#160; If you think about a delegate, what are you doing, you are giving an object the implementation of some bit of logic that the object will subsequently call.&amp;#160; That’s the same thing that’s going on with an ActivityAction.&amp;#160; there are three important parts to an ActivityAction&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The Handler (this is the logic of the ActivityAction) &lt;/li&gt;    &lt;li&gt;The Shape (this determines the data that will be passed to the handler) &lt;/li&gt;    &lt;li&gt;The way that we invoke it from our activity &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Let’s start with some simple code (this is from a demo that I showed in my PDC &lt;a href="http://microsoftpdc.com/sessions/ft17"&gt;talk&lt;/a&gt;).&amp;#160; This is a timer activity which allows us to time the execution for the contained activity and then uses an activity action to act on the result.&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Activities;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Diagnostics;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; CustomActivities.ActivityTypes&lt;/pre&gt;

  &lt;pre class="alt"&gt;{&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;sealed&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Timer : NativeActivity&amp;lt;TimeSpan&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Activity Body { get; set; }&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Variable&amp;lt;Stopwatch&amp;gt; Stopwatch { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; ActivityAction&amp;lt;TimeSpan&amp;gt; OnCompletion { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Timer()&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            Stopwatch = &lt;span class="kwrd"&gt;new&lt;/span&gt; Variable&amp;lt;Stopwatch&amp;gt;();&lt;/pre&gt;

  &lt;pre&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; CacheMetadata(NativeActivityMetadata metadata)&lt;/pre&gt;

  &lt;pre class="alt"&gt;        {&lt;/pre&gt;

  &lt;pre&gt;            metadata.AddImplementationVariable(Stopwatch);&lt;/pre&gt;

  &lt;pre class="alt"&gt;            metadata.AddChild(Body);&lt;/pre&gt;

  &lt;pre&gt;            metadata.AddDelegate(OnCompletion);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Execute(NativeActivityContext context)&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            Stopwatch sw = &lt;span class="kwrd"&gt;new&lt;/span&gt; Stopwatch();&lt;/pre&gt;

  &lt;pre&gt;            Stopwatch.Set(context, sw);&lt;/pre&gt;

  &lt;pre class="alt"&gt;            sw.Start();&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="rem"&gt;// schedule body and completion callback&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            context.ScheduleActivity(Body, Completed);&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Completed(NativeActivityContext context, ActivityInstance instance)&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!context.IsCancellationRequested)&lt;/pre&gt;

  &lt;pre&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;                Stopwatch sw = Stopwatch.Get(context);&lt;/pre&gt;

  &lt;pre&gt;                sw.Stop();&lt;/pre&gt;

  &lt;pre class="alt"&gt;                Result.Set(context, sw.Elapsed);&lt;/pre&gt;

  &lt;pre&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (OnCompletion != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre class="alt"&gt;                {&lt;/pre&gt;

  &lt;pre&gt;                    context.ScheduleAction&amp;lt;TimeSpan&amp;gt;(OnCompletion, Result.Get(context));&lt;/pre&gt;

  &lt;pre class="alt"&gt;                }&lt;/pre&gt;

  &lt;pre&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Cancel(NativeActivityContext context)&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            context.CancelChildren();&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (OnCompletion != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre class="alt"&gt;            {&lt;/pre&gt;

  &lt;pre&gt;                context.ScheduleAction&amp;lt;TimeSpan&amp;gt;(OnCompletion, TimeSpan.MinValue);&lt;/pre&gt;

  &lt;pre class="alt"&gt;            }&lt;/pre&gt;

  &lt;pre&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;    }&lt;/pre&gt;

  &lt;pre&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;A few things to note about this code sample:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The declaration of an ActivityAction&amp;lt;TimeSpan&amp;gt; as a member of the activity.&amp;#160; You’ll note we use the OnXXX convention often for activity actions. &lt;/li&gt;

  &lt;li&gt;The usage of the &lt;a href="http://msdn.microsoft.com/en-us/library/dd485397(VS.100).aspx"&gt;ActivityAction&amp;lt;T&amp;gt;&lt;/a&gt; with on type argument.&amp;#160; The way to read this, or any of the 15 other types is that the T is the type of the data that will be passed to the activity action’s handler. 

    &lt;ul&gt;
      &lt;li&gt;Think about this like an Activity&amp;lt;Foo&amp;gt; corresponding to a void DoSomething(Foo argument1) method &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;The call to &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.nativeactivitymetadata.adddelegate(VS.100).aspx"&gt;NativeActivityMetadata.AddDelegate()&lt;/a&gt; which lets the runtime know that it needs to worry about the delegate &lt;/li&gt;

  &lt;li&gt;The code in the Completed( ) method which checks to see if OnCompletion is set and then schedules it using &lt;a href="http://msdn.microsoft.com/en-us/library/dd987734(VS.100).aspx"&gt;ScheduleAction&lt;/a&gt;.&amp;#160; I want to call out that line of code. &lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (OnCompletion != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
{
    context.ScheduleAction&amp;lt;TimeSpan&amp;gt;(OnCompletion, Result.Get(context));
}&lt;/pre&gt;

&lt;p&gt;&lt;style type="text/css"&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;It is important to note that I use the second parameter (and the third through 16th if that version is provided) in order to provide the data.&amp;#160; This way, the activity determines what data will be passed to the handler, allowing the activity to determine what data is visible where.&amp;#160; This is a much better way than allowing an invoked child to access any and all data from the parent.&amp;#160; This lets us be very specific about what data goes to the ActivityAction.&amp;#160;&amp;#160; Also, you could make it so that OnCompletion must be provided, that is, the only way to use the activity is to supply an implementation.&amp;#160; If you have something like “ProcessPayment” you likely want that to be a required thing.&amp;#160; You can use the CacheMetadata method in order to check and validate this. &lt;/p&gt;

&lt;p&gt;Now, let’s look at the code required to consume this time activity:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;DelegateInArgument&amp;lt;TimeSpan&amp;gt; time = &lt;span class="kwrd"&gt;new&lt;/span&gt; DelegateInArgument&amp;lt;TimeSpan&amp;gt;();
a = &lt;span class="kwrd"&gt;new&lt;/span&gt; Timer
{
    Body = &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpGet { Url = &lt;span class="str"&gt;&amp;quot;http://www.microsoft.com&amp;quot;&lt;/span&gt; },
    OnCompletion = &lt;span class="kwrd"&gt;new&lt;/span&gt; ActivityAction&amp;lt;TimeSpan&amp;gt;
    {
        Argument = time,
        Handler = &lt;span class="kwrd"&gt;new&lt;/span&gt; WriteLine { 
            Text = &lt;span class="kwrd"&gt;new&lt;/span&gt; InArgument&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(
                ctx =&amp;gt; 
                    &lt;span class="str"&gt;&amp;quot;Time input from timer &amp;quot;&lt;/span&gt; + time.Get(ctx).TotalMilliseconds)
        } 

    }
};&lt;/pre&gt;

&lt;p&gt;&lt;style type="text/css"&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;There are a couple of interesting things here:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Creation of &lt;a href="http://msdn.microsoft.com/en-us/library/dd987988(VS.100).aspx"&gt;DelegateInArgument&lt;/a&gt;&amp;lt;TimeSpan&amp;gt; : This is used to represent the data passed by the ActivityAction to the handler &lt;/li&gt;

  &lt;li&gt;Creation of the ActivityAction to pass in.&amp;#160; You’ll note that the &lt;a href="http://msdn.microsoft.com/en-us/library/dd486711(VS.100).aspx"&gt;Argument&lt;/a&gt; property is set to the DelegateInArgument, which we can then use in the handler &lt;/li&gt;

  &lt;li&gt;The H&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.activitydelegate.handler(VS.100).aspx"&gt;andler&lt;/a&gt; is the “implementation” that we want to invoke.&amp;#160; here’s it’s pretty simple, it’s a WriteLine and when we construct the argument we construct if from a lambda that uses the passed in context to resolve the DelegateInArgument when that executes. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At runtime, when we get to the point in the execution of the Timer activity, the WriteLine that the hosting app provided will be scheduled when the ScheduleAction is called.&amp;#160; This means we will output the timing information that the Timer observed.&amp;#160; A different implementation could have an IfThen activity and use that to determine if an SLA was enforced or not, and if not, send a nasty email to the WF author.&amp;#160; The possibilities are endless, and they open up scenarios for you to provide specific extension points for your activities.&lt;/p&gt;

&lt;p&gt;That wraps up a very brief tour of ActivityAction.&amp;#160; ActivityAction provides a easy way to create an empty place in activity that the consumer can use to supply the logic that they want executed.&amp;#160; In the second part of this post, we’ll dive into how to create a designer for one of these, how to represent this in XAML, and a few other interesting topics. &lt;/p&gt;

&lt;p&gt;It’s that time of year that I’ll be taking a little bit of time off for the holidays, so I will see y’all in 2010! &lt;/p&gt;

&lt;p&gt;Photo Credit &lt;/p&gt;

&lt;div about="http://www.flickr.com/photos/myklroventine/497322721/" xmlns:cc="http://creativecommons.org/ns#"&gt;&lt;a href="http://www.flickr.com/photos/myklroventine/" rel="cc:attributionURL"&gt;http://www.flickr.com/photos/myklroventine/&lt;/a&gt; / &lt;a href="http://creativecommons.org/licenses/by/2.0/" rel="license"&gt;CC BY 2.0&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9940807" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/wf4/">wf4</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/ActivityModel/">ActivityModel</category></item><item><title>Inspection, Default Services and Items (WF4 EditingContext Intro Part 6)</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/12/23/inspection-default-services-and-items-wf4-editingcontext-intro-part-6.aspx</link><pubDate>Wed, 23 Dec 2009 01:59:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9940348</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9940348</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/12/23/inspection-default-services-and-items-wf4-editingcontext-intro-part-6.aspx#comments</comments><description>
&lt;STYLE id=toolsplat_features_updated_29733_Styles&gt;






&lt;!--table
	{mso-displayed-decimal-separator:"\.";
	mso-displayed-thousand-separator:"\,";}
.xl1529733
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:black;
	font-size:11.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:general;
	vertical-align:bottom;
	mso-background-source:auto;
	mso-pattern:auto;
	white-space:nowrap;}
.xl6529733
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:#006100;
	font-size:11.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:general;
	vertical-align:bottom;
	background:#c6efce;
	mso-pattern:black none;
	white-space:nowrap;}
.xl6629733
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:#9c0006;
	font-size:11.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:general;
	vertical-align:bottom;
	background:#ffc7ce;
	mso-pattern:black none;
	white-space:nowrap;}
--&gt;&lt;/STYLE&gt;

&lt;STYLE id=toolsplat_features_updated_16386_Styles&gt;







&lt;!--table
	{mso-displayed-decimal-separator:"\.";
	mso-displayed-thousand-separator:"\,";}
.xl1516386
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:black;
	font-size:11.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:general;
	vertical-align:bottom;
	mso-background-source:auto;
	mso-pattern:auto;
	white-space:nowrap;}
.xl6516386
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:#006100;
	font-size:11.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:general;
	vertical-align:bottom;
	background:#c6efce;
	mso-pattern:black none;
	white-space:nowrap;}
.xl6616386
	{padding-top:1px;
	padding-right:1px;
	padding-left:1px;
	mso-ignore:padding;
	color:#9c0006;
	font-size:11.0pt;
	font-weight:400;
	font-style:normal;
	text-decoration:none;
	font-family:calibri, sans-serif;
	mso-font-charset:0;
	mso-number-format:general;
	text-align:general;
	vertical-align:bottom;
	background:#ffc7ce;
	mso-pattern:black none;
	white-space:nowrap;}
--&gt;&lt;/STYLE&gt;

&lt;P&gt;This part 6 of my 6&amp;nbsp; part series on the EditingContext.&lt;/P&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/introduction-to-the-wf4-designer-editing-context-part-1.aspx" mce_href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/introduction-to-the-wf4-designer-editing-context-part-1.aspx"&gt;Introduction&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/sharing-functionality-between-designers-wf4-editingcontext-intro-part-2.aspx" mce_href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/sharing-functionality-between-designers-wf4-editingcontext-intro-part-2.aspx"&gt;Sharing Functionality between Designers&lt;/A&gt;&amp;nbsp; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/host-provided-capabilities-wf4-editingcontext-intro-part-3.aspx" mce_href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/host-provided-capabilities-wf4-editingcontext-intro-part-3.aspx"&gt;Host provided capabilities&lt;/A&gt;&amp;nbsp;&amp;nbsp; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/providing-callbacks-for-the-host-wf4-editingcontext-intro-part-4.aspx" mce_href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/providing-callbacks-for-the-host-wf4-editingcontext-intro-part-4.aspx"&gt;Providing callbacks for the host&lt;/A&gt;&amp;nbsp; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/subscription-notification-engine-wf4-editingcontext-intro-part-5.aspx" mce_href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/subscription-notification-engine-wf4-editingcontext-intro-part-5.aspx"&gt;Subscription/Notification engine&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/mwinkle/archive/2009/12/23/inspection-default-services-and-items-wf4-editingcontext-intro-part-6.aspx" mce_href="http://blogs.msdn.com/mwinkle/archive/2009/12/23/inspection-default-services-and-items-wf4-editingcontext-intro-part-6.aspx"&gt;Inspection, Default Services and Items (you are here)&lt;/A&gt; 
&lt;P&gt;I want to wrap up this series of posts by posting some code for an activity designer that functions more as a diagnostic tool, and will display all of the Items and services of the EditingContext within the designer.&amp;nbsp; This will be useful from an investigation perspective, and hopefully as a diagnostic tool.&amp;nbsp; We will use this to help us understand what are the services that are available out of the box in VS, as well as in a rehosted application.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;We first need to create an empty activity to attach a designer to.&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System;
&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.Collections.Generic;
&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.Linq;
&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.Text;
&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.Activities;
&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.ComponentModel;

&lt;SPAN class=kwrd&gt;namespace&lt;/SPAN&gt; blogEditingContext
{
    [Designer(&lt;SPAN class=kwrd&gt;typeof&lt;/SPAN&gt;(DiagnosticDesigner))]
    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;sealed&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; Diagnosticator : CodeActivity
    {
        &lt;SPAN class=rem&gt;// Define an activity input argument of type string&lt;/SPAN&gt;
        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; InArgument&amp;lt;&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;&amp;gt; Text { get; set; }

        &lt;SPAN class=rem&gt;// If your activity returns a value, derive from CodeActivity&amp;lt;TResult&amp;gt;&lt;/SPAN&gt;
        &lt;SPAN class=rem&gt;// and return the value from the Execute method.&lt;/SPAN&gt;
        &lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;override&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Execute(CodeActivityContext context)
        {
            &lt;SPAN class=rem&gt;// Obtain the runtime value of the Text input argument&lt;/SPAN&gt;
            &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; text = context.GetValue(&lt;SPAN class=kwrd&gt;this&lt;/SPAN&gt;.Text);
        }
    }
}&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;





.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;Now, let’s create our designer.&amp;nbsp; We could do fancy treeviews or object browser style UI’s, but as this is a blog post, I want to provide you with the basics, and then let you figure out how that is most useful to you.&amp;nbsp; So, we will just create a designer that writes out to debug output the relevant information.&amp;nbsp; &lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;sap:ActivityDesigner&lt;/SPAN&gt; &lt;SPAN class=attr&gt;x:Class&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="blogEditingContext.DiagnosticDesigner"&lt;/SPAN&gt;
    &lt;SPAN class=attr&gt;xmlns&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;/SPAN&gt;
    &lt;SPAN class=attr&gt;xmlns:x&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="http://schemas.microsoft.com/winfx/2006/xaml"&lt;/SPAN&gt;
    &lt;SPAN class=attr&gt;xmlns:sap&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"&lt;/SPAN&gt;
    &lt;SPAN class=attr&gt;xmlns:sapv&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;Grid&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
        &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;Button&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Click&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Button_Click"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;Debug.WriteLine Context Data&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;Button&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;Grid&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;sap:ActivityDesigner&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;







.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;And now the code&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.Diagnostics;
&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.Linq;
&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.Windows;

&lt;SPAN class=kwrd&gt;namespace&lt;/SPAN&gt; blogEditingContext
{
    &lt;SPAN class=rem&gt;// Interaction logic for DiagnosticDesigner.xaml&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;partial&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; DiagnosticDesigner
    {
        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; DiagnosticDesigner()
        {
            InitializeComponent();
        }

        &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Button_Click(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; sender, RoutedEventArgs e)
        {
            &lt;SPAN class=rem&gt;// the goal here is to output meaningful and useful information about &lt;/SPAN&gt;
            &lt;SPAN class=rem&gt;// the contents of the editing context here. &lt;/SPAN&gt;
            &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; level = Debug.IndentLevel;
            Debug.WriteLine(&lt;SPAN class=str&gt;"Items in the EditingContext"&lt;/SPAN&gt;);
            Debug.IndentLevel++;
            &lt;SPAN class=kwrd&gt;foreach&lt;/SPAN&gt; (var item &lt;SPAN class=kwrd&gt;in&lt;/SPAN&gt; Context.Items.OrderBy(x =&amp;gt; x.ItemType.ToString()))
            {
                Debug.WriteLine(item.ItemType);
            }

            Debug.IndentLevel = level;
            Debug.WriteLine(&lt;SPAN class=str&gt;"Services in the EditingContext"&lt;/SPAN&gt;);
            &lt;SPAN class=kwrd&gt;foreach&lt;/SPAN&gt; (var service &lt;SPAN class=kwrd&gt;in&lt;/SPAN&gt; Context.Services.OrderBy(x =&amp;gt; x.ToString()))
            {
                Debug.WriteLine(service);
            }
        }
    }
}&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;







.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;Let’s break this down.&amp;nbsp; The work here happens in the button click where we simply order by types’ string representations and output them to the debug writer (a more robust implementation might use a trace writer that could be configured in the app, but for this purpose, this will be sufficient. &lt;/P&gt;
&lt;P&gt;So, what output do we get?&lt;/P&gt;
&lt;H1&gt;&lt;/H1&gt;
&lt;H1&gt;VS Standard Services and Items&lt;/H1&gt;
&lt;P&gt;We determine this by using the activity in a freshly opened WF project&lt;/P&gt;
&lt;H2&gt;Items&lt;/H2&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;
&lt;TABLE border=0 cellSpacing=0 cellPadding=0&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width=64&gt;System.Activities.Presentation.Hosting.AssemblyContextControlItem&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Hosting.ReadOnlyState&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Hosting.WorkflowCommandExtensionItem&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.View.Selection&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.WorkflowFileItem&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;H2&gt;Services&lt;/H2&gt;
&lt;TABLE border=0 cellSpacing=0 cellPadding=0&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width=64&gt;System.Activities.Presentation.Debug.IDesignerDebugView&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.DesignerPerfEventProvider&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.FeatureManager&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Hosting.ICommandService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Hosting.IMultiTargetingSupportService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Hosting.WindowHelperService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.IActivityToolboxService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.IIntegratedHelpService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.IWorkflowDesignerStorageService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.IXamlLoadErrorService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Model.AttachedPropertiesService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Model.ModelTreeManager&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Services.ModelService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Services.ViewService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.UndoEngine&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Validation.IValidationErrorService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Validation.ValidationService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.View.ActivityTypeDesigner+DisplayNameUpdater&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.View.DesignerView&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.View.IExpressionEditorService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.View.ViewStateService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.View.VirtualizedContainerService&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;&lt;/H1&gt;
&lt;H1&gt;Basic Rehosted Application Standard Services and Items&lt;/H1&gt;
&lt;H2&gt;Items&lt;/H2&gt;
&lt;TABLE border=0 cellSpacing=0 cellPadding=0&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width=64&gt;System.Activities.Presentation.Hosting.ReadOnlyState&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Hosting.WorkflowCommandExtensionItem&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.View.Selection&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;H2&gt;Services&lt;/H2&gt;
&lt;TABLE border=0 cellSpacing=0 cellPadding=0&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width=64&gt;System.Activities.Presentation.DesignerPerfEventProvider&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.FeatureManager&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Hosting.WindowHelperService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Model.AttachedPropertiesService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Model.ModelTreeManager&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Services.ModelService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Services.ViewService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.UndoEngine&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.Validation.ValidationService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.View.DesignerView&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.View.ViewStateService&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;System.Activities.Presentation.View.VirtualizedContainerService&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;H1&gt;Comparison Table View&lt;/H1&gt;
&lt;DIV align=center x:publishsource="Excel"&gt;
&lt;TABLE style="WIDTH: 507pt; BORDER-COLLAPSE: collapse; TABLE-LAYOUT: fixed" border=0 cellSpacing=0 cellPadding=0 width=676&gt;
&lt;COLGROUP&gt;
&lt;COL style="WIDTH: 396pt; mso-width-source: userset; mso-width-alt: 19309" width=528&gt;
&lt;COL style="WIDTH: 48pt" width=64&gt;
&lt;COL style="WIDTH: 63pt; mso-width-source: userset; mso-width-alt: 3072" width=84&gt;&lt;/COLGROUP&gt;
&lt;TBODY&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; WIDTH: 396pt; FONT-FAMILY: calibri; BACKGROUND: #4f81bd; HEIGHT: 15pt; COLOR: white; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 700; TEXT-DECORATION: none; mso-pattern: #4f81bd none; text-underline-style: none; text-line-through: none" class=xl1529733 height=20 width=528 align=left class="xl1529733"&gt;Items&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; WIDTH: 48pt; FONT-FAMILY: calibri; BACKGROUND: #4f81bd; COLOR: white; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 700; TEXT-DECORATION: none; mso-pattern: #4f81bd none; text-underline-style: none; text-line-through: none" class=xl1529733 width=64 align=left class="xl1529733"&gt;VS&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; WIDTH: 63pt; FONT-FAMILY: calibri; BACKGROUND: #4f81bd; COLOR: white; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 700; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: #4f81bd none; text-underline-style: none; text-line-through: none" class=xl1529733 width=84 align=left class="xl1529733"&gt;Rehosted&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1529733 height=20 align=left class="xl1529733"&gt;
&lt;P align=left&gt;System.Activities.Presentation.Hosting.AssemblyContextControlItem&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6529733 align=left class="xl6529733"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #ffc7ce; COLOR: #9c0006; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6629733 align=left class="xl6629733"&gt;
&lt;P align=left&gt;No&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1529733 height=20 align=left class="xl1529733"&gt;
&lt;P align=left&gt;System.Activities.Presentation.Hosting.ReadOnlyState&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6529733 align=left class="xl6529733"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6529733 align=left class="xl6529733"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1529733 height=20 align=left class="xl1529733"&gt;
&lt;P align=left&gt;System.Activities.Presentation.Hosting.WorkflowCommandExtensionItem&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6529733 align=left class="xl6529733"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6529733 align=left class="xl6529733"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1529733 height=20 align=left class="xl1529733"&gt;
&lt;P align=left&gt;System.Activities.Presentation.View.Selection&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6529733 align=left class="xl6529733"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6529733 align=left class="xl6529733"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 0.5pt solid; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1529733 height=20 align=left class="xl1529733"&gt;
&lt;P align=left&gt;System.Activities.Presentation.WorkflowFileItem&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6529733 align=left class="xl6529733"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 0.5pt solid; FONT-FAMILY: calibri; BACKGROUND: #ffc7ce; COLOR: #9c0006; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6629733 align=left class="xl6629733"&gt;
&lt;P align=left&gt;No&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/DIV&gt;
&lt;DIV align=center x:publishsource="Excel"&gt;
&lt;TABLE style="WIDTH: 507pt; BORDER-COLLAPSE: collapse; TABLE-LAYOUT: fixed" border=0 cellSpacing=0 cellPadding=0 width=676&gt;
&lt;COLGROUP&gt;
&lt;COL style="WIDTH: 396pt; mso-width-source: userset; mso-width-alt: 19309" width=528&gt;
&lt;COL style="WIDTH: 48pt" width=64&gt;
&lt;COL style="WIDTH: 63pt; mso-width-source: userset; mso-width-alt: 3072" width=84&gt;&lt;/COLGROUP&gt;
&lt;TBODY&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; WIDTH: 396pt; FONT-FAMILY: calibri; BACKGROUND: #4f81bd; HEIGHT: 15pt; COLOR: white; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 700; TEXT-DECORATION: none; mso-pattern: #4f81bd none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 width=528 class="xl1516386"&gt;Services&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; WIDTH: 48pt; FONT-FAMILY: calibri; BACKGROUND: #4f81bd; COLOR: white; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 700; TEXT-DECORATION: none; mso-pattern: #4f81bd none; text-underline-style: none; text-line-through: none" class=xl1516386 width=64 class="xl1516386"&gt;VS&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; WIDTH: 63pt; FONT-FAMILY: calibri; BACKGROUND: #4f81bd; COLOR: white; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 700; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: #4f81bd none; text-underline-style: none; text-line-through: none" class=xl1516386 width=84 class="xl1516386"&gt;Rehosted&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.Debug.IDesignerDebugView&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #ffc7ce; COLOR: #9c0006; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6616386 class="xl6616386"&gt;
&lt;P align=left&gt;No&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.DesignerPerfEventProvider&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.FeatureManager&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.Hosting.ICommandService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #ffc7ce; COLOR: #9c0006; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6616386 class="xl6616386"&gt;
&lt;P align=left&gt;No&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.Hosting.IMultiTargetingSupportService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #ffc7ce; COLOR: #9c0006; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6616386 class="xl6616386"&gt;
&lt;P align=left&gt;No&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.Hosting.WindowHelperService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.IActivityToolboxService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #ffc7ce; COLOR: #9c0006; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6616386 class="xl6616386"&gt;
&lt;P align=left&gt;No&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.IIntegratedHelpService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #ffc7ce; COLOR: #9c0006; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6616386 class="xl6616386"&gt;
&lt;P align=left&gt;No&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.IWorkflowDesignerStorageService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #ffc7ce; COLOR: #9c0006; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6616386 class="xl6616386"&gt;
&lt;P align=left&gt;No&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.IXamlLoadErrorService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #ffc7ce; COLOR: #9c0006; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6616386 class="xl6616386"&gt;
&lt;P align=left&gt;No&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.Model.AttachedPropertiesService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.Model.ModelTreeManager&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.Services.ModelService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.Services.ViewService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.UndoEngine&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.Validation.IValidationErrorService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #ffc7ce; COLOR: #9c0006; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6616386 class="xl6616386"&gt;
&lt;P align=left&gt;No&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.Validation.ValidationService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.View.ActivityTypeDesigner+DisplayNameUpdater&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #ffc7ce; COLOR: #9c0006; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6616386 class="xl6616386"&gt;
&lt;P align=left&gt;No&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.View.DesignerView&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.View.IExpressionEditorService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #ffc7ce; COLOR: #9c0006; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6616386 class="xl6616386"&gt;
&lt;P align=left&gt;No&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.View.ViewStateService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 15pt" height=20&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 0.5pt solid; BORDER-LEFT: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; HEIGHT: 15pt; COLOR: black; FONT-SIZE: 11pt; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; text-underline-style: none; text-line-through: none" class=xl1516386 height=20 class="xl1516386"&gt;
&lt;P align=left&gt;System.Activities.Presentation.View.VirtualizedContainerService&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 0.5pt solid; BORDER-RIGHT-STYLE: none; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 0.5pt solid; FONT-FAMILY: calibri; BACKGROUND: #c6efce; COLOR: #006100; FONT-SIZE: 11pt; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 0.5pt solid; FONT-WEIGHT: 400; BORDER-RIGHT: #4f81bd 0.5pt solid; TEXT-DECORATION: none; mso-pattern: black none; text-underline-style: none; text-line-through: none" class=xl6516386 class="xl6516386"&gt;
&lt;P align=left&gt;Yes&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/DIV&gt;
&lt;H1&gt;&amp;nbsp;&lt;/H1&gt;
&lt;H1&gt;&amp;nbsp;&lt;/H1&gt;
&lt;H1&gt;&amp;nbsp;&lt;/H1&gt;
&lt;H1&gt;&amp;nbsp;&lt;/H1&gt;
&lt;H1&gt;Conclusion&lt;/H1&gt;
&lt;P&gt;This wraps up our series on the editing context.&amp;nbsp; We’ve gone through the basics of why we need it, what we can do with it, and then we moved how to use it, from both the very simple to the very complex.&amp;nbsp; We’ve finished with a diagnostic tool to help understand what all items I can bind to.&lt;/P&gt;
&lt;P&gt;What’s Next From Here?&lt;/P&gt;
&lt;P&gt;A few ideas for the readers who have read all of these:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Wire up a few attached properties to reflect back through to some interesting data (like if it is selected).&amp;nbsp; These attached properties could then be used directly by your UI (via the binding in XAML) to let your designers display and react to changes in the data &lt;/LI&gt;
&lt;LI&gt;Think about ideas for services you might want to add in VS without depending on an activity to inject it (and send me mail, I am trying to compile a list of interesting things) &lt;/LI&gt;
&lt;LI&gt;Are there service/item implementations you want to override in VS? &lt;/LI&gt;
&lt;LI&gt;Is there a service/item you expect to see that is not there? &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Thanks for now!&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/LI&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9940348" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-09-94-03-48/blogEditingContext.zip" length="22510" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/designer/">designer</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/wf4/">wf4</category></item><item><title>Subscription / Notification Engine (WF4 EditingContext Intro Part 5)</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/12/22/subscription-notification-engine-wf4-editingcontext-intro-part-5.aspx</link><pubDate>Tue, 22 Dec 2009 21:20:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9940236</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9940236</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/12/22/subscription-notification-engine-wf4-editingcontext-intro-part-5.aspx#comments</comments><description>&lt;p&gt;This part 5 of my 6&amp;#160; part series on the EditingContext.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/introduction-to-the-wf4-designer-editing-context-part-1.aspx"&gt;Introduction&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/sharing-functionality-between-designers-wf4-editingcontext-intro-part-2.aspx"&gt;Sharing Functionality between Designers&lt;/a&gt;&amp;#160; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/host-provided-capabilities-wf4-editingcontext-intro-part-3.aspx"&gt;Host provided capabilities&lt;/a&gt;&amp;#160;&amp;#160; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/providing-callbacks-for-the-host-wf4-editingcontext-intro-part-4.aspx"&gt;Providing callbacks for the host&lt;/a&gt;&amp;#160; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/subscription-notification-engine-wf4-editingcontext-intro-part-5.aspx"&gt;Subscription/Notification engine (you are here)&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/23/inspection-default-services-and-items-wf4-editingcontext-intro-part-6.aspx"&gt;Inspection, Default Services and Items&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In this post, we’re going to tie together a few of the things we’ve seen in the last few posts and show how we can wire up parts of the designer (or the hosting application) to changes made to the Items collection of the EditingContext to do some interesting things.&lt;/p&gt;  &lt;p&gt;You will note that both the ServiceManager and ContextItemManager have Subscribe methods, and I’ve talked in previous posts about how the publish mechanism is a little different.&amp;#160; I want to dive a little deeper into how these work, the different overloads, and what you can expect have happen on the subscribe side of things.&lt;/p&gt;  &lt;h1&gt;Services&lt;/h1&gt;  &lt;p&gt;On service, there are two different publish methods.&amp;#160; I will list all four, and then talk about how there are really only two :-) &lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width="338"&gt;&lt;strong&gt;           &lt;h3&gt;Method&lt;/h3&gt;         &lt;/strong&gt;&lt;/td&gt;        &lt;td width="477"&gt;&lt;strong&gt;           &lt;h3&gt;Description&lt;/h3&gt;         &lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="338"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee425880(VS.100).aspx"&gt;Publish(Type, PublishServiceCallback)&lt;/a&gt;&lt;/td&gt;        &lt;td width="477"&gt;Publishes the specified service type, but does not declare an instance. When the service is requested, the Publish service callback will be invoked to create the instance. The callback is invoked only once. After that, the instance it returned is cached.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="338"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee403965(VS.100).aspx"&gt;Publish(Type, Object)&lt;/a&gt;&lt;/td&gt;        &lt;td width="477"&gt;Publishes the given service. After it is published, the service instance remains in the service manager until the editing context is disposed of. &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="338"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee407838(VS.100).aspx"&gt;Publish&amp;lt;(Of &amp;lt;(TServiceType&amp;gt;)&amp;gt;)(TServiceType)&lt;/a&gt;&lt;/td&gt;        &lt;td width="477"&gt;Publishes the given service. After it is published, the service instance remains in the service manager until the editing context is disposed of.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="338"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee408377(VS.100).aspx"&gt;Publish&amp;lt;(Of &amp;lt;(TServiceType&amp;gt;)&amp;gt;)(PublishServiceCallback&amp;lt;(Of &amp;lt;(TServiceType&amp;gt;)&amp;gt;))&lt;/a&gt;&lt;/td&gt;        &lt;td width="477"&gt;Publishes the given service type, but does not declare an instance yet. When the service is requested, the PublishServiceCallback will be invoked to create the instance. The callback is invoked only once. After that, the instance it returned is cached.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;There are really only two methods here, and some generic sugar for the other two.&amp;#160; They are Publish(Type, PublishServiceCallback), and Publish(Type, Object).&amp;#160; If you were to look at the implementation of the generic versions, they simply turn around and call the un-generic form.&lt;/p&gt;  &lt;p&gt;The difference between the basic one (Publish(Type, Object)) and the version with the callback is that the callback enables us to be a little more lazy and wait to actually create the instance of the object until it is first requested.&amp;#160; Let’s look at how &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.publishservicecallback(VS.100).aspx"&gt;PublishServiceCallback&lt;/a&gt; is defined:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; Object PublishServiceCallback(
    Type serviceType
)&lt;/pre&gt;

&lt;p&gt;&lt;style type="text/css"&gt;






.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;What this lets us do is that the first time someone calls GetService, this method will be called with the responsibility of returning an instance of the service type.&amp;#160; Subsequent calls to GetService will simply return the instance returned by the method provided fro the PublishServiceCallback.&amp;#160; It is important to note that on Publish, any subscribers will be notified.&amp;#160; As the Subscribe callback takes an instance, we will internally call GetService on the notification, which will in turn call the PublishServiceCallback to instantiate an object.&amp;#160; If we have subscribers, our publish is less lazy (but that’s by design, we have consumers who are ready and waiting to consume). &lt;/p&gt;

&lt;p&gt;Let’s now look at the subscribe methods.&amp;#160; Again, here there are two methods (generic and non-generic), but they both do the same thing:&lt;/p&gt;

&lt;table border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td width="338"&gt;
        &lt;h3&gt;Method&lt;/h3&gt;
      &lt;/td&gt;

      &lt;td width="477"&gt;
        &lt;h3&gt;Description&lt;/h3&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td width="338"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee403874(VS.100).aspx"&gt;Subscribe&lt;/a&gt;&lt;/td&gt;

      &lt;td width="477"&gt;Invokes the provided callback when someone has published the requested service. If the service was already available, this method invokes the callback immediately. &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td width="338"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee403953(VS.100).aspx"&gt;Subscribe&amp;lt;(Of &amp;lt;(TServiceType&amp;gt;)&amp;gt;)&lt;/a&gt;&lt;/td&gt;

      &lt;td width="477"&gt;Invokes the provided callback when someone has published the requested service. If the service was already available, this method invokes the callback immediately. &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Both of these use a &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.subscribeservicecallback(VS.100).aspx"&gt;SubscribeServiceCallback&lt;/a&gt; defined as the following&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SubscribeServiceCallback(
    Type serviceType,
    Object serviceInstance
)&lt;/pre&gt;
&lt;style type="text/css"&gt;






.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;This allows any consumer to be notified &lt;em&gt;when a service is initially published.&lt;/em&gt;&amp;#160; This is an important distinction we will call out versus items which provide a more advanced subscription method (namely, to changes).&lt;/p&gt;

&lt;h2&gt;Why is this Useful?&lt;/h2&gt;

&lt;p&gt;Generally we find this useful for a few reasons:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Services may not be available at designer initialization, or the order in which they are created may not be fixed (it is ultimately up to the host to determine this).&amp;#160; &lt;/li&gt;

  &lt;li&gt;Services may be provided by the host.&amp;#160; It is possible your activity designer may be used in a host that does not provide that service.&amp;#160; You may want to be flexible in handling that &lt;/li&gt;

  &lt;li&gt;Services can be injected at any time.&amp;#160; A publish – subscribe model lets us have a little more flexibility to react to new services as they are added.&amp;#160; You could imagine a spell checking service that a host only provides on the first time someone hits “spell check.”&amp;#160; When this service comes online, then our designers can decide to consume this. &lt;/li&gt;

  &lt;li&gt;Flipping things around, you may want to use a service to callout to a host, and you would like the host to subscribe for when an certain activity designer will publish a service. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let’s talk about Items:&lt;/p&gt;

&lt;h1&gt;Items&lt;/h1&gt;

&lt;p&gt;Items do not have a publish method, per se, but they have the &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.contextitemmanager.setvalue(VS.100).aspx"&gt;SetValue&lt;/a&gt; method which basically publishes an instance to the context.&amp;#160; The semantics of SetValue are that it will first attempt to store the new value.&amp;#160; Provided that succeeds, we then call &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.contextitem.onitemchanged(VS.100).aspx"&gt;OnItemChanged&lt;/a&gt; on the &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.contextitem(VS.100).aspx"&gt;ContextItem&lt;/a&gt; itself.&amp;#160; This is basically notifies the object itself (giving it a chance to react, clean up, or throw if something is really wrong).&amp;#160; If this throws, the old value is preserved.&amp;#160; If this succeeds, we then notify anyone who has subscribed to the changes.&amp;#160; &lt;/p&gt;

&lt;p&gt;GetValue allows me to retrieve the &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.contextitem(VS.100).aspx"&gt;ContextItem&lt;/a&gt;.&amp;#160; There are two GetValue’s, one &lt;a href="http://msdn.microsoft.com/en-us/library/ee403629(VS.100).aspx"&gt;generic&lt;/a&gt;, the other &lt;a href="http://msdn.microsoft.com/en-us/library/ee407858(VS.100).aspx"&gt;non-generic&lt;/a&gt;, but with a type as its parameter.&amp;#160; It is important to note the point that is also present in the docs.&amp;#160; If there is not an item present when this is called, the default value will be instantiated and returned.&amp;#160; &lt;/p&gt;

&lt;p&gt;Provided items are written using SetValue, all of the subscribers will be subsequently notified.&amp;#160; If I just do an arbitrary GetValue and then make a few changes without calling SetValue, by default nothing interesting is going to happen (that is, no subscribers will be notified, subsequent calls to GetValue will get the updated object however).&amp;#160; &lt;a href="http://msdn.microsoft.com/en-us/library/ee403526(VS.100).aspx"&gt;Subscribe&lt;/a&gt; (and it’s generic &lt;a href="http://msdn.microsoft.com/en-us/library/ee425855(VS.100).aspx"&gt;counterpart&lt;/a&gt;) allow me to provide a &lt;a href="http://msdn.microsoft.com/en-us/library/ee408228(VS.100).aspx"&gt;SubscribeContextCallback&lt;/a&gt; which will be invoked whenever SetValue is called.&amp;#160;&amp;#160; This functions basically in the same way that it does for Services.&lt;/p&gt;

&lt;p&gt;An interesting pattern for Items that we use in a few places throughout the designer is to create an AttachedProperty on the modelItem (similar to this &lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/07/attachedproperty-part-2-putting-it-together.aspx"&gt;post&lt;/a&gt;) which in the implementation of the Getter and Setter will call out to the editing context to get or set the value from a ContextItem.&amp;#160; This gives me a WPF friendly binding surface (foo.Bar binding syntax) that we can wire up to be change aware.&amp;#160; We do this for a number of our triggers within our style implementation for things like is selected, etc.&amp;#160; Future post note for me is that I should go through all of the attached properties present on a ModelItem that you could use to bind to :-) &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;This wraps up a tour of the Subscription / Notification engine present within the EditingContext.&amp;#160; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9940236" width="1" height="1"&gt;</description></item><item><title>Providing Callbacks for the Host (WF4 EditingContext Intro Part 4)</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/12/22/providing-callbacks-for-the-host-wf4-editingcontext-intro-part-4.aspx</link><pubDate>Tue, 22 Dec 2009 17:57:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9940150</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9940150</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/12/22/providing-callbacks-for-the-host-wf4-editingcontext-intro-part-4.aspx#comments</comments><description>&lt;p&gt;This part 4 of my 6&amp;#160; part series on the EditingContext.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/introduction-to-the-wf4-designer-editing-context-part-1.aspx"&gt;Introduction&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/sharing-functionality-between-designers-wf4-editingcontext-intro-part-2.aspx"&gt;Sharing Functionality between Designers&amp;#160; (you are here)&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/host-provided-capabilities-wf4-editingcontext-intro-part-3.aspx"&gt;Host provided capabilities&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/providing-callbacks-for-the-host-wf4-editingcontext-intro-part-4.aspx"&gt;Providing callbacks for the host&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/subscription-notification-engine-wf4-editingcontext-intro-part-5.aspx"&gt;Subscription/Notification engine&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/23/inspection-default-services-and-items-wf4-editingcontext-intro-part-6.aspx"&gt;Inspection, Default Services and Items&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;&amp;#160;&lt;/h1&gt;  &lt;p&gt;In addition to having a host provide an instance of a type to be used within the designer, it can also be used to pass an instance that will route callbacks to the host.&amp;#160; I covered this briefly in a previous post (&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/11/06/displaying-validation-errors-in-a-rehosted-wf4-designer.aspx"&gt;Displaying Validation Errors in a Rehosted WF4 Designer&lt;/a&gt;).&amp;#160; In that case, we provide an implementation of &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.validation.ivalidationerrorservice%28VS.100%29.aspx"&gt;IValidationErrorService&lt;/a&gt;, which the designer infrastructure will call, if available, towards the end of a completion of a validation episode.&amp;#160; In the sample application in that post, we use that instance to route, and display the validation errors in the system. &lt;/p&gt;  &lt;p&gt;Rather than duplicate the code, I will simply encourage you to check out that &lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/11/06/displaying-validation-errors-in-a-rehosted-wf4-designer.aspx"&gt;post&lt;/a&gt; and think about the way you could publish a service that your activity designers know about, and use it as a mechanism for calling methods within the hosting application.&amp;#160; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9940150" width="1" height="1"&gt;</description></item><item><title>Host Provided Capabilities (WF4 EditingContext Intro Part 3)</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/12/22/host-provided-capabilities-wf4-editingcontext-intro-part-3.aspx</link><pubDate>Tue, 22 Dec 2009 17:03:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9940125</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9940125</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/12/22/host-provided-capabilities-wf4-editingcontext-intro-part-3.aspx#comments</comments><description>&lt;p&gt;This part 3 of my 6&amp;#160; part series on the EditingContext.&lt;/p&gt;  &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/introduction-to-the-wf4-designer-editing-context-part-1.aspx"&gt;Introduction&lt;/a&gt; &lt;/li&gt;  &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/sharing-functionality-between-designers-wf4-editingcontext-intro-part-2.aspx"&gt;Sharing Functionality between Designers&lt;/a&gt;&amp;#160; &lt;/li&gt;  &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/host-provided-capabilities-wf4-editingcontext-intro-part-3.aspx"&gt;Host provided capabilities&amp;#160; (you are here)&lt;/a&gt; &lt;/li&gt;  &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/providing-callbacks-for-the-host-wf4-editingcontext-intro-part-4.aspx"&gt;Providing callbacks for the host&lt;/a&gt; &lt;/li&gt;  &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/subscription-notification-engine-wf4-editingcontext-intro-part-5.aspx"&gt;Subscription/Notification engine&lt;/a&gt; &lt;/li&gt;  &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/23/inspection-default-services-and-items-wf4-editingcontext-intro-part-6.aspx"&gt;Inspection, Default Services and Items&lt;/a&gt;     &lt;p&gt;EditingContext is used by our primary hosting application, Visual Studio, to provide concrete implementations of certain services.&amp;#160; The example that we will talk about here is the &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.view.iexpressioneditorservice(VS.100).aspx"&gt;IExpressionEditorService&lt;/a&gt;.&amp;#160; Now, one thing that we would have really liked to have done in vs2010 is to provide a way to use the intellisense enabled VB editor that you see within VS inside a rehosted app.&amp;#160; For various reasons, we were not able to ship with that dependency in the .NET framework.&amp;#160; However, we needed a mechanism for our primary host to have the intellisense experience (and similarly, you could build an experience, or maybe we’ll ship one in the future for rehosted apps).&amp;#160; &lt;/p&gt;    &lt;p&gt;Let’s look at the design of IExpressionEditorService:&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;table border="0" cellspacing="0" cellpadding="0" width="447"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td width="194"&gt;Name&lt;/td&gt;          &lt;td width="251"&gt;Description&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td width="195"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.view.iexpressioneditorservice.closeexpressioneditors(VS.100).aspx"&gt;CloseExpressionEditors&lt;/a&gt;&lt;/td&gt;          &lt;td width="252"&gt;Closes all the active expression editors.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td width="196"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.view.iexpressioneditorservice.createexpressioneditor(VS.100).aspx"&gt;CreateExpressionEditor&lt;/a&gt;&lt;/td&gt;          &lt;td width="253"&gt;Overloaded. Creates a new expression editor.&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td width="197"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee474050(VS.100).aspx"&gt;UpdateContext&lt;/a&gt;&lt;/td&gt;          &lt;td width="254"&gt;Updates the context for the editing session. &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;    &lt;p&gt;Inside the ExpressionTextBox control, when the control needs to render the editor, it has code that looks like the following (note, if it can’t find an instance, it skips and just uses a plain old text box):&lt;/p&gt;    &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.Context.Services.GetService&amp;lt;IExpressionEditorService&amp;gt;() != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
{
      &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.Context.Services.GetService&amp;lt;IExpressionEditorService&amp;gt;().CreateExpressionEditor(...)
}&lt;/pre&gt;

  &lt;p&gt;Using the following overload of &lt;a href="IExpressionEditorInstance CreateExpressionEditor("&gt;CreateExpressionEditor&lt;/a&gt;:&lt;/p&gt;

  &lt;pre class="csharpcode"&gt;IExpressionEditorInstance CreateExpressionEditor(
    AssemblyContextControlItem assemblies,
    ImportedNamespaceContextItem importedNamespaces,
    List&amp;lt;ModelItem&amp;gt; variables,
    &lt;span class="kwrd"&gt;string&lt;/span&gt; text
)&lt;/pre&gt;
  &lt;style type="text/css"&gt;






.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

  &lt;p&gt;Now, what happens is that inside the code that we ship in the Microsoft.VisualStudio.Activities.Addin.dll, there is both a concrete implementation of this type, as well as the code which will publish an instance of this to the editing context.&amp;#160; Remember, this is the same thing that you can do in your app for a these host provided services.&amp;#160; In a subsequent post, I will get into more details of what are the ones that the designer has built in (like IExpressionEditorService).&amp;#160; &lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;
&lt;/li&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9940125" width="1" height="1"&gt;</description></item><item><title>Sharing Functionality Between Designers (WF4 EditingContext Intro Part 2)</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/12/21/sharing-functionality-between-designers-wf4-editingcontext-intro-part-2.aspx</link><pubDate>Mon, 21 Dec 2009 22:10:24 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9939811</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9939811</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/12/21/sharing-functionality-between-designers-wf4-editingcontext-intro-part-2.aspx#comments</comments><description>&lt;p&gt;This part 2 of my 6 part series on the EditingContext.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/introduction-to-the-wf4-designer-editing-context-part-1.aspx"&gt;Introduction&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/sharing-functionality-between-designers-wf4-editingcontext-intro-part-2.aspx"&gt;Sharing Functionality between Designers&amp;#160; (you are here)&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/host-provided-capabilities-wf4-editingcontext-intro-part-3.aspx"&gt;Host provided capabilities&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/providing-callbacks-for-the-host-wf4-editingcontext-intro-part-4.aspx"&gt;Providing callbacks for the host&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/subscription-notification-engine-wf4-editingcontext-intro-part-5.aspx"&gt;Subscription/Notification engine&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/23/inspection-default-services-and-items-wf4-editingcontext-intro-part-6.aspx"&gt;Inspection, Default Services and Items&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;&amp;#160;&lt;/h1&gt;  &lt;h1&gt;Setup&lt;/h1&gt;  &lt;p&gt;We will need a custom activity, EmptyOne and designer called InteractWithServiceDesigner.&amp;#160; &lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Activities;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.ComponentModel;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; blogEditingContext
{
    [Designer(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(InteractWithServicesDesigner))]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;sealed&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; EmptyOne : CodeActivity
    {
        &lt;span class="rem"&gt;// Define an activity input argument of type string&lt;/span&gt;
        &lt;span class="kwrd"&gt;public&lt;/span&gt; InArgument&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; Text { get; set; }

        &lt;span class="rem"&gt;// If your activity returns a value, derive from CodeActivity&amp;lt;TResult&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;// and return the value from the Execute method.&lt;/span&gt;
        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Execute(CodeActivityContext context)
        {
            &lt;span class="rem"&gt;// Obtain the runtime value of the Text input argument&lt;/span&gt;
            &lt;span class="kwrd"&gt;string&lt;/span&gt; text = context.GetValue(&lt;span class="kwrd"&gt;this&lt;/span&gt;.Text);
        }
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;





.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;h1&gt;What We Will See&lt;/h1&gt;

&lt;p&gt;The designers for Foo will leverage a new service in order to display a list of database tables.&amp;#160; We will also need to publish this service to the editing context, and handle the fact that we don’t know who might publish it (or when it might be published).&amp;#160; Note that in VS, there is no way to inject services except by having an activity designer do it.&amp;#160;&amp;#160; In a rehosted app, the hosting application could publish additional services (see part 4) that the activities can consume.&amp;#160; In this case though, we will use the activity designer as our hook.&lt;/p&gt;

&lt;h1&gt;Publishing a Service&lt;/h1&gt;

&lt;p&gt;Let’s look at the designer for Foo (as Foo is our generic, and relatively boring activity).&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sap:ActivityDesigner&lt;/span&gt; &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;blogEditingContext.InteractWithServicesDesigner&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:sap&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:sapv&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ListBox&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;100&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;listBox1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;120&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Button&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;button1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Click&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Button_Click&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Publish Service&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Button&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;sap:ActivityDesigner&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;









.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Not much to this, except a drop down list that is currently unbound (but a name is provided).&amp;#160; Also note that there is a button that says to “publish the service”.&amp;#160; Let’s first look at the code for the button click&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Button_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (!&lt;span class="kwrd"&gt;this&lt;/span&gt;.Context.Services.Contains&amp;lt;ISampleService&amp;gt;())
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.Context.Services.Publish&amp;lt;ISampleService&amp;gt;(&lt;span class="kwrd"&gt;new&lt;/span&gt; SampleServiceImpl());
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;









.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;What are we doing here?&amp;#160; We first check if this service is already published using the Contains method.&amp;#160; We can do this because ServiceManager implements IEnumerable&amp;lt;Type&amp;gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[update, finishing this sentence.]&amp;#160; One could also consume the service using&lt;/strong&gt;&amp;#160; &lt;a href="http://msdn.microsoft.com/en-us/library/ee403882(VS.100).aspx"&gt;GetService&amp;lt;TResult&amp;gt;.&lt;/a&gt;&amp;#160; You may also note that there is a &lt;a href="http://msdn.microsoft.com/en-us/library/ee407849(VS.100).aspx"&gt;GetRequiredService&amp;lt;T&amp;gt;&lt;/a&gt;.&amp;#160; This is a call that we know won’t return null, as the services we are requesting must be there for the designer to work.&amp;#160; Rather than returning null, this will throw an exception. Within the designer, we generally think of one service as required:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.services.modelservice(VS.100).aspx"&gt;ModelService&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s look at the definition of the service.&amp;#160; Here you can see that we are using both an interface and then providing an implementation of that interface.&amp;#160; You could just as easily use an abstract class, or even a concrete class, there is no constraint on the service type.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; blogEditingContext
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; ISampleService
    {
        IEnumerable&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; GetDropdownValues(&lt;span class="kwrd"&gt;string&lt;/span&gt; DisplayName);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SampleServiceImpl : ISampleService
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; IEnumerable&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; GetDropdownValues(&lt;span class="kwrd"&gt;string&lt;/span&gt; DisplayName)
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[]  { 
                DisplayName + &lt;span class="str"&gt;&amp;quot; Foo&amp;quot;&lt;/span&gt;, 
                DisplayName + &lt;span class="str"&gt;&amp;quot; Bar&amp;quot;&lt;/span&gt;,
                &lt;span class="str"&gt;&amp;quot;Baz &amp;quot;&lt;/span&gt; + DisplayName
            } ;
        }
    }

}&lt;/pre&gt;
&lt;style type="text/css"&gt;









.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;If there is not a service present, we will publish an instance of one.&amp;#160; This becomes the singleton instance for any other designer that may request it.&amp;#160; Right now, we have a designer that can safely publish a service.&amp;#160; Let’s look at consuming one&lt;/p&gt;

&lt;h1&gt;Consuming a Service&lt;/h1&gt;

&lt;p&gt;Let’s look at some code to consume the service.&amp;#160; There are two parts to this.&amp;#160; One is simply consuming it, which we already saw above &lt;strong&gt;in discussing GetService and GetRequiredService&lt;/strong&gt; .&amp;#160; The second is hooking into the notification system to let us know when a service is made available.&amp;#160; In this case, it’s a little contrived, as the service isn’t published until the button click, but it’s good practice to use the subscription mechanism as we make no guarantees on ordering, or timing of service availability. &lt;/p&gt;

&lt;h2&gt;Subscribing to Service&lt;/h2&gt;

&lt;p&gt;Here, using the &lt;a href="http://msdn.microsoft.com/en-us/library/ee403953(VS.100).aspx"&gt;Subscribe&amp;lt;TServiceType&amp;gt;&lt;/a&gt; method, we wait for the service to be available.&amp;#160; The documentation summarizes this method nicely:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Invokes the provided callback when someone has published the requested service. If the service was already available, this method invokes the callback immediately.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the OnModelItemChanged method, we will subscribe and hook a callback.&amp;#160; The callback’s &lt;a href="http://msdn.microsoft.com/en-us/library/ee425837(VS.100).aspx"&gt;signature&lt;/a&gt; is as follows:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SubscribeServiceCallback&amp;lt;TServiceType&amp;gt;(
    TServiceType serviceInstance
)&lt;/pre&gt;
&lt;style type="text/css"&gt;











.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;As you can see, in this callback, the service instance is provided, so we can query it directly. You may ask, “why not in Intialize?”&amp;#160; well, there are no guarentees that the editing context will be available at that point. We could either subscribe to context being made available, or just use ModelItemChanged:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnModelItemChanged(&lt;span class="kwrd"&gt;object&lt;/span&gt; newItem)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (!subscribed)
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.Context.Services.Subscribe&amp;lt;ISampleService&amp;gt;(
            servInstance =&amp;gt;
            {
                listBox1.ItemsSource = servInstance.GetDropdownValues(&lt;span class="kwrd"&gt;this&lt;/span&gt;.ModelItem.Properties[&lt;span class="str"&gt;&amp;quot;DisplayName&amp;quot;&lt;/span&gt;].ComputedValue.ToString());
                button1.IsEnabled = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            }
            );
        subscribed = &lt;span class="kwrd"&gt;true&lt;/span&gt;; 
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;









.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;This wraps a basic introduction to the ServiceManager type and how to leverage it effectively to share functionality in designers.&lt;/p&gt;

&lt;p&gt;Let’s look at a before and after shot in the designer:&lt;/p&gt;

&lt;h2&gt;Before &amp;amp; After&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/c76c6e55bb1b_12118/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="before" border="0" alt="before" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/c76c6e55bb1b_12118/image_thumb.png" width="176" height="467" /&gt;&lt;/a&gt; &lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/c76c6e55bb1b_12118/image_6.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="after" border="0" alt="after" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/c76c6e55bb1b_12118/image_thumb_2.png" width="174" height="467" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;&amp;#160;&lt;/h2&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;What about Items?&lt;/h1&gt;

&lt;p&gt;Items follow generally the same &lt;a href="http://msdn.microsoft.com/en-us/library/ee403629(VS.100).aspx"&gt;Get&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/ee425855(VS.100).aspx"&gt;Subscribe&lt;/a&gt;, and publish pattern, but rather than publish, there is a &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.contextitemmanager.setvalue(VS.100).aspx"&gt;SetValue&lt;/a&gt; method.&amp;#160; If you have “just data” that you would like to share between designers (or between the host and the designer) an Item is the way to go about that.&amp;#160; The most commonly used item we’ve seen customers use is the &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.view.selection(VS.100).aspx"&gt;Selection&lt;/a&gt; item in order to be able to get or set the currently selected model item.&lt;/p&gt;

&lt;p&gt;That’s our tour of basic publish and subscribe with Services and Items.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[updated 12/22/2009 @ 10:23 am to finish an unclear sentence about GetService&amp;lt;&amp;gt;]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[updated 12/22/2009 @ 8:50pm : Link to download sample code is here]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Attachment(s): &lt;/b&gt;&lt;a href="http://blogs.msdn.com/mwinkle/attachment/9940348.ashx"&gt;blogEditingContext.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9939811" width="1" height="1"&gt;</description></item><item><title>Introduction to the WF4 Designer Editing Context (Part 1)</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/12/21/introduction-to-the-wf4-designer-editing-context-part-1.aspx</link><pubDate>Mon, 21 Dec 2009 18:02:43 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9939686</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9939686</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/12/21/introduction-to-the-wf4-designer-editing-context-part-1.aspx#comments</comments><description>&lt;p&gt;I want to briefly touch on the editing context and give a little introduction to its capabilities.&amp;#160; This is part 1 of a 6 part series&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/introduction-to-the-wf4-designer-editing-context-part-1.aspx"&gt;Introduction (you are here)&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/21/sharing-functionality-between-designers-wf4-editingcontext-intro-part-2.aspx"&gt;Sharing Functionality between Designers&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/host-provided-capabilities-wf4-editingcontext-intro-part-3.aspx"&gt;Host provided capabilities&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/providing-callbacks-for-the-host-wf4-editingcontext-intro-part-4.aspx"&gt;Providing callbacks for the host&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/22/subscription-notification-engine-wf4-editingcontext-intro-part-5.aspx"&gt;Subscription/Notification engine&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/23/inspection-default-services-and-items-wf4-editingcontext-intro-part-6.aspx"&gt;Inspection, Default Services and Items&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The way to think about the editing context is that it is the point of contact between the hosting application, and the designer (and elements on the designer).&amp;#160; In my PDC talk, I had the following slide which I think captures the way to think about how these elements are layered together.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/IntroductiontotheWF4DesignerEditingConte_FBE3/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/IntroductiontotheWF4DesignerEditingConte_FBE3/image_thumb.png" width="581" height="421" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h1&gt;Motivation&lt;/h1&gt;  &lt;p&gt;The editing context represents the a common boundary between the hosting application and the designer, and the mechanism to handle interaction with the designer (outside of the most common methods that have been promoted on WorkflowDesigner).&amp;#160; If you were to look at the implementation of some of the more common methods on WorkflowDesigner, you would see that almost all of these use the editing context in order to get anything done.&amp;#160; For instance, the Flush method (and Save which calls Flush) will acquire an &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.hosting.idocumentpersistenceservice(VS.100).aspx"&gt;IDocumentPersistenceService&lt;/a&gt; from the Services collection, and then use that in order to properly serialize the document.&amp;#160; &lt;/p&gt;  &lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.editingcontext(VS.100,lightweight).aspx"&gt;EditingContext&lt;/a&gt; type has two important properties&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.editingcontext.items(VS.100).aspx"&gt;Items&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.editingcontext.services(VS.100).aspx"&gt;Services&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;Items&lt;/h1&gt;  &lt;p&gt;The Items collection is for data that is shared between the host and the designer, or data that is available to all designers.&amp;#160; These need to derive from &lt;a href="http://msdn.microsoft.com/en-us/library/ee403969(VS.100).aspx"&gt;ContextItem&lt;/a&gt; which will provide the mechanism to hook into subscription and change notification. There are a couple of interesting methods on the &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.contextitemmanager(VS.100).aspx"&gt;ContextItemManager&lt;/a&gt; type&amp;#160; :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee403629(VS.100).aspx"&gt;GetValue&amp;lt;TItemType&amp;gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee403526(VS.100).aspx"&gt;Subscribe&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee403928(VS.100).aspx"&gt;Unsubscribe&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.contextitemmanager.setvalue(VS.100).aspx"&gt;SetValue&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;Services&lt;/h1&gt;  &lt;p&gt;Services represent functionality that is either provided by the host for the designer to use, or is used by the designer to make functionality available to all designers within the editor.&amp;#160; Generally, these are likely defined as interfaces, but can also be a type.&amp;#160; It is then required for an implementation or an instance to be provided.&amp;#160; This instance will be shared as a singleton.&amp;#160; There are&amp;#160; a few interesting methods on the &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.servicemanager_methods(VS.100).aspx"&gt;ServiceManager&lt;/a&gt; type:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.servicemanager.publish(VS.100).aspx"&gt;Publish&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee403874(VS.100).aspx"&gt;Subscribe&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee408361(VS.100).aspx"&gt;Unsubscribe&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee403882(VS.100).aspx"&gt;GetService&amp;lt;TServiceType&amp;gt;&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We’ll start walking through these over the next few posts.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9939686" width="1" height="1"&gt;</description></item><item><title>Emitting the mc:Ignorable Instruction In Your WF4 XAML</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/12/10/emitting-the-mc-ignorable-instruction-in-your-wf4-xaml.aspx</link><pubDate>Thu, 10 Dec 2009 21:33:48 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9935376</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9935376</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/12/10/emitting-the-mc-ignorable-instruction-in-your-wf4-xaml.aspx#comments</comments><description>&lt;p&gt;Frequent forum guest Notre posed this &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/wfprerelease/thread/e60b68f8-e3d2-46bf-aa70-7280853cd3f5"&gt;question&lt;/a&gt; to the forums the other day noting that the XAML being produced from &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.xamlintegration.activityxamlservices.createbuilderwriter(VS.100).aspx"&gt;ActivityXamlServices.CreateBuilderWriter()&lt;/a&gt; was slightly different than the XAML being output from &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.workflowdesigner.save(VS.100).aspx"&gt;WorkflowDesigner.Save().&lt;/a&gt;&amp;#160; The reason for this stems from the fact that WorkflowDesigner leverages an additional internal type (which derives from XamlXmlWriter) in order to attach the mc:Ignorable attribute.&amp;#160; &lt;/p&gt;  &lt;h1&gt;Why use mc:Ignorable?&lt;/h1&gt;  &lt;p&gt;From the &lt;a href="http://msdn.microsoft.com/en-us/library/aa350024.aspx"&gt;source&lt;/a&gt; at MSDN:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;The mc XML namespace prefix is the recommended prefix convention to use when mapping the XAML compatibility namespace http://schemas.openxmlformats.org/markup-compatibility/2006.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Elements or attributes where the prefix portion of the element name are identified as mc:Ignorable will not raise errors when processed by a XAML processor. If that attribute could not be resolved to an underlying type or programming construct, then that element is ignored. Note however that ignored elements might still generate additional parsing errors for additional element requirements that are side effects of that element not being processed. For instance, a particular element content model might require exactly one child element, but if the specified child element was in an mc:Ignorable prefix, and the specified child element could not be resolved to a type, then the XAML processor might raise an error.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Basically, this lets a XAML reader gracefully ignore any content marked from that namespace if it cannot be resolved.&amp;#160; So, imagine a runtime scenario where we don’t want to load System.Activities.Presentation every time we read a WF XAML file that may contain viewstate.&amp;#160; As a result, we use mc:Ignorable, which means the reader will skip that content when it does not have that assembly referenced at runtime.&amp;#160; &lt;/p&gt;  &lt;p&gt;This is what the output from the designer usually contains:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt; 
     &lt;span class="attr"&gt;mc:Ignorable&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;sap&amp;quot;&lt;/span&gt; 
     &lt;span class="attr"&gt;mva:VisualBasic&lt;/span&gt;.&lt;span class="attr"&gt;Settings&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Assembly references and imported namespaces serialized as XML namespaces&amp;quot;&lt;/span&gt;
     &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/netfx/2009/xaml/activities&amp;quot;&lt;/span&gt; 
     &lt;span class="attr"&gt;xmlns:mc&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.openxmlformats.org/markup-compatibility/2006&amp;quot;&lt;/span&gt;
     &lt;span class="attr"&gt;xmlns:mva&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities&amp;quot;&lt;/span&gt; 
     &lt;span class="attr"&gt;xmlns:sap&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation&amp;quot;&lt;/span&gt; 
     &lt;span class="attr"&gt;xmlns:scg&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:System.Collections.Generic;assembly=mscorlib&amp;quot;&lt;/span&gt; 
     &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sap:WorkflowViewStateService.ViewState&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;scg:Dictionary&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String, x:Object&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;x:Boolean&lt;/span&gt; &lt;span class="attr"&gt;x:Key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;IsExpanded&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;True&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;x:Boolean&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;scg:Dictionary&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;sap:WorkflowViewStateService.ViewState&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Persist&lt;/span&gt; &lt;span class="attr"&gt;sap:VirtualizedContainerService&lt;/span&gt;.&lt;span class="attr"&gt;HintSize&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;211,22&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Persist&lt;/span&gt; &lt;span class="attr"&gt;sap:VirtualizedContainerService&lt;/span&gt;.&lt;span class="attr"&gt;HintSize&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;211,22&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;WriteLine&lt;/span&gt; &lt;span class="attr"&gt;sap:VirtualizedContainerService&lt;/span&gt;.&lt;span class="attr"&gt;HintSize&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;211,61&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;mc:Ignorable will cause the ViewState and HintSize to be ignored. &lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;Why do I have to worry about this?&lt;/h1&gt;

&lt;p&gt;If you use WorkflowDesigner.Save(), you don’t.&amp;#160; If you want to be able to serialize the ActivityBuilder and have XAML which is what the designer produces, you need will need to add a XamlXmlWriter into the XamlWriter stack in order to get the right output. You may also worry about this if you are implementing your own storage and plan on writing some additional XAML readers or writers for additional extensibility and flexibility.&lt;/p&gt;

&lt;h1&gt;How Do I Get the Same Behavior?&lt;/h1&gt;

&lt;p&gt;The code below describes the same approach you would need to take to implement an XamlXmlWriter that does the same thing our internal type does.&amp;#160; While I can’t copy and paste code, this does the same thing.&amp;#160; We do two things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Override &lt;a title="WriteNamespace(" href="http://msdn.microsoft.com/en-us/library/system.xaml.xamlxmlwriter.writenamespace(VS.100).aspx"&gt;WriteNamespace(&lt;/a&gt;) to collect all of the namespaces being emitted.&amp;#160; We do this to specifically check for ones that we should ignore, and to also gather all of the prefixes to make sure we don’t have a collision&lt;/li&gt;

  &lt;li&gt;Override &lt;a title="WriteStartObject" href="http://msdn.microsoft.com/en-us/library/system.xaml.xamlxmlwriter.writestartobject(VS.100).aspx"&gt;WriteStartObject&lt;/a&gt;() to generate and write out the Ignorable attribute within the start (first) member for any namespaces we should ignore.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What namespaces do we ignore in the designer?&amp;#160; Just one: &lt;strong&gt;&lt;em&gt;http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Xaml;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Xml;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; IgnorableXamlWriter&lt;/pre&gt;

    &lt;pre class="alt"&gt;{&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; IgnorableXamlXmlWriter : XamlXmlWriter&lt;/pre&gt;

    &lt;pre class="alt"&gt;    {&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        HashSet&amp;lt;NamespaceDeclaration&amp;gt; ignorableNamespaces = &lt;span class="kwrd"&gt;new&lt;/span&gt; HashSet&amp;lt;NamespaceDeclaration&amp;gt;();&lt;/pre&gt;

    &lt;pre&gt;        HashSet&amp;lt;NamespaceDeclaration&amp;gt; allNamespaces = &lt;span class="kwrd"&gt;new&lt;/span&gt; HashSet&amp;lt;NamespaceDeclaration&amp;gt;();&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;bool&lt;/span&gt; objectWritten;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;bool&lt;/span&gt; hasDesignNamespace;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; designNamespacePrefix;&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; IgnorableXamlXmlWriter(TextWriter tw, XamlSchemaContext context)&lt;/pre&gt;

    &lt;pre&gt;            : &lt;span class="kwrd"&gt;base&lt;/span&gt;(XmlWriter.Create(tw,&lt;/pre&gt;

    &lt;pre class="alt"&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; XmlWriterSettings { Indent = &lt;span class="kwrd"&gt;true&lt;/span&gt;, OmitXmlDeclaration = &lt;span class="kwrd"&gt;true&lt;/span&gt; }),&lt;/pre&gt;

    &lt;pre&gt;                                    context,&lt;/pre&gt;

    &lt;pre class="alt"&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; XamlXmlWriterSettings { AssumeValidInput = &lt;span class="kwrd"&gt;true&lt;/span&gt; })&lt;/pre&gt;

    &lt;pre&gt;        {&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; WriteNamespace(NamespaceDeclaration namespaceDeclaration)&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!objectWritten)&lt;/pre&gt;

    &lt;pre class="alt"&gt;            {&lt;/pre&gt;

    &lt;pre&gt;                allNamespaces.Add(namespaceDeclaration);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="rem"&gt;// if we find one, add that to ignorable namespaces&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="rem"&gt;// the goal here is to collect all of them that might point to this&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="rem"&gt;// if you had a broader set of things to ignore, you would collect &lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="rem"&gt;// those here.&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (namespaceDeclaration.Namespace == &lt;span class="str"&gt;&amp;quot;http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre&gt;                {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    hasDesignNamespace = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;                    designNamespacePrefix = namespaceDeclaration.Prefix;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                }&lt;/pre&gt;

    &lt;pre&gt;            }&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;base&lt;/span&gt;.WriteNamespace(namespaceDeclaration);&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; WriteStartObject(XamlType type)&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!objectWritten)&lt;/pre&gt;

    &lt;pre class="alt"&gt;            {&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="rem"&gt;// we should check if we should ignore &lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (hasDesignNamespace)&lt;/pre&gt;

    &lt;pre&gt;                {&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    &lt;span class="rem"&gt;// note this is not robust as mc could naturally occur&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;                    &lt;span class="kwrd"&gt;string&lt;/span&gt; mcAlias = &lt;span class="str"&gt;&amp;quot;mc&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;this&lt;/span&gt;.WriteNamespace(&lt;/pre&gt;

    &lt;pre&gt;                        &lt;span class="kwrd"&gt;new&lt;/span&gt; NamespaceDeclaration(&lt;/pre&gt;

    &lt;pre class="alt"&gt;                            &lt;span class="str"&gt;&amp;quot;http://schemas.openxmlformats.org/markup-compatibility/2006&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

    &lt;pre&gt;                            mcAlias)&lt;/pre&gt;

    &lt;pre class="alt"&gt;                            );&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                }&lt;/pre&gt;

    &lt;pre&gt;            }&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;base&lt;/span&gt;.WriteStartObject(type);&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!objectWritten)&lt;/pre&gt;

    &lt;pre class="alt"&gt;            {&lt;/pre&gt;

    &lt;pre&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (hasDesignNamespace)&lt;/pre&gt;

    &lt;pre class="alt"&gt;                {&lt;/pre&gt;

    &lt;pre&gt;                    XamlDirective ig = &lt;span class="kwrd"&gt;new&lt;/span&gt; XamlDirective(&lt;/pre&gt;

    &lt;pre class="alt"&gt;                        &lt;span class="str"&gt;&amp;quot;http://schemas.openxmlformats.org/markup-compatibility/2006&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

    &lt;pre&gt;                        &lt;span class="str"&gt;&amp;quot;Ignorable&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    WriteStartMember(ig);&lt;/pre&gt;

    &lt;pre&gt;                    WriteValue(designNamespacePrefix);&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    WriteEndMember();&lt;/pre&gt;

    &lt;pre&gt;                    objectWritten = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre class="alt"&gt;                }&lt;/pre&gt;

    &lt;pre&gt;            }&lt;/pre&gt;

    &lt;pre class="alt"&gt;        }&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;}&lt;/pre&gt;
  &lt;/div&gt;
  &lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;One note on the code above, it is noted that the generation of the namespace prefix “mc” is not robust.&amp;#160; In the product code we will check to see if mc1, mc2, … are available up to mc1000.&amp;#160; In that case we would then append a GUID for the ugliest XML namespace known to mankind.&amp;#160; The chance of collision up to 1000 would be a highly extreme edge case.&lt;/p&gt;

&lt;p&gt;How would I use this? The following code shows feeding this into a CreateBuilderWriter that is passed to XamlServices.Save()&lt;/p&gt;

&lt;pre class="csharpcode"&gt;StringBuilder sb = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();
XamlSchemaContext xsc = &lt;span class="kwrd"&gt;new&lt;/span&gt; XamlSchemaContext();
var bw = ActivityXamlServices.CreateBuilderWriter(
    &lt;span class="kwrd"&gt;new&lt;/span&gt; IgnorableXamlXmlWriter(&lt;span class="kwrd"&gt;new&lt;/span&gt; StringWriter(sb), xsc));

XamlServices.Save(bw,
                  wd.Context.Services.GetService&amp;lt;ModelTreeManager&amp;gt;().Root.GetCurrentValue());&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9935376" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/wf4/">wf4</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/xaml/">xaml</category></item><item><title>AttachedProperty Part 2, Putting it Together</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/12/07/attachedproperty-part-2-putting-it-together.aspx</link><pubDate>Mon, 07 Dec 2009 05:19:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9933272</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9933272</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/12/07/attachedproperty-part-2-putting-it-together.aspx#comments</comments><description>&lt;p&gt;On my last &lt;a href="http://bit.ly/6z2THv"&gt;post&lt;/a&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/06/wf4-design-time-attachedpropertiesservice-and-attached-properties.aspx"&gt;&lt;/a&gt;, Jason jumped right to the punchline in his comment &lt;a href="http://bit.ly/6z2THv"&gt;here&lt;/a&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/06/wf4-design-time-attachedpropertiesservice-and-attached-properties.aspx#9933257"&gt;&lt;/a&gt;. He asks “if there is an easy way to have the properties value serialized out to the xaml.” &lt;/p&gt;  &lt;p&gt;First, let’s look at what we need to do from the XAML side.&lt;/p&gt;  &lt;p&gt;First, create a helper type with a getter and setter for the property that you want to attach.&amp;#160; Here we’re going to attach comments:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Comment
{
    &lt;span class="kwrd"&gt;static&lt;/span&gt; AttachableMemberIdentifier CommentTextName = &lt;span class="kwrd"&gt;new&lt;/span&gt; AttachableMemberIdentifier(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Comment), &lt;span class="str"&gt;&amp;quot;CommentText&amp;quot;&lt;/span&gt;);

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; GetCommentText(&lt;span class="kwrd"&gt;object&lt;/span&gt; instance)
    {
        &lt;span class="kwrd"&gt;object&lt;/span&gt; viewState;
        AttachablePropertyServices.TryGetProperty(instance, CommentTextName, &lt;span class="kwrd"&gt;out&lt;/span&gt; viewState);
        &lt;span class="kwrd"&gt;return&lt;/span&gt; viewState;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SetCommentText(&lt;span class="kwrd"&gt;object&lt;/span&gt; instance, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;)
    {
        AttachablePropertyServices.SetProperty(instance, CommentTextName, &lt;span class="kwrd"&gt;value&lt;/span&gt;);
    }

}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Next, let’s use the &lt;a href="http://msdn.microsoft.com/en-us/library/system.xaml.attachablememberidentifier(VS.100).aspx"&gt;AttachableMemberIdentifier&lt;/a&gt; and the &lt;a href="http://msdn.microsoft.com/en-us/library/system.xaml.attachablepropertyservices(VS.100).aspx"&gt;AttachablePropertyServices&lt;/a&gt; to do something interesting with this:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;AttachableMemberIdentifier ami = &lt;span class="kwrd"&gt;new&lt;/span&gt; AttachableMemberIdentifier(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Comment), &lt;span class="str"&gt;&amp;quot;CommentText&amp;quot;&lt;/span&gt;);
Dog newDog = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dog { Age = 12, Name = &lt;span class="str"&gt;&amp;quot;Sherlock&amp;quot;&lt;/span&gt;, Noise = &lt;span class="str"&gt;&amp;quot;Hooowl&amp;quot;&lt;/span&gt; };
AttachablePropertyServices.SetProperty(newDog, ami, &lt;span class="str"&gt;&amp;quot;A very good dog&amp;quot;&lt;/span&gt;);
&lt;span class="kwrd"&gt;string&lt;/span&gt; s = XamlServices.Save(newDog);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;XAML&amp;quot;&lt;/span&gt;);
Console.WriteLine(s);
Dog aSecondNewDog = XamlServices.Load(&lt;span class="kwrd"&gt;new&lt;/span&gt; StringReader(s)) &lt;span class="kwrd"&gt;as&lt;/span&gt; Dog;
&lt;span class="kwrd"&gt;string&lt;/span&gt; outter;
AttachablePropertyServices.TryGetProperty(aSecondNewDog, ami, &lt;span class="kwrd"&gt;out&lt;/span&gt; outter);
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;read out: {0}&amp;quot;&lt;/span&gt;, outter);&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Let’s see the output from this:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;XAML
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Dog&lt;/span&gt;
     &lt;span class="attr"&gt;Age&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;12&amp;quot;&lt;/span&gt;
     &lt;span class="attr"&gt;Comment&lt;/span&gt;.&lt;span class="attr"&gt;CommentText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;A very good dog&amp;quot;&lt;/span&gt;
     &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Sherlock&amp;quot;&lt;/span&gt;
     &lt;span class="attr"&gt;Noise&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Hooowl&amp;quot;&lt;/span&gt; 
     &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:AttachedPropertiesBlogPosting;assembly=AttachedPropertiesBlogPosting&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
read out: A very good dog&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;You’ll note that the value is contained in the XAML under Comment.CommentText.&lt;/p&gt;

&lt;h1&gt;Pulling it all Together&lt;/h1&gt;

&lt;p&gt;Let’s take what we did in the last post and combine it with the above stuff in order to have an attached property that writes through and is stored inside the XAML.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; Comment = &lt;span class="kwrd"&gt;new&lt;/span&gt; AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;
{
    IsBrowsable = &lt;span class="kwrd"&gt;true&lt;/span&gt;,
    Name = &lt;span class="str"&gt;&amp;quot;Comment&amp;quot;&lt;/span&gt;,
    Getter = (mi =&amp;gt;
        { &lt;span class="kwrd"&gt;string&lt;/span&gt; temp;
          AttachablePropertyServices.TryGetProperty&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(mi.GetCurrentValue(), ami, &lt;span class="kwrd"&gt;out&lt;/span&gt; temp);
          &lt;span class="kwrd"&gt;return&lt;/span&gt; temp;
        }),
    Setter = ( (mi,val) =&amp;gt; AttachablePropertyServices.SetProperty(mi.GetCurrentValue(), ami, val) )

};
aps.AddProperty(Comment);
dogMi.Properties[&lt;span class="str"&gt;&amp;quot;Comment&amp;quot;&lt;/span&gt;].SetValue(&lt;span class="str"&gt;&amp;quot;I think I like that dog&amp;quot;&lt;/span&gt;);
&lt;span class="kwrd"&gt;string&lt;/span&gt; xaml = XamlServices.Save(dogMi.GetCurrentValue());
Console.WriteLine(&lt;span class="str"&gt;&amp;quot;XAML&amp;quot;&lt;/span&gt;);
Console.WriteLine(xaml);&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;What are we doing here, well, we basically just use the Getter and Setter to write through to the underlying instance.&amp;#160; You’ll note that usually, we never want to go and use GetCurrentValue(), as any changes made there are not made via the ModelItem tree which means we might miss a change notification.&amp;#160; However, given that the only place where we can store the XAML attached property is on the instance itself, this gives us a good way to write through.&amp;#160; The XAML output below shows that this works as expected:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Dog&lt;/span&gt; 
   &lt;span class="attr"&gt;Age&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;5&amp;quot;&lt;/span&gt;
   &lt;span class="attr"&gt;Comment&lt;/span&gt;.&lt;span class="attr"&gt;CommentText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;I think I like that dog&amp;quot;&lt;/span&gt;
   &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Sasha&amp;quot;&lt;/span&gt; 
   &lt;span class="attr"&gt;Noise&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Snort&amp;quot;&lt;/span&gt; 
   &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:AttachedPropertiesBlogPosting;assembly=AttachedPropertiesBlogPosting&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9933272" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/wf4/">wf4</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/vs2010/">vs2010</category></item><item><title>WF4 Design Time AttachedPropertiesService and Attached Properties</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/12/06/wf4-design-time-attachedpropertiesservice-and-attached-properties.aspx</link><pubDate>Sun, 06 Dec 2009 04:51:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9933077</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9933077</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/12/06/wf4-design-time-attachedpropertiesservice-and-attached-properties.aspx#comments</comments><description>&lt;p&gt;I’ve been meaning to throw together some thoughts on attached properties and how they can be used within the designer.&amp;#160; Basically, you can think about attached properties as injecting some additional “stuff” onto an instance that you can use elsewhere in your code. &lt;/p&gt;  &lt;h1&gt;Motivation&lt;/h1&gt;  &lt;p&gt;In the designer, we want to be able to have behavior and view tied to interesting aspects of the data.&amp;#160; For instance, we would like to have a view updated when an item becomes selected.&amp;#160; In WPF, we bind the style based on the “isSelectionProperty.”&amp;#160; Now, our data model doesn’t have any idea of selection, it’s something we’d like the view level to “inject” that idea on any model item so that a subsequent view could take advantage of.&amp;#160; You can kind of view Attached Properties as a nice syntactic sugar to not have to keep a bunch of lookup lists around.&amp;#160; As things like WPF bind to the object very well, and not so much a lookup list, this ends up being an interesting model.&lt;/p&gt;  &lt;p&gt;To be clear, you could write a number of value converters that take the item being bound, look up in a lookup list somewhere, and return the result that will be used.&amp;#160; The problem we found is that we were doing this in a bunch of places, and we really wanted to have clean binding statements inside our WPF XAML, rather than hiding a bunch of logic in the converters. &lt;/p&gt;  &lt;h1&gt;How Does it Work&lt;/h1&gt;  &lt;p&gt;First, some types.&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="548"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="200"&gt;Name&lt;/td&gt;        &lt;td valign="top" width="346"&gt;Description&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.attachedpropertiesservice(VS.100).aspx"&gt;&lt;a href="http://bit.ly/6dvvwh"&gt;AttachedPropertiesService&lt;/a&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="346"&gt;Service in editing context for managing AttachedProperties&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.attachedproperty(VS.100).aspx"&gt;&lt;a href="http://bit.ly/4MioTX"&gt;AttachedProperty&lt;/a&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="346"&gt;Base attached property type (abstract)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee473952(VS.100).aspx"&gt;&lt;a href="http://bit.ly/4NYHil"&gt;AttachedProperty&amp;lt;T&amp;gt;&lt;/a&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="346"&gt;Strongly typed attached property with interesting getter/setter programmability&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;in diagram form:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/WF4DesignTimeAttachedPropertiesServicean_124AC/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/WF4DesignTimeAttachedPropertiesServicean_124AC/image_thumb.png" width="712" height="376" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;One thing that might look a little funny to some folks who have used attached properties in other contexts (WF3, WPF, XAML), is the “&lt;a href="http://bit.ly/5DvhJs"&gt;IsBrowsable&lt;/a&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.attachedproperty.isbrowsable(VS.100).aspx"&gt;&lt;/a&gt;” property.&amp;#160; The documentation is a little sparse right now, but what this will do is determine how discoverable the property is.&amp;#160; If this is set to true, the attached property will show up in the Properties collection of the ModelItem to which the AP is attached.&amp;#160; What this means is that it can show up in the Property grid, you can bind WPF statements directly to it, as if it were a real property of the object.&amp;#160; Attached properties by themselves have no actual storage representation, so these exist as design time only constructs. &lt;/p&gt;  &lt;h2&gt;Getter/ Setter? &lt;/h2&gt;  &lt;p&gt;One other thing that you see on the &lt;a href="http://msdn.microsoft.com/en-us/library/ee473952(VS.100).aspx"&gt;&lt;/a&gt;&lt;a href="http://bit.ly/4NYHil"&gt;AttachedProperty&amp;lt;T&amp;gt;&lt;/a&gt;&lt;/a&gt; is the &lt;a href="http://bit.ly/5woYQg"&gt;Getter&lt;/a&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee473895(VS.100).aspx"&gt;&lt;/a&gt; and &lt;a href="http://bit.ly/75yEyX"&gt;Setter&lt;/a&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ee473838(VS.100).aspx"&gt;&lt;/a&gt; properties.&amp;#160; These are of type Func&amp;lt;ModelItem,T&amp;gt; and Action&amp;lt;ModelItem,T&amp;gt; respectively.&amp;#160; What these allow you to do is perform some type of computation whenever the get or set is called against the AttachedProperty.&amp;#160; Why is this interesting?&amp;#160; Well, let’s say that you’d like to have a computed value retrieved, such as “IsPrimarySelection” checking with the Selection context item to see if an item is selected.&amp;#160; Or, customizing the setter to either store the value somewhere more durable, or updating a few different values.&amp;#160; The other thing that happens is that since all of these updates go through the ModelItem tree, any changes will be propagated to other listeners throughout the designer. &lt;/p&gt;  &lt;h1&gt;Looking at Some Code&lt;/h1&gt;  &lt;p&gt;Here is a very small console based app that shows how you can program against the attached properties.&amp;#160; An interesting exercise for the reader would be to take this data structure, put it in a WPF app and experiment with some of the data binding. &lt;/p&gt;  &lt;p&gt;First, two types:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Dog
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name { get; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Noise { get; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Age { get; set; }
   
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Cat
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name { get; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Noise { get; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Age { get; set; }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Ignore no common base type, that actually makes this a little more interesting, as we will see. &lt;/p&gt;

&lt;p&gt;Now, let’s write some code.&amp;#160; First, let’s initialize and &lt;a href="http://bit.ly/81kTQz"&gt;EditingContext&lt;/a&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.editingcontext(VS.100).aspx"&gt;&lt;/a&gt; and &lt;a href="http://bit.ly/5mJyPi"&gt;ModelTreeManager&lt;/a&gt;.&amp;#160; &lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;     &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;            EditingContext ec = &lt;span class="kwrd"&gt;new&lt;/span&gt; EditingContext();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;            ModelTreeManager mtm = &lt;span class="kwrd"&gt;new&lt;/span&gt; ModelTreeManager(ec);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;            mtm.Load(&lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;[] { &lt;span class="kwrd"&gt;new&lt;/span&gt; Dog { Name = &lt;span class="str"&gt;&amp;quot;Sasha&amp;quot;&lt;/span&gt;, Noise = &lt;span class="str"&gt;&amp;quot;Snort&amp;quot;&lt;/span&gt;, Age = 5 },&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; Cat { Name=&lt;span class="str"&gt;&amp;quot;higgs&amp;quot;&lt;/span&gt;, Noise=&lt;span class="str"&gt;&amp;quot;boom&amp;quot;&lt;/span&gt;, Age=1 } });&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;            dynamic root = mtm.Root;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;            dynamic dog = root[0];&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;            dynamic cat = root[1];&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            ModelItem dogMi = root[0] &lt;span class="kwrd"&gt;as&lt;/span&gt; ModelItem;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;            ModelItem catMi = root[1] &lt;span class="kwrd"&gt;as&lt;/span&gt; ModelItem;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note, lines 7-9 will not work in Beta2 (preview of coming attractions).&amp;#160; To get lines 10-11 working in beta2, cast root to ModelItemCollection and then use the indexers to extract the values&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, let’s build an attached property, and we will assign it only to type “dog”&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="rem"&gt;// Add an attached Property&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt; ap = &lt;span class="kwrd"&gt;new&lt;/span&gt; AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    IsBrowsable = &lt;span class="kwrd"&gt;true&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    Name = &lt;span class="str"&gt;&amp;quot;IsAnInterestingDog&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    Getter = (mi =&amp;gt; mi.Properties[&lt;span class="str"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;].ComputedValue.ToString() == &lt;span class="str"&gt;&amp;quot;Sasha&amp;quot;&lt;/span&gt;),&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    OwnerType = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Dog)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;};&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;ec.Services.Publish&amp;lt;AttachedPropertiesService&amp;gt;(&lt;span class="kwrd"&gt;new&lt;/span&gt; AttachedPropertiesService());&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;AttachedPropertiesService aps = ec.Services.GetService&amp;lt;AttachedPropertiesService&amp;gt;();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;aps.AddProperty(ap);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;&amp;quot;---- Enumerate properties on dog (note new property)----&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;dogMi.Properties.ToList().ForEach(mp =&amp;gt; Console.WriteLine(&lt;span class="str"&gt;&amp;quot; Property : {0}&amp;quot;&lt;/span&gt;, mp.Name));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;&amp;quot;---- Enumerate properties on cat (note  no new property) ----&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;catMi.Properties.ToList().ForEach(mp =&amp;gt; Console.WriteLine(&lt;span class="str"&gt;&amp;quot; Property : {0}&amp;quot;&lt;/span&gt;, mp.Name));&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Let’s break down what happened here.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Line2-8, create an AttachedProperty&amp;lt;bool&amp;gt;&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;We set &lt;a href="http://bit.ly/5DvhJs"&gt;IsBrowsable&lt;/a&gt; to true, we want to see it in the output&lt;/li&gt;

    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.attachedproperty.name(VS.100).aspx"&gt;&lt;a href="http://bit.ly/5a2cJS"&gt;Name&lt;/a&gt;&lt;/a&gt;, that’s what it will be projected as&lt;/li&gt;

    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.attachedproperty.ownertype(VS.100).aspx"&gt;&lt;a href="http://bit.ly/5GiqA1"&gt;OwnerType&lt;/a&gt;&lt;/a&gt;, we only want this to apply to Dog’s, not Cat’s or Objects or whatever.&lt;/li&gt;

    &lt;li&gt;Finally, &lt;a href="http://bit.ly/5woYQg"&gt;Getter&lt;/a&gt;, and look what we do here, we operate on the model item to do some computation and return a bool (in this case, we look to see if the name property equals “Sasha”&lt;/li&gt;
  &lt;/ul&gt;

  &lt;li&gt;Line 9-11 create an &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.attachedpropertiesservice(VS.100).aspx"&gt;&lt;/a&gt;&lt;a href="http://bit.ly/6dvvwh"&gt;AttachedPropertiesService&lt;/a&gt;&lt;/a&gt; and add it to the editing context.&lt;/li&gt;

  &lt;li&gt;Lines 13-17 output the properties, and let’s see what that looks like:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;---- Enumerate properties on dog (note new property)----&lt;/pre&gt;

  &lt;pre&gt; Property : Name&lt;/pre&gt;

  &lt;pre class="alt"&gt; Property : Noise&lt;/pre&gt;

  &lt;pre&gt; Property : Age&lt;/pre&gt;

  &lt;pre class="alt"&gt; Property : IsAnInterestingDog&lt;/pre&gt;

  &lt;pre&gt;---- Enumerate properties on cat (note  no new property) ----&lt;/pre&gt;

  &lt;pre class="alt"&gt; Property : Name&lt;/pre&gt;

  &lt;pre&gt; Property : Noise&lt;/pre&gt;

  &lt;pre class="alt"&gt; Property : Age&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Ok, so that’s interesting, we’ve injected a new property, only on the dog type.&amp;#160; If I got dogMI.Properties[“IsAnInterestingDog”], I would have a value that I could manipulate (albeit returned via the getter).&lt;/p&gt;

&lt;p&gt;Let’s try something a little different:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt; isYoungAnimal = &lt;span class="kwrd"&gt;new&lt;/span&gt; AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    IsBrowsable = &lt;span class="kwrd"&gt;false&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    Name = &lt;span class="str"&gt;&amp;quot;IsYoungAnimal&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    Getter = (mi =&amp;gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;.Parse(mi.Properties[&lt;span class="str"&gt;&amp;quot;Age&amp;quot;&lt;/span&gt;].ComputedValue.ToString()) &amp;lt; 2)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;};&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;aps.AddProperty(isYoungAnimal);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;&lt;span class="rem"&gt;// expect to not see isYoungAnimal show up&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;&amp;quot;---- Enumerate properties on dog  (note isYoungAnimal doesn't appear )----&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;dogMi.Properties.ToList().ForEach(mp =&amp;gt; Console.WriteLine(&lt;span class="str"&gt;&amp;quot; Property : {0}&amp;quot;&lt;/span&gt;, mp.Name));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;&amp;quot;---- Enumerate properties on cat (note isYoungAnimal doesn't appear )----&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;catMi.Properties.ToList().ForEach(mp =&amp;gt; Console.WriteLine(&lt;span class="str"&gt;&amp;quot; Property : {0}&amp;quot;&lt;/span&gt;, mp.Name));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;&amp;quot;---- get attached property via GetValue ----&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;&amp;quot;getting non browsable attached property on dog {0}&amp;quot;&lt;/span&gt;, isYoungAnimal.GetValue(dogMi));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;&amp;quot;getting non browsable attached property on cat {0}&amp;quot;&lt;/span&gt;, isYoungAnimal.GetValue(catMi));&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Let’s break this down:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Lines 1-6 create a new attached property&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;IsBrowsable is false&lt;/li&gt;

    &lt;li&gt;No OwnerType being set&lt;/li&gt;

    &lt;li&gt;The Getter does some computation to return true or false&lt;/li&gt;
  &lt;/ul&gt;

  &lt;li&gt;Lines 10-14 write out the properties (as above)&lt;/li&gt;

  &lt;li&gt;Lines 17-18 extract the value with &lt;em&gt;&lt;a href="http://bit.ly/67pRXJ"&gt;AttachedPropertyInstance.GetValue(ModelItem)&lt;/a&gt;&lt;/em&gt;&lt;em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.attachedproperty.getvalue(VS.100).aspx"&gt;&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s see the output there:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;--&lt;span class="rem"&gt;-- Enumerate properties on dog  (note isYoungAnimal doesn't appear )----&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt; Property : Name&lt;/pre&gt;

  &lt;pre class="alt"&gt; Property : Noise&lt;/pre&gt;

  &lt;pre&gt; Property : Age&lt;/pre&gt;

  &lt;pre class="alt"&gt; Property : IsAnInterestingDog&lt;/pre&gt;

  &lt;pre&gt;--&lt;span class="rem"&gt;-- Enumerate properties on cat (note isYoungAnimal doesn't appear )----&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt; Property : Name&lt;/pre&gt;

  &lt;pre&gt; Property : Noise&lt;/pre&gt;

  &lt;pre class="alt"&gt; Property : Age&lt;/pre&gt;

  &lt;pre&gt;--&lt;span class="rem"&gt;-- get attached property via GetValue ----&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;getting non browsable attached property &lt;span class="kwrd"&gt;on&lt;/span&gt; dog &lt;span class="kwrd"&gt;False&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;getting non browsable attached property &lt;span class="kwrd"&gt;on&lt;/span&gt; cat True&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;As we can see, we’ve now injected this behavior, and we can extract the value.&amp;#160; &lt;/p&gt;

&lt;p&gt;Let’s get a little more advanced and do something with the setter.&amp;#160; Here, if isYoungAnimal is set to true, we will change the age (it’s a bit contrived, but shows the dataflow on simple objects, we’ll see in a minute a more interesting case).&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="rem"&gt;// now, let's do something clever with the setter. &lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;&amp;quot;---- let's use the setter to have some side effect ----&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;isYoungAnimal.Setter = ((mi, val) =&amp;gt; { &lt;span class="kwrd"&gt;if&lt;/span&gt; (val) { mi.Properties[&lt;span class="str"&gt;&amp;quot;Age&amp;quot;&lt;/span&gt;].SetValue(10); } });&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;isYoungAnimal.SetValue(cat, &lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;&amp;quot;cat's age now {0}&amp;quot;&lt;/span&gt;, cat.Age);&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;
  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;Pay attention to what the Setter does now.&amp;#160; We create the method through which subsequent SetValue’s will be pushed.&amp;#160; Here’s that output:&lt;/p&gt;

  &lt;pre class="csharpcode"&gt;--&lt;span class="rem"&gt;-- let's use the setter to have some side effect ----&lt;/span&gt;
cat's age now 10&lt;/pre&gt;
  &lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

  &lt;p&gt;Finally, let’s show an example of how this can really function as some nice sugar to eliminate the need for a lot of value converters in WPF by using this capability as a way to store the relationship somewhere (rather than just using at a nice proxy to change a value):&lt;/p&gt;

  &lt;div class="csharpcode"&gt;
    &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="rem"&gt;// now, let's have a browesable one with a setter.&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="rem"&gt;// this plus dynamics are a mini &amp;quot;macro language&amp;quot; against the model items&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;List&amp;lt;Object&amp;gt; FavoriteAnimals = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt;();&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&lt;span class="rem"&gt;// we maintain state in FavoriteAnimals, and use the getter/setter func&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&lt;span class="rem"&gt;// in order to query or edit that collection.  Thus changes to an &amp;quot;instance&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;&lt;span class="rem"&gt;// are tracked elsewhere.&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt; isFavoriteAnimal = &lt;span class="kwrd"&gt;new&lt;/span&gt; AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;{&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    IsBrowsable = &lt;span class="kwrd"&gt;false&lt;/span&gt;,&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    Name = &lt;span class="str"&gt;&amp;quot;IsFavoriteAnimal&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    Getter = (mi =&amp;gt; FavoriteAnimals.Contains(mi)),&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    Setter = ((mi, val) =&amp;gt; &lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        {&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (val)&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;                FavoriteAnimals.Add(mi);&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;            &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            {&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;                FavoriteAnimals.Remove(mi);&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;            }&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;        })&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;};&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;aps.AddProperty(isFavoriteAnimal);&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;dog.IsFavoriteAnimal = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;&lt;span class="rem"&gt;// remove that cat that isn't there&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;cat.IsFavoriteAnimal = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;cat.IsFavoriteAnimal = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;cat.IsFavoriteAnimal = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Who are my favorite animal?&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;FavoriteAnimals.ForEach(o =&amp;gt; Console.WriteLine((o &lt;span class="kwrd"&gt;as&lt;/span&gt; ModelItem).Properties[&lt;span class="str"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;].ComputedValue.ToString()));&lt;/pre&gt;
  &lt;/div&gt;
  &lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

  &lt;p&gt;Little bit of code, let’s break it down one last time:&lt;/p&gt;
&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Line 14 – Create a setter that acts upon the FavoriteAnimals collection to either add or remove the element&lt;/li&gt;

  &lt;li&gt;Line 28-32 – do a few different sets on this attached property&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;NOTE: you can’t do that in beta2 as the dynamic support hasn’t been turned on.&amp;#160; Rather you would have to do isFavoriteAnimal.SetValue(dogMi, true).&lt;/li&gt;
  &lt;/ul&gt;

  &lt;li&gt;Line 35 then prints the output to the console, and as expected we only see the dog there:&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;-- Who are my favorite animals?&lt;/span&gt;
Sasha&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;I will attach the whole code file at the bottom of this post, but this shows you how you can use the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Attached properties to create “computed values” on top of existing types&lt;/li&gt;

  &lt;li&gt;Attached properties to inject a new (and discoverable) property entry on top of the designer data model (in the form of a new property)&lt;/li&gt;

  &lt;li&gt;Using the Setter capability to both propagate real changes to the type, providing a nice way to give a cleaner interface, as well as use it as a mechanism to store data about the object outside of the object, but in a way that gives me access to it such that it seems like the object.&amp;#160; &lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;This is some really nice syntactic sugar that we sprinkle on top of things&lt;/li&gt;
  &lt;/ul&gt;
&lt;/ul&gt;

&lt;h1&gt;What do I do now?&lt;/h1&gt;

&lt;p&gt;Hopefully this post gave you some ideas about how the attached property mechanisms work within the WF4 designer.&amp;#160; These give you a nice way to complement the data model and create nice bindable targets that your WPF Views can layer right on top of. &lt;/p&gt;

&lt;p&gt;A few ideas for these things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Use the Setters to clean up a “messy” activity API into a single property type that you then build a custom editor for in the property grid.&amp;#160; &lt;/li&gt;

  &lt;li&gt;Use the Getters (and the integration into the ModelProperty collection) in order to create computational properties that are used for displaying interesting information on the designer surface.&lt;/li&gt;

  &lt;li&gt;Figure out how to bridge the gap to take advantage of the XAML attached property storage mechanism, especially if you author runtime types that look for attached properties at runtime.&amp;#160; &lt;/li&gt;

  &lt;li&gt;Use these, with a combination of custom activity designers to extract and display interesting runtime data from a tracking store&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;Full Code Posting&lt;/h1&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Activities.Presentation;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Activities.Presentation.Model;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; AttachedPropertiesBlogPosting
{
    &lt;span class="kwrd"&gt;class&lt;/span&gt; Program
    {
        &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)
        {
            EditingContext ec = &lt;span class="kwrd"&gt;new&lt;/span&gt; EditingContext();
            ModelTreeManager mtm = &lt;span class="kwrd"&gt;new&lt;/span&gt; ModelTreeManager(ec);
            mtm.Load(&lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;[] { &lt;span class="kwrd"&gt;new&lt;/span&gt; Dog { Name = &lt;span class="str"&gt;&amp;quot;Sasha&amp;quot;&lt;/span&gt;, Noise = &lt;span class="str"&gt;&amp;quot;Snort&amp;quot;&lt;/span&gt;, Age = 5 },
                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; Cat { Name=&lt;span class="str"&gt;&amp;quot;higgs&amp;quot;&lt;/span&gt;, Noise=&lt;span class="str"&gt;&amp;quot;boom&amp;quot;&lt;/span&gt;, Age=1 } });
            dynamic root = mtm.Root;
            dynamic dog = root[0];
            dynamic cat = root[1];
            ModelItem dogMi = root[0] &lt;span class="kwrd"&gt;as&lt;/span&gt; ModelItem;
            ModelItem catMi = root[1] &lt;span class="kwrd"&gt;as&lt;/span&gt; ModelItem;
          
            &lt;span class="rem"&gt;// Add an attached Property&lt;/span&gt;
            AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt; ap = &lt;span class="kwrd"&gt;new&lt;/span&gt; AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt;
            {
                IsBrowsable = &lt;span class="kwrd"&gt;true&lt;/span&gt;,
                Name = &lt;span class="str"&gt;&amp;quot;IsAnInterestingDog&amp;quot;&lt;/span&gt;,
                Getter = (mi =&amp;gt; mi.Properties[&lt;span class="str"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;].ComputedValue.ToString() == &lt;span class="str"&gt;&amp;quot;Sasha&amp;quot;&lt;/span&gt;),
                OwnerType = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Dog)
            };
            ec.Services.Publish&amp;lt;AttachedPropertiesService&amp;gt;(&lt;span class="kwrd"&gt;new&lt;/span&gt; AttachedPropertiesService());
            AttachedPropertiesService aps = ec.Services.GetService&amp;lt;AttachedPropertiesService&amp;gt;();
            aps.AddProperty(ap);

            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;---- Enumerate properties on dog (note new property)----&amp;quot;&lt;/span&gt;);
            dogMi.Properties.ToList().ForEach(mp =&amp;gt; Console.WriteLine(&lt;span class="str"&gt;&amp;quot; Property : {0}&amp;quot;&lt;/span&gt;, mp.Name));

            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;---- Enumerate properties on cat (note  no new property) ----&amp;quot;&lt;/span&gt;);
            catMi.Properties.ToList().ForEach(mp =&amp;gt; Console.WriteLine(&lt;span class="str"&gt;&amp;quot; Property : {0}&amp;quot;&lt;/span&gt;, mp.Name));


            
            AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt; isYoungAnimal = &lt;span class="kwrd"&gt;new&lt;/span&gt; AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt;
            {
                IsBrowsable = &lt;span class="kwrd"&gt;false&lt;/span&gt;,
                Name = &lt;span class="str"&gt;&amp;quot;IsYoungAnimal&amp;quot;&lt;/span&gt;,
                Getter = (mi =&amp;gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;.Parse(mi.Properties[&lt;span class="str"&gt;&amp;quot;Age&amp;quot;&lt;/span&gt;].ComputedValue.ToString()) &amp;lt; 2)
            };

            aps.AddProperty(isYoungAnimal);

            &lt;span class="rem"&gt;// expect to not see isYoungAnimal show up&lt;/span&gt;
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;---- Enumerate properties on dog  (note isYoungAnimal doesn't appear )----&amp;quot;&lt;/span&gt;);
            dogMi.Properties.ToList().ForEach(mp =&amp;gt; Console.WriteLine(&lt;span class="str"&gt;&amp;quot; Property : {0}&amp;quot;&lt;/span&gt;, mp.Name));
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;---- Enumerate properties on cat (note isYoungAnimal doesn't appear )----&amp;quot;&lt;/span&gt;);
            catMi.Properties.ToList().ForEach(mp =&amp;gt; Console.WriteLine(&lt;span class="str"&gt;&amp;quot; Property : {0}&amp;quot;&lt;/span&gt;, mp.Name));

            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;---- get attached property via GetValue ----&amp;quot;&lt;/span&gt;);
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;getting non browsable attached property on dog {0}&amp;quot;&lt;/span&gt;, isYoungAnimal.GetValue(dogMi));
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;getting non browsable attached property on cat {0}&amp;quot;&lt;/span&gt;, isYoungAnimal.GetValue(catMi));
            
            
            &lt;span class="rem"&gt;// now, let's do something clever with the setter. &lt;/span&gt;
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;---- let's use the setter to have some side effect ----&amp;quot;&lt;/span&gt;);
            isYoungAnimal.Setter = ((mi, val) =&amp;gt; { &lt;span class="kwrd"&gt;if&lt;/span&gt; (val) { mi.Properties[&lt;span class="str"&gt;&amp;quot;Age&amp;quot;&lt;/span&gt;].SetValue(10); } });
            isYoungAnimal.SetValue(cat, &lt;span class="kwrd"&gt;true&lt;/span&gt;);
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;cat's age now {0}&amp;quot;&lt;/span&gt;, cat.Age);

            &lt;span class="rem"&gt;// now, let's have a browesable one with a setter.&lt;/span&gt;
            &lt;span class="rem"&gt;// this plus dynamics are a mini &amp;quot;macro language&amp;quot; against the model items&lt;/span&gt;

            List&amp;lt;Object&amp;gt; FavoriteAnimals = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt;();

            &lt;span class="rem"&gt;// we maintain state in FavoriteAnimals, and use the getter/setter func&lt;/span&gt;
            &lt;span class="rem"&gt;// in order to query or edit that collection.  Thus changes to an &amp;quot;instance&amp;quot;&lt;/span&gt;
            &lt;span class="rem"&gt;// are tracked elsewhere.&lt;/span&gt;
            AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt; isFavoriteAnimal = &lt;span class="kwrd"&gt;new&lt;/span&gt; AttachedProperty&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt;
            {
                IsBrowsable = &lt;span class="kwrd"&gt;false&lt;/span&gt;,
                Name = &lt;span class="str"&gt;&amp;quot;IsFavoriteAnimal&amp;quot;&lt;/span&gt;,
                Getter = (mi =&amp;gt; FavoriteAnimals.Contains(mi)),
                Setter = ((mi, val) =&amp;gt; 
                    {
                        &lt;span class="kwrd"&gt;if&lt;/span&gt; (val)
                            FavoriteAnimals.Add(mi);
                        &lt;span class="kwrd"&gt;else&lt;/span&gt;
                        {
                            FavoriteAnimals.Remove(mi);
                        }
                    })
            };
            aps.AddProperty(isFavoriteAnimal);
            dog.IsFavoriteAnimal = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            &lt;span class="rem"&gt;// remove that cat that isn't there&lt;/span&gt;
            cat.IsFavoriteAnimal = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            cat.IsFavoriteAnimal = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            cat.IsFavoriteAnimal = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Who are my favorite animals?&amp;quot;&lt;/span&gt;);
            FavoriteAnimals.ForEach(o =&amp;gt; Console.WriteLine((o &lt;span class="kwrd"&gt;as&lt;/span&gt; ModelItem).Properties[&lt;span class="str"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;].ComputedValue.ToString()));
            Console.ReadLine();
        }
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Dog
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name { get; set; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Noise { get; set; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Age { get; set; }
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Cat
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name { get; set; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Noise { get; set; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Age { get; set; }
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9933077" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/designer/">designer</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/wf4/">wf4</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/vs2010/">vs2010</category></item><item><title>WF4 ViewStateService</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/12/06/wf4-viewstateservice.aspx</link><pubDate>Sun, 06 Dec 2009 01:33:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9933058</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9933058</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/12/06/wf4-viewstateservice.aspx#comments</comments><description>&lt;p&gt;A comment posted by Notre asked for some more details about view state and attached property services, so I thought I would dive into those next.&amp;#160; I will follow-up in a subsequent post on the AttachedPropertyService, as there is a little bit more going on there.&lt;/p&gt;  &lt;h1&gt;Motivation&lt;/h1&gt;  &lt;p&gt;Why do I care about viewstate?&amp;#160; Well, usually it is because we want to write something down and store it for later that is not required for runtime.&amp;#160; A common example of viewstate is the position of nodes within a flowchart.&amp;#160; While not required to execute the flowchart, they are required to effectively view the flowchart.&amp;#160; &lt;/p&gt;  &lt;h1&gt;Where to write them down?&lt;/h1&gt;  &lt;p&gt;This was a question that caused a fair amount of debate on the team.&amp;#160; There are basically two places to write down things like view state in a file-based world.&amp;#160; &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;In the source document itself&lt;/li&gt;    &lt;li&gt;In a document that stays close to the source (usually referred to as a sidecar file)&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;We had customers asking for both.&amp;#160; The motivation for the first is that for things like flowchart, where I may always care about the visualization representation, I want to keep that metadata around and only deal with one element.&amp;#160; For the second, it is motivated by the reason that we want a clean source document that only describes the minimal artifact to run.&amp;#160; Now, there are certainly many stops along the spectrum (for instance, we might always want to keep annotations or source comments in the source document, and put positioning elsewhere).&amp;#160; For VS2010, we landed with a unified API to use, and we write in the source document.&amp;#160; This is something that is likely to change in future releases, as it does make things like textual diffs rather painful. &lt;/p&gt;  &lt;p&gt;So, that’s why we want to use it.&lt;/p&gt;  &lt;h1&gt;How do we use it?&lt;/h1&gt;  &lt;p&gt;We are going to create a simple activity designer that lets me write down a comment.&lt;/p&gt;  &lt;p&gt;A few simple steps:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Create a new VS Project, let’s create an Activity Library&lt;/li&gt;    &lt;li&gt;Add a Designer to that activity library &lt;/li&gt;    &lt;li&gt;Add an attribute to the activity pointing to the designer&lt;/li&gt;    &lt;li&gt;Add a new WorkflowConsoleApp Project&lt;/li&gt;    &lt;li&gt;Build&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/WF4WorkflowViewStateServiceandAttachedPr_13D08/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/WF4WorkflowViewStateServiceandAttachedPr_13D08/image_thumb_2.png" width="256" height="421" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now, let’s go and make our activity designer a little interesting.&lt;/p&gt;  &lt;p&gt;Let’s add a text box and a button.&amp;#160; We’ll make the text of the button something obvious like “commit comment” The XAML for the activity designer looks like this:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sap:ActivityDesigner&lt;/span&gt; &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;simpleActivity.CommentingDesigner&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:sap&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation&amp;quot;&lt;/span&gt;
    &lt;span class="attr"&gt;xmlns:sapv&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Grid&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;stackPanel1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;VerticalAlignment&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Top&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBox&lt;/span&gt;  &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;commentBlock&amp;quot;&lt;/span&gt;   &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Button&lt;/span&gt; &lt;span class="attr"&gt;Content&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Load View State&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;loadViewState&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Click&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;loadViewState_Click&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Button&lt;/span&gt; &lt;span class="attr"&gt;Content&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Commit View State&amp;quot;&lt;/span&gt;  &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;button1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Click&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;button1_Click&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Grid&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;sap:ActivityDesigner&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Now, let’s add some code to the button (and to the initialization of the form) &lt;/p&gt;

&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.view.viewstateservice_members(VS.100).aspx"&gt;ViewStateService&lt;/a&gt; has a few useful methods on it.&amp;#160; I want to call out a subtle difference.&amp;#160; You will see &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.view.viewstateservice.storeviewstate(VS.100).aspx"&gt;StoreViewState&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.view.viewstateservice.storeviewstatewithundo(VS.100).aspx"&gt;StoreViewStateWithUndo&lt;/a&gt;.&amp;#160; The primary distinction as the name implies is that one will simply write the view state down and will bypass the undo/redo stack.&amp;#160; This is for view state like an expanded/collapsed view.&amp;#160; You don’t really want ctl-z to simply flip expanded versus collapsed for you.&amp;#160; But for something like flowchart, where changing some of the viewstate, like position, might be such a thing that you want support for undoing the action.&amp;#160; That’s the primary difference.&lt;/p&gt;

&lt;p&gt;So, our code for the button looks like this:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; button1_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)
{
    ViewStateService vss = &lt;span class="kwrd"&gt;this&lt;/span&gt;.Context.Services.GetService&amp;lt;ViewStateService&amp;gt;();
    vss.StoreViewStateWithUndo(&lt;span class="kwrd"&gt;this&lt;/span&gt;.ModelItem, &lt;span class="str"&gt;&amp;quot;comment&amp;quot;&lt;/span&gt;, commentBlock.Text);
}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Now, on load, we want to be able to populate the value, so we will use the &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.view.viewstateservice.retrieveviewstate(VS.100).aspx"&gt;RetrieveViewState&lt;/a&gt; method in order to extract this.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; loadViewState_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)
{
    ViewStateService vss = &lt;span class="kwrd"&gt;this&lt;/span&gt;.Context.Services.GetService&amp;lt;ViewStateService&amp;gt;();
    commentBlock.Text = vss.RetrieveViewState(&lt;span class="kwrd"&gt;this&lt;/span&gt;.ModelItem, &lt;span class="str"&gt;&amp;quot;comment&amp;quot;&lt;/span&gt;) &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Now, let’s go back to our workflow project and put an instance of this activity on the surface: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/WF4WorkflowViewStateServiceandAttachedPr_13D08/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/WF4WorkflowViewStateServiceandAttachedPr_13D08/image_thumb.png" width="242" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Let’s add some viewstate information and commit it.&amp;#160; Now let’s look at the XAML:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;s4:NotRealInterestingActivity&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{x:Null}&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;sap:VirtualizedContainerService&lt;/span&gt;.&lt;span class="attr"&gt;HintSize&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;200,99&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sap:WorkflowViewStateService.ViewState&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;scg3:Dictionary&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String, x:Object&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;x:String&lt;/span&gt; &lt;span class="attr"&gt;x:Key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;comment&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;basic comment&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;x:String&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;scg3:Dictionary&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;sap:WorkflowViewStateService.ViewState&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;s4:NotRealInterestingActivity&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Ok, now, to show that we can pull this in, let’s change the text in the xaml and then reload our designer. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/WF4WorkflowViewStateServiceandAttachedPr_13D08/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/WF4WorkflowViewStateServiceandAttachedPr_13D08/image_thumb_1.png" width="244" height="224" /&gt;&lt;/a&gt;&amp;#160; &lt;/p&gt;

&lt;p&gt;You can muck around with ctl-z to see that this does get handled correctly via the undo.&amp;#160; &lt;/p&gt;

&lt;p&gt;The other important thing to note is that this takes an object, so your viewstate is not limited to strings, you can have more full featured objects if you’d like. Finally, the ViewStateService also has a &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.view.viewstateservice.viewstatechanged(VS.100).aspx"&gt;ViewStateChanged&lt;/a&gt; you can subscribe to in order to handle, dispatch, and react to view state changes in the designer. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9933058" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/designer/">designer</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/wf4/">wf4</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/beta/">beta</category></item><item><title>Where is System.Activities.Design in WF4 Beta2 and Beyond?</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/12/05/where-is-system-activities-design-in-wf4-beta2-and-beyond.aspx</link><pubDate>Sat, 05 Dec 2009 23:40:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9933046</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9933046</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/12/05/where-is-system-activities-design-in-wf4-beta2-and-beyond.aspx#comments</comments><description>&lt;p&gt;I got an email over the weekend asking about this, and I realized that it’s somewhat buried in this post &lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/10/20/wf4-designer-enhancements-in-vs-2010-beta-2.aspx"&gt;here&lt;/a&gt;.&amp;#160; Anyway, in Beta1, you often saw System.Activities.Design.&amp;#160; For beta2 (and RTM), one important change&lt;/p&gt;  &lt;h3&gt;System.Activities.Design&amp;#160; =&amp;gt; System.Activities.Presentation&lt;/h3&gt;  &lt;p&gt;The primary reason for this change is that the *.Design suffix is generally reserved for VS design extensibility.&amp;#160; As our designer ships in the framework, *.Design was not the correct suffix.&amp;#160; *.Presentation is where we landed.&amp;#160; &lt;/p&gt;  &lt;p&gt;Hoping that putting this in the title lands this high up in search queries so that this post might be useful for a few people.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9933046" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/wf4/">wf4</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/beta/">beta</category></item><item><title>WF4, WCF and AppFabric Sessions @ PDC09</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/11/23/wf4-wcf-and-appfabric-pdc09.aspx</link><pubDate>Mon, 23 Nov 2009 23:16:44 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9927614</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9927614</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/11/23/wf4-wcf-and-appfabric-pdc09.aspx#comments</comments><description>&lt;p&gt;I’m taking this week off to catch up on everything I haven’t done the last two months and to celebrate the &lt;a href="http://en.wikipedia.org/wiki/Thanksgiving"&gt;Thanksgiving holiday&lt;/a&gt; here in the US. &lt;/p&gt;  &lt;p&gt;PDC was a blast!&amp;#160; It was incredibly awesome to meet so many folks interested in WF and talking with others about how they are using (or plan to use) WF4.&amp;#160; I’ll be following up with a more detailed post on my talk, including demos and code, but I wanted to give a summary of the talks that came from my team at this PDC.&amp;#160; Below is the diagram that breaks down some of the “capabilities” of AppFabric and I have color coded them for the various talks that we gave.&amp;#160; All of the PDC Sessions are available online &lt;a href="http://microsoftpdc.com/Videos"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/WF4WCFandAppFabricPDC09_D6DC/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/WF4WCFandAppFabricPDC09_D6DC/image_thumb.png" width="592" height="309" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h2&gt;WF Talks&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/FT17"&gt;Spice Up Your Applications with Windows Workflow Foundation 4&lt;/a&gt; – Matt Winkler&lt;/li&gt;    &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/P09-22"&gt;Windows Workflow Foundation 4 from the Inside Out&lt;/a&gt; – Bob Schmidt&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;WCF Talks&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/FT13"&gt;What’s New for Windows Communication Foundation 4&lt;/a&gt; – Ed Pinto&lt;/li&gt;    &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/FT55"&gt;Developing REST Applications with the .NET Framework&lt;/a&gt; – Henrik Nielsen &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;AppFabric Talks&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/FT25"&gt;Microsoft Application Server Technologies: Present and Future&lt;/a&gt; – Anil Nori &lt;/li&gt;    &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVR15"&gt;Microsoft BizTalk Server Futures and Roadmap&lt;/a&gt; –&amp;#160; Balasubramanian Sriram &lt;/li&gt;    &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/FT14"&gt;Workflow Services and Windows Server AppFabric&lt;/a&gt; – Mark Fussell&lt;/li&gt;    &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/FT27"&gt;Application Server Extensibility with Microsoft .NET 4 and Windows Server AppFabric&lt;/a&gt; – Nicholas Allen&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There’s a ton of great content up at the PDC site, plenty to sit back and enjoy!&amp;#160; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9927614" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/WCF/">WCF</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/wf4/">wf4</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/pdc09/">pdc09</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/AppFabric/">AppFabric</category></item><item><title>A Few Additional Treats @ PDC09</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/11/13/a-few-additional-treats-pdc09.aspx</link><pubDate>Fri, 13 Nov 2009 21:15:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9922220</guid><dc:creator>Matt Winkler -- MSFT</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9922220</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/11/13/a-few-additional-treats-pdc09.aspx#comments</comments><description>&lt;p&gt;One fun thing we will be doing this year is using the theater in our lounge/booth area to have a few chalk style presentations.&amp;#160; These will be brief 30 minute demo/ q&amp;amp;a / conversation sessions with somebody from the product team.&amp;#160; These will dive a little deeper and be more interactive about topics we know you’re interested in.&amp;#160; We’d love you to come and just ask a ton of questions here:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;Thursday, 11:00-11:30 / &lt;/b&gt;&lt;b&gt;Future Directions for State Machine Workflows&amp;#160; / &lt;/b&gt;&lt;b&gt;Alan Ko&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;Discuss options for using the State Machine modeling style on WF4, and see a demonstration of a WF4-based State Machine design experience. &lt;/p&gt;    &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;&lt;b&gt;Thursday, 1-1:30 / &lt;/b&gt;&lt;b&gt;Migrating WF 3.5 Workflows to WF 4 / &lt;/b&gt;&lt;b&gt;Bob Schmidt&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;Learn some tips and techniques for migrating your WF 3.5 workflows to the new WF4 runtime, and see a demonstration of a tool that helps automate this process.&lt;/p&gt;    &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;&lt;b&gt;Thursday, 2:00-2:30 / &lt;/b&gt;&lt;b&gt;WF Rehosting Deep Dive / &lt;/b&gt;&lt;b&gt;Kushal Shah&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;See how WF’s rehostable runtime, designer, and debugger can add powerful capabilities to your applications&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;I’m excited because we’re going to use this as an opportunity to show some cool stuff that we’re thinking about.&amp;#160; Usual disclaimers apply, &lt;strong&gt;some of the stuff here we will show are prototypes, ideas we are looking for feedback,&lt;/strong&gt; etc, etc.&amp;#160;&amp;#160; These are things that we think are important, and your feedback helps us understand what you really need to make these things useful for you&lt;/p&gt;  &lt;p&gt;Stop on by the booth if you’re interested in any of the above topics!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9922220" width="1" height="1"&gt;</description></item></channel></rss>