<?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>Matt W's Windows Workflow Place</title><link>http://blogs.msdn.com/b/mwinkle/</link><description /><dc:language>en-US</dc:language><generator>Telligent Community 5.6.583.21163 (Build: 5.6.583.21163)</generator><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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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>mwinkle</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><item><title>Matt’s PDC Session List</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/11/12/matt-s-pdc-session-list.aspx</link><pubDate>Thu, 12 Nov 2009 05:48:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9921191</guid><dc:creator>mwinkle</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9921191</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/11/12/matt-s-pdc-session-list.aspx#comments</comments><description>&lt;p&gt;I’m hoping that this PDC might be a little different and I may actually get to attend some sessions, rather than just prepping for &lt;a href="http://microsoftpdc.com/Sessions/FT17"&gt;mine&lt;/a&gt; (or &lt;a href="http://microsoftpdc.com/Sessions/FT25"&gt;the&lt;/a&gt; &lt;a href="http://microsoftpdc.com/Sessions/SVR15"&gt;others&lt;/a&gt; &lt;a href="http://microsoftpdc.com/Sessions/FT14"&gt;from&lt;/a&gt; &lt;a href="http://microsoftpdc.com/Sessions/P09-22"&gt;my&lt;/a&gt; &lt;a href="http://microsoftpdc.com/Sessions/FT13"&gt;team&lt;/a&gt;).&amp;#160; I’ve gone through all 22 pages of published talks, and I think there are some interesting ones.&amp;#160; So, without further ado, and with little, if any regard for actual scheduling of talks in relation to mine, here are the talks I would be interested in going to at PDC09.&lt;/p&gt;  &lt;p&gt;Hopefully I can get to 10 of them. &lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width="407"&gt;         &lt;h2&gt;Session Name&lt;/h2&gt;       &lt;/td&gt;        &lt;td width="604"&gt;         &lt;h2&gt;Comment&lt;/h2&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;&lt;a href="http://microsoftpdc.com/Sessions/FT50"&gt;Building Data-Driven Applications Using Microsoft Project Code Name &amp;quot;Quadrant&amp;quot; and Microsoft Project Code Name &amp;quot;M&amp;quot;&lt;/a&gt;&lt;/td&gt;        &lt;td width="604"&gt;&lt;a href="http://www.douglaspurdy.com/"&gt;Doug’s&lt;/a&gt; had a few things to say recently, and I think this talk will be interesting.&amp;#160; My team was part of the Quadrant team for a while, and I’m curious to see what they’ve been up to.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/P09-20"&gt;Windows 7 and Windows Server 2008 R2 Kernel Changes&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;Anytime that you get to hear Mark talk about the kernel, it’s a great opportunity to learn a lot about a topic we don’t think every day.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/FT08"&gt;Code Visualization, UML, and DSLs&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;The architecture tools team has done some really, really neat stuff to help you understand your code base better. I've found the tools to be really useful when looking at our code base, and I'd like to learn more here.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVR08"&gt;Advanced Microsoft SQL Server 2008 R2 StreamInsight&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;I've been watching StreamInsight since there was an internal talk on the technology. The capabilities here to do high capacity event stream queries is amazing. I think there are a number of interesting classes of problems where this can be useful and I'd like to find out more&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVR07"&gt;Introduction to Microsoft SQL Server 2008 R2 StreamInsight&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;&amp;#160;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/FT31"&gt;Dynamic Binding in C# 4&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;This feature is one that I was excited to hear about in Anders' talk last year. A whole hour on how this works, that's just bliss&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/CL33"&gt;Windows Error Reporting&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;         &lt;p&gt;This kind of data is gold for folks who are building software.&amp;#160; You can’t catch every bug, or be aware of a video card incompatibility in a certain language on XP SP2, or always know why things might go wrong in your apps.&amp;#160; WER gives you a way to get that kind of data. &lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/CL09"&gt;How Microsoft Visual Studio 2010 Was Built with Windows Presentation Foundation 4&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;This has been a huge undertaking, and hearing Paul talk about this will be insightful about the challenges faced, the way to integrate large, existing code bases with WPF, native WPF interop, etc.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/CL10"&gt;Windows Presentation Foundation 4 Plumbing and Internals&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;         &lt;p&gt;I have a weak spot for deepdives into plumbing like this talk. This kind of knowledge is so useful for building apps on top of WPF to really understand how the pieces work together and what's happening at the low levels&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/FT51"&gt;Future of Garbage Collection&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;I got to sit next to Patrick at a dinner and had an amazing convesation that knocked my socks off. This is one of the guys who built the GC in .NET, and hearing the way he thinks will be interesting.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/FT52"&gt;Microsoft Perspectives on the Future of Programming&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;Look at the list of this panel, how could you not want to hear this conversation? Just getting these folks together means there will be some interesting topics with lots of different backgrounds (from Jeffery Snover to Erik Meijer)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVC19"&gt;REST Services Security Using the Access Control Service&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;Justin is my former partner in crime from our days as technical evangelists, and I have lunch with him regularly and the stuff that he is working with is wicked cool. He's also one of the best presenters in the company, and there is always something I learn about presenting when I watch him talk.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVR17"&gt;Data-Intensive Computing on Windows HPC Server with the DryadLINQ Framework&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;I'd love to see anything that talks about &amp;quot;familiar declarative syntax of LINQ combined with the fault-tolerant distributed graph scheduling of the Dryad runtime&amp;quot;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/CL17"&gt;Building Sensor- and Location-Aware Applications with Windows 7 and the Microsoft .NET Framework 4.0&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;The location API made me open up my first C++ project in a long time, the range of scenarios that this enables in Win7 is awesome&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/VTL01"&gt;Code Contracts and Pex: Power Charge Your Assertions and Unit Tests&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;My first &amp;quot;from the labs&amp;quot; talk on the list, Pex and Code Contracts bring some really compelling capabilities to .NET development. This would be great to see.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/FT25"&gt;Microsoft Application Server Technologies: Present and Future&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;This is from my team, and I'm excited to see the reaction to some of the cool stuff we will be talking about in the App Server space&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/VTL04"&gt;Rx: Reactive Extensions for .NET&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;Erik Meijer is one of those guys I can't get enough of, I'd sign up for the fan club on channel9 if it were available.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/CL21"&gt;Building Amazing Business Applications with Microsoft Silverlight and Microsoft .NET RIA Services&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;Brad is a really great presenter, and this is a whole space I have not had a chance to pay much attention to. I'd love to learn more about the ways to rapidly create business applications.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/CL23"&gt;SketchFlow: Prototyping to the Rescue&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;Having just finished a project with a lot of designer/developer interaction, I have a lot of hope for things like SketchFlow.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td width="407"&gt;         &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/FT55"&gt;Developing REST Applications with the .NET Framework&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td width="604"&gt;I like watching Don's talks, and REST is kind of a thing these days. Done deal.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9921191" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/pdc09/">pdc09</category></item><item><title>Displaying Validation Errors in a Rehosted WF4 Designer</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/11/06/displaying-validation-errors-in-a-rehosted-wf4-designer.aspx</link><pubDate>Fri, 06 Nov 2009 18:55:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9918740</guid><dc:creator>mwinkle</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9918740</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/11/06/displaying-validation-errors-in-a-rehosted-wf4-designer.aspx#comments</comments><description>&lt;p&gt;Here’s a quick one&lt;/p&gt;  &lt;h2&gt;“I’d like to find out if the workflow in the designer is valid… is there someway to retrieve the validation errors?”&lt;/h2&gt;  &lt;p&gt;Yes, the short answer is that you need to provide an implementation &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.validation.ivalidationerrorservice%28VS.100%29.aspx"&gt;IValidationErrorService&lt;/a&gt;.&amp;#160; There is one important method to implement on this interface, &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.validation.ivalidationerrorservice.showvalidationerrors%28VS.100%29.aspx"&gt;ShowValidationErrors&lt;/a&gt; which will pass you a list of &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.validation.validationerrorinfo%28VS.100%29.aspx"&gt;ValidationErrorInfo&lt;/a&gt; objects.&lt;/p&gt;  &lt;p&gt;The next thing that needs to happen is that you need to publish an instance of that new type to the editing context. &lt;/p&gt;  &lt;p&gt;Let’s look at a really simple implementation that will write out the validation errors to the debug log.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Activities.Presentation.Validation;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;
&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;namespace&lt;/span&gt; VariableFinderShell
{
    &lt;span class="kwrd"&gt;class&lt;/span&gt; DebugValidationErrorService : IValidationErrorService
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ShowValidationErrors(IList&amp;lt;ValidationErrorInfo&amp;gt; errors)
        {
            errors.ToList().ForEach(vei =&amp;gt; Debug.WriteLine(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;&amp;quot;Error: {0} &amp;quot;&lt;/span&gt;, vei.Message)));
        }
    }
}&lt;/pre&gt;

&lt;p&gt;The final bit is to publish this to the editing context:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;wd.Context.Services.Publish&amp;lt;IValidationErrorService&amp;gt;(&lt;span class="kwrd"&gt;new&lt;/span&gt; DebugValidationErrorService());&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, when editing the workflow in the rehosted app, let’s introduce some errors and then look at the output window.&amp;#160; Note, most of the errors below come from incorrect expressions introduced in the expression editor (putting integers in the wrong place, wrong variable name, etc). &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DisplayingValidationErrorsinaRehostedWF4_9585/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/DisplayingValidationErrorsinaRehostedWF4_9585/image_thumb.png" width="604" height="303" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9918740" width="1" height="1"&gt;</description></item><item><title>Got a cool .NET app? Hang with Tortoises for 12 days</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/11/06/got-a-cool-net-app-hang-with-tortoises-for-12-days.aspx</link><pubDate>Fri, 06 Nov 2009 17:15:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9918679</guid><dc:creator>mwinkle</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9918679</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/11/06/got-a-cool-net-app-hang-with-tortoises-for-12-days.aspx#comments</comments><description>&lt;p&gt;&lt;em&gt;&lt;a href="http://www.flickr.com/photos/mikeweston/333093049/sizes/l/"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="tortoise" border="0" alt="tortoise" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/Gotacoo.NETappHangwithTortoisesfor12days_B138/tortoise_3.jpg" width="327" height="254" /&gt;&lt;/a&gt; &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;photo courtesy of flickr user &lt;a href="http://www.flickr.com/photos/mikeweston/"&gt;mikeweston&lt;/a&gt;&amp;#160;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;This is a something that the .NET team is putting together that has a &lt;a href="http://www.mydotnetstory.com/submit.aspx"&gt;contest&lt;/a&gt; with super cool prizes (seriously, 12 day trip to the Galapagos, for real (as my 4 year old says)).&amp;#160; (obligatory legalese &lt;a href="http://mydotnetstory.com/rules.aspx"&gt;here&lt;/a&gt;). If you’ve built a sweet app with the .NET framework, we’d like to hear about it.&amp;#160;&amp;#160; So check out &lt;a href="http://www.myDotNetStory.com"&gt;http://www.myDotNetStory.com&lt;/a&gt; today and enter to win.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9918679" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/Microsoft/">Microsoft</category></item><item><title>Finding the Variables in Scope Within the WF Designer</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/11/06/finding-the-variables-in-scope-within-the-wf-designer.aspx</link><pubDate>Fri, 06 Nov 2009 06:21:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9918399</guid><dc:creator>mwinkle</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9918399</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/11/06/finding-the-variables-in-scope-within-the-wf-designer.aspx#comments</comments><description>&lt;p&gt;In this &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/wfprerelease/thread/53c91c81-02cf-4eab-b43f-c3d73a03c501"&gt;thread&lt;/a&gt;, one of our forum customers asked the question:&lt;/p&gt;  &lt;h2&gt;“how do I find all of the variables that are in scope for a given activity in the designer?”&lt;/h2&gt;  &lt;p&gt;We do not have a public API to do this.&amp;#160; Internally we have a helper type called VariableHelper that we use to display the list of variables in the variable designer, as well as passed into the expression text box intellisense control. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/FindingtheVariablesinScopeWithintheWFDes_13A44/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/FindingtheVariablesinScopeWithintheWFDes_13A44/image_thumb.png" width="603" height="280" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/FindingtheVariablesinScopeWithintheWFDes_13A44/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/FindingtheVariablesinScopeWithintheWFDes_13A44/image_thumb_1.png" width="319" height="235" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;One thing that I would like to point out is that if you are implementing your expression editor and want to be able to enumerate the variables (to highlight the tokens that are in scope), your implementation of &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.view.iexpressioneditorservice.createexpressioneditor(VS.100).aspx"&gt;IExpressionEditorService.CreateExpressionEditor&lt;/a&gt;() will get a list of model items that correspond to the inscope variables.&amp;#160; &lt;/p&gt;  &lt;p&gt;Now, if you are not building an expression editor, and want to be able to enumerate all of the in scope variables, you will need to do a little more work.&amp;#160; Here are the basic steps&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Go to parent container&lt;/li&gt;    &lt;li&gt;Does it contain variables*&lt;/li&gt;    &lt;li&gt;Does it have a parent?&lt;/li&gt;    &lt;li&gt;Go to parent’s parent&lt;/li&gt;    &lt;li&gt;Repeat from step 2&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;* This is basically the tricky part, because it is not something we can cleanly determine (and it can also be altered at runtime by adding some additional ones via the CacheMetadata() method.&amp;#160; I’ll describe what the designer is currently doing to accumulate this list, and then talk about designs we could have in a future release. &lt;/p&gt;  &lt;h2&gt;Current Approach&lt;/h2&gt;  &lt;p&gt;Currently, there are two things that we look for when we navigate up the model item tree.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Collections of Variables name Variables&lt;/li&gt;    &lt;li&gt;Variables injected by the use of ActivityAction&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;As we walk up the tree, we need to find these.&amp;#160; Let’s first consider the following workflow we will use for our tests:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;wd.Load(&lt;span class="kwrd"&gt;new&lt;/span&gt; Sequence&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    Activities =&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        &lt;span class="kwrd"&gt;new&lt;/span&gt; Sequence&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;            Activities = &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;                &lt;span class="kwrd"&gt;new&lt;/span&gt; ForEach&amp;lt;&lt;span class="kwrd"&gt;string&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 class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;                    Body = &lt;span class="kwrd"&gt;new&lt;/span&gt; ActivityAction&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;                    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;                         Argument = &lt;span class="kwrd"&gt;new&lt;/span&gt; DelegateInArgument&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; { Name=&lt;span class="str"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt; },&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;                         Handler = &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;                            &lt;span class="kwrd"&gt;new&lt;/span&gt; Sequence&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;                            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;                                Activities = &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;                                {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; WriteLine()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;                                }&lt;/pre&gt;

  &lt;pre class="alt"&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 class="alt"&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;            }&lt;/pre&gt;

  &lt;pre class="alt"&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;    }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;});&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Line 13 is the only one that might look a little different here, I’ll eventually have a post up about &lt;a href="http://msdn.microsoft.com/en-us/library/dd485397(VS.100).aspx"&gt;ActivityAction&lt;/a&gt; that talks in more detail what’s going on there.&lt;/p&gt;

&lt;p&gt;So, this loaded in a rehosted designer looks like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/FindingtheVariablesinScopeWithintheWFDes_13A44/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/FindingtheVariablesinScopeWithintheWFDes_13A44/image_thumb_2.png" width="234" height="373" /&gt;&lt;/a&gt;&amp;#160;&amp;#160; &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;Now, let’s look at the code to figure out what is in scope of the selected element.&amp;#160; First, let’s get the selected element :-) &lt;/p&gt;

&lt;pre class="csharpcode"&gt; Selection  sel = wd.Context.Items.GetValue&amp;lt;Selection&amp;gt;();
 &lt;span class="kwrd"&gt;if&lt;/span&gt; (sel != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
 {
        ModelItem mi = sel.PrimarySelection;&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;mi is now the model item of my selected item.&amp;#160; Let’s write some code to walk up the tree and add to a collection called variables&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;while&lt;/span&gt; (mi.Parent != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    Type parentType = mi.Parent.ItemType;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Activity).IsAssignableFrom(parentType))&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        &lt;span class="rem"&gt;// we have encountered an activity derived type&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        &lt;span class="rem"&gt;// look for variable collection&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        ModelProperty mp = mi.Parent.Properties[&lt;span class="str"&gt;&amp;quot;Variables&amp;quot;&lt;/span&gt;];&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != mp &amp;amp;&amp;amp; mp.PropertyType == &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Collection&amp;lt;Variable&amp;gt;))&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;            mp.Collection.ToList().ForEach(item =&amp;gt; variables.Add(item));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    &lt;span class="rem"&gt;// now we need to look action handlers &lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    &lt;span class="rem"&gt;// this will ideally return a bunch of DelegateArguments&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    var dels = mi.Properties.Where(p =&amp;gt; &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(ActivityDelegate).IsAssignableFrom(p.PropertyType));&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var actdel &lt;span class="kwrd"&gt;in&lt;/span&gt; dels)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (actdel.Value != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var innerProp &lt;span class="kwrd"&gt;in&lt;/span&gt; actdel.Value.Properties)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;            {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(DelegateArgument).IsAssignableFrom(innerProp.PropertyType) &amp;amp;&amp;amp; &lt;span class="kwrd"&gt;null&lt;/span&gt; != innerProp.Value)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;                {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;                    variables.Add(innerProp.Value);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;                }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;    mi = mi.Parent;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&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;Lines 4-13 handle the case where I just encounter an activity.&amp;#160; Lines 16-29 handle the slightly more tricky case where I need to handle ActivityAction (which ultimately derives from ActivityDelegate).&amp;#160; There are a few loops there but basically I look through all of the properties of the item which inherit from ActivityDelegate.&amp;#160; For each one of those, and for each property on that, I look for properties assignable from &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.delegateargument(VS.100).aspx"&gt;DelegateArgument&lt;/a&gt;.&amp;#160; As I find them I add them to my collection of model items for variables.&amp;#160; &lt;/p&gt;

&lt;p&gt;In my WPF app, I have a simple list box that shows all of these.&amp;#160; Because of the loosely typed data template I use in my WPF app, I get a pretty decent display since they share common things like &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelitem.itemtype(VS.100).aspx"&gt;ItemType&lt;/a&gt; from ModelItem, and a &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelitem.name(VS.100).aspx"&gt;Name&lt;/a&gt; that routes through to the underlying Name property both elements share. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/FindingtheVariablesinScopeWithintheWFDes_13A44/image_8.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/FindingtheVariablesinScopeWithintheWFDes_13A44/image_thumb_3.png" width="438" height="116" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&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;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;listBox1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Grid&lt;/span&gt;.&lt;span class="attr"&gt;Row&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Grid&lt;/span&gt;.&lt;span class="attr"&gt;ColumnSpan&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Grid&lt;/span&gt;.&lt;span class="attr"&gt;Column&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ListBox.ItemTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DataTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&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;Orientation&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Horizontal&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Foo:&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt; &lt;span class="attr"&gt;FontWeight&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Bold&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding Path=ItemType}&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding Path=Name}&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&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;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;DataTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ListBox.ItemTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ListBox&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&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;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Potential Future Approach&lt;/h2&gt;

&lt;p&gt;Our approach outlined above is generally correct.&amp;#160; That said, you can imagine a deeply nested data structure on an activity that contain variables that get injected into the scope at runtime.&amp;#160; We need a way for an activity to provide a way to declare how to get all of its variables.&amp;#160; The current approach is one of inspection, which works for all of our activities. In the future we may need to add an extensibility point to allow an activity author to specify how to find the variables that are available to its children.&amp;#160; The way that we could do that is to introduce an “VariableResolver” attribute which points to a type (or maybe a Func&amp;lt;&amp;gt;) that operates on the activity and returns the list of variables.&amp;#160; Actually today you could likely introduce a custom type descriptor that lifted the variables out of the activity and surfaces them in such a way that they would be discovered by the inspection above.&amp;#160; &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Disclaimer: the Potential Future Approach is simply something that we’ve discussed that we could do, it does not represent something that we will do.&amp;#160; If you think that is an interesting extensibility point that you might want to take advantage of down the road, let me know.&amp;#160; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9918399" 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/beta/">beta</category><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/vs2010/">vs2010</category></item><item><title>WF4 Beta1 =&gt; Beta2 Breaking Changes Document Published</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/11/02/wf4-beta1-beta2-breaking-changes-document-published.aspx</link><pubDate>Mon, 02 Nov 2009 05:24:44 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9916032</guid><dc:creator>mwinkle</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9916032</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/11/02/wf4-beta1-beta2-breaking-changes-document-published.aspx#comments</comments><description>&lt;p&gt;Fresh on microsoft.com downloads, you can get the details of the major breaking changes that occurred for WF between Beta 1 and Beta 2.&lt;/p&gt;  &lt;p&gt;Get the document &lt;a href="http://bit.ly/1EsOVK"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;We will publish a similar document for any changes between Beta2 and RTM, although that list should be on the shorter side.&amp;#160; If you have feedback on the document, like the way something is presented or think we could have done a better job explaining it, please let me know.&amp;#160; Either comment here or use the &lt;a href="http://blogs.msdn.com/mwinkle/contact.aspx"&gt;“Email” link&lt;/a&gt; on the side. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9916032" 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><category domain="http://blogs.msdn.com/b/mwinkle/archive/tags/vs2010/">vs2010</category></item><item><title>Deep Dive into the WF4 Designer Data Model: ModelItem and ModelProperty</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/10/28/deep-dive-into-the-designer-data-model-modelitem-and-modelproperty.aspx</link><pubDate>Wed, 28 Oct 2009 21:50:45 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9914364</guid><dc:creator>mwinkle</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9914364</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/10/28/deep-dive-into-the-designer-data-model-modelitem-and-modelproperty.aspx#comments</comments><description>&lt;p&gt;In this &lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/06/17/introduction-to-wf-designer-rehosting-part-1.aspx"&gt;post&lt;/a&gt; I published an overview of the designer architecture.&amp;#160; I’ll copy the picture and the description of what I want to talk about today.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DeepDiveintotheDesignerDataModelModelIte_C3C6/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/DeepDiveintotheDesignerDataModelModelIte_C3C6/image_thumb.png" width="417" height="192" /&gt;&lt;/a&gt; &lt;/p&gt;    &lt;p&gt;There are a few key components here&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;Source        &lt;ul&gt;         &lt;li&gt;In VS, this is xaml, but this represents the durable storage of the “thing” we are editing &lt;/li&gt;       &lt;/ul&gt;     &lt;/li&gt;      &lt;li&gt;Instance        &lt;ul&gt;         &lt;li&gt;This is the in memory representation of the item being edited.&amp;#160; In vs2010 for the WF designer, this is a hierarchy of System.Activities instances (an object tree) &lt;/li&gt;       &lt;/ul&gt;     &lt;/li&gt;      &lt;li&gt;&lt;strong&gt;Model Item Tree &lt;/strong&gt;        &lt;ul&gt;         &lt;li&gt;&lt;strong&gt;This serves as an intermediary between the view and the instance, and is responsible for change notification and tracking things like undo state &lt;/strong&gt;&lt;/li&gt;       &lt;/ul&gt;     &lt;/li&gt;      &lt;li&gt;Design View        &lt;ul&gt;         &lt;li&gt;This is the visual editing view that is surfaced to the user, the designers are written using WPF, which uses plain old data binding in order to wire up to the underlying model items (which represent the data being edited). &lt;/li&gt;       &lt;/ul&gt;     &lt;/li&gt;      &lt;li&gt;Metadata Store        &lt;ul&gt;         &lt;li&gt;This is a mapping between type and designers, an attribute table for lack of a better term.&amp;#160; This is how we know what designer to use for what type &lt;/li&gt;       &lt;/ul&gt;     &lt;/li&gt;   &lt;/ul&gt; &lt;/blockquote&gt;  &lt;h1&gt;Motivating the ModelItem tree&lt;/h1&gt;  &lt;p&gt;One observation that you could make when looking at the diagram above is “I should just be able to bind the view to the instance.”&amp;#160; This approach could work, but has a couple of implementation problems:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;It is unrealistic to expect that instances of runtime types will all be built to fit perfectly into a design oriented world.&amp;#160; The most obvious problem is that our activity types aren’t going to inherit from &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject%28VS.100%29.aspx"&gt;DependencyObject&lt;/a&gt;, or implement &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged%28VS.100%29.aspx"&gt;INotifyPropertyChanged&lt;/a&gt;.&amp;#160; We can’t specify that all collections are &lt;a href="http://msdn.microsoft.com/en-us/library/ms668604.aspx"&gt;ObservableCollection&lt;/a&gt;&amp;#160; [interesting trivia, ObservableCollection has moved from WindowsBase.dll into System.dll].&amp;#160; If we could, that would make life easy, but that’s not the case.&amp;#160;&amp;#160; &lt;ul&gt;       &lt;li&gt;Additionally, there are design time services that we need to think about supporting (such as Undo/Redo), and we need to make sure we can consistently handle this across many object types, including those that have not been written by us. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;There may be a case for not actually operating on a live instance of the object graph.&amp;#160; Note, in VS2010, we do, but if we want to do work that would enable a design time XAML experience, we would need our instance to actually contain a lot of information about the source document.&amp;#160; &lt;/li&gt;    &lt;li&gt;If we go directly from the view to the instance, we tightly couple the two together, and that makes doing more interesting things in the future tricky.&amp;#160; For instance, if we want to add refactoring support to update instances of objects, we need more than just the object graph to do that (the model item tree also keeps track of things like back pointers, so I know everybody that references the object).&amp;#160; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;These reasons cause us to think about an abstraction we can use to intermediate the implementation details of the instance and the view with a common layer.&amp;#160; If you have programmed at the &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.windows.design.model%28VS.100%29.aspx"&gt;WPF designer extensibility level&lt;/a&gt;, you will likely be familiar with the idea (and some of the types) here. &lt;/p&gt;  &lt;h1&gt;The ModelItem tree&lt;/h1&gt;  &lt;p&gt;The way that I think about the &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelitem%28VS.100%29.aspx"&gt;ModelItem&lt;/a&gt;/&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelproperty%28VS.100%29.aspx"&gt;ModelProperty&lt;/a&gt; tree is that it forms a very thing proxy layer on top of the shape of the instance being edited.&amp;#160; &lt;/p&gt;  &lt;p&gt;Let’s start with a very simple type:&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; Animal
{
    &lt;span class="rem"&gt;// simple property&lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name { get; set; }
    &lt;span class="rem"&gt;// complex property &lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; Location Residence { get; set; } 
    &lt;span class="rem"&gt;// list &lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; List&amp;lt;Animal&amp;gt; CloseRelatives { get; set; }
    &lt;span class="rem"&gt;// dictionary&lt;/span&gt;
    &lt;span class="kwrd"&gt;public&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt; Features { get; set; } 
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Location
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; StreetAddress { get; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; City { get; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; State { 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 for a moment that I just gave an animal Features, I’m a PM, it’s how we think :-) &lt;/p&gt;

&lt;p&gt;Now, let’s create some instances of that, and then actually create a ModelItem.&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &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;   2:  &lt;/span&gt;var companion1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; Animal { Name = &lt;span class="str"&gt;&amp;quot;Houdini the parakeet&amp;quot;&lt;/span&gt; };&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;var companion2 = &lt;span class="kwrd"&gt;new&lt;/span&gt; Animal { Name = &lt;span class="str"&gt;&amp;quot;Groucho the fish&amp;quot;&lt;/span&gt; };&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;var animal = &lt;span class="kwrd"&gt;new&lt;/span&gt; Animal &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;                 {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;                     Name = &lt;span class="str"&gt;&amp;quot;Sasha the pug&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;                     Residence = &lt;span class="kwrd"&gt;new&lt;/span&gt; Location &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;                     {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;                         StreetAddress = &lt;span class="str"&gt;&amp;quot;123 Main Street&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;                         City = &lt;span class="str"&gt;&amp;quot;AnyTown&amp;quot;&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;                         State = &lt;span class="str"&gt;&amp;quot;Washington&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;                     },&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;                     Features = { &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;                        {&lt;span class="str"&gt;&amp;quot;noise&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;snort&amp;quot;&lt;/span&gt; },&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;                        {&lt;span class="str"&gt;&amp;quot;MeanTimeUntilNaps&amp;quot;&lt;/span&gt;, TimeSpan.FromMinutes(15) }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;                     },&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;                     CloseRelatives = { companion1, companion2 } &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;                 };&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;ModelTreeManager mtm = &lt;span class="kwrd"&gt;new&lt;/span&gt; ModelTreeManager(ec);&amp;#160; mtm.Load(animal);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;ModelItem mi = mtm.Root;&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;One thing to note here is that I am using &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modeltreemanager%28VS.100%29.aspx"&gt;ModelTreeManager&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.editingcontext%28VS.100%29.aspx"&gt;EditingContext&lt;/a&gt; outside the context (no pun intended) of the designer (see lines 1, 19, and 20 in the above snippet).&amp;#160; This isn’t the usual way we interact with these, but it’s for this sample so that we can focus just on the data structure itself. [as an aside, my brother did have a parakeet named Houdini].&amp;#160; &lt;/p&gt;

&lt;p&gt;Let’s take a quick look at a visualization of what the data structure will look like.&amp;#160; Remember to think about the ModelItem tree as a thin proxy to the shape of the instance.&lt;/p&gt;

&lt;p&gt;Rather than spend an hour in powerpoint,&amp;#160; I’ll just include a sketch :-)&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DeepDiveintotheDesignerDataModelModelIte_C3C6/IMAG0111_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="IMAG0111" border="0" alt="IMAG0111" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DeepDiveintotheDesignerDataModelModelIte_C3C6/IMAG0111_thumb.jpg" width="542" height="421" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;On the left, you see the object itself.&amp;#160; For that object, there will be one ModelItem which “points” to that object.&amp;#160; You can call &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelitem.getcurrentvalue(VS.100).aspx"&gt;ModelItem.GetCurrentValue()&lt;/a&gt; and that will return the actual object. If you look at the ModelItem type, you will see some interesting properties which describe the object. &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&amp;#160;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelitem.itemtype(VS.100).aspx"&gt;ItemType&lt;/a&gt; is the type of the object pointed to (in this case, Animal) &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelitem.parent(VS.100).aspx"&gt;Parent&lt;/a&gt; is the item in the tree which “owns” this model item (in the case of the root, this is null) &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelitem.source(VS.100).aspx"&gt;Source&lt;/a&gt; is the property that provided the value (in the case of the root, this is null) &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelitem.sources(VS.100).aspx"&gt;Sources&lt;/a&gt; is a collection of all the backpointers to all of the properties which hold this value 

    &lt;ul&gt;
      &lt;li&gt;Note, the distinction between Source and Sources and Parent and Parents is a topic worthy of another post &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelitem.view(VS.100).aspx"&gt;View&lt;/a&gt; is the DependencyObject that is the visual (in teh case above, this is null as there is no view service hooked into the editing context) &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelitem.properties(VS.100).aspx"&gt;Properties&lt;/a&gt; is the collection of properties of this object &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Properties is the part where things get interesting.&amp;#160; There is a collection of ModelProperty objects which correspond to the shape of the underlying objects.&amp;#160; For the example above, let’s break in the debugger and see what there is to see. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DeepDiveintotheDesignerDataModelModelIte_C3C6/image_4.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/DeepDiveintotheDesignerDataModelModelIte_C3C6/image_thumb_1.png" width="711" height="515" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As we might expect, there are 4 properties, and you will see all sorts of properties that describe the properties.&amp;#160; A few interesting ones:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelproperty.computedvalue(VS.100).aspx"&gt;ComputedValue&lt;/a&gt;&amp;#160; is a short circuit to the return the underlying object that is pointed to by the property.&amp;#160; This is equivalent to ModelProperty.Value.GetCurrentValue(), but has an interesting side effect that setting it is equivalent to &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelproperty.setvalue(VS.100).aspx"&gt;SetValue().&lt;/a&gt;&amp;#160;&amp;#160; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelproperty.name(VS.100).aspx"&gt;Name&lt;/a&gt;, not surprisingly, this is name of the property &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelproperty.propertytype(VS.100).aspx"&gt;PropertyType&lt;/a&gt; is the type of the property &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelproperty.collection(VS.100).aspx"&gt;Collection&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelproperty.dictionary(VS.100).aspx"&gt;Dictionary&lt;/a&gt; are interesting little shortcuts that we’ll learn about in a future blog post. &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelproperty.value(VS.100).aspx"&gt;Value&lt;/a&gt; points to a model item that is in turn the pointer to the value &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.presentation.model.modelproperty.parent(VS.100).aspx"&gt;Parent&lt;/a&gt; points to the ModelItem which “owns” this property &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As Value points to another model item, you can see how this begins to wrap the object, and how this can be used to program against the data model.&amp;#160; Let’s look at a little bit of code.&amp;#160; &lt;/p&gt;

&lt;pre class="csharpcode"&gt;root.Properties[&lt;span class="str"&gt;&amp;quot;Residence&amp;quot;&lt;/span&gt;].
                Value.
                Properties[&lt;span class="str"&gt;&amp;quot;StreetAddress&amp;quot;&lt;/span&gt;].
                Value.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;p&gt;You might say “hey, that’s a little ugly”&amp;#160; and I have two bits of good news for you.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;ModelItem has a custom type descriptor, which means that in WPF XAML we can bind in the way we expect (that is, I can bind to ModelItem.Location.StreetAddress, and the WPF binding mechanism will route that to mi.Properties[“Location”].Value.Properties[“StreetAddress”].&amp;#160; So, if you don’t use C# (and just use XAML), you don’t worry about this &lt;/li&gt;

  &lt;li&gt;In RTM, we will likely add support for the dynamic keyword in C# that will let you have a dynamic object and then program against it just like you would from WPF XAML.&amp;#160; It’s pretty cool and I hope we get to it, if we do I will blog about it. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here’s a set of tests which show the different things we’ve talked about:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;ModelItem root = mtm.Root;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;Assert.IsTrue(root.GetCurrentValue() == animal, &lt;span class="str"&gt;&amp;quot;GetCurrentValue() returns same object&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;Assert.IsTrue(root.ItemType == &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Animal),&lt;span class="str"&gt;&amp;quot;ItemType describes the item&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;Assert.IsTrue(root.Parent == &lt;span class="kwrd"&gt;null&lt;/span&gt;,&lt;span class="str"&gt;&amp;quot;root parent is null&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;Assert.IsTrue(root.Source == &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;root source is null&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;Assert.IsTrue(((List&amp;lt;Animal&amp;gt;)root.Properties[&lt;span class="str"&gt;&amp;quot;CloseRelatives&amp;quot;&lt;/span&gt;].ComputedValue)[0] == companion1, &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;           &lt;span class="str"&gt;&amp;quot;ComputedValue of prop == actual object&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;Assert.IsFalse(((List&amp;lt;Animal&amp;gt;)root.Properties[&lt;span class="str"&gt;&amp;quot;CloseRelatives&amp;quot;&lt;/span&gt;].ComputedValue)[0] == companion2, &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;           &lt;span class="str"&gt;&amp;quot;ComputedValue of prop == actual object&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;Assert.AreEqual(root.Properties[&lt;span class="str"&gt;&amp;quot;Residence&amp;quot;&lt;/span&gt;].&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    Value.&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    Properties[&lt;span class="str"&gt;&amp;quot;StreetAddress&amp;quot;&lt;/span&gt;].&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    Value.GetCurrentValue(), &lt;span class="str"&gt;&amp;quot;123 Main Street&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;get actual value back out&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;Assert.AreEqual(root, root.Properties[&lt;span class="str"&gt;&amp;quot;Residence&amp;quot;&lt;/span&gt;].Parent, &lt;span class="str"&gt;&amp;quot;property points to owner&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;ModelItem location = root.Properties[&lt;span class="str"&gt;&amp;quot;Residence&amp;quot;&lt;/span&gt;].Value;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;Assert.AreEqual(root.Properties[&lt;span class="str"&gt;&amp;quot;Residence&amp;quot;&lt;/span&gt;], location.Source, &lt;span class="str"&gt;&amp;quot;sources point to the right place&amp;quot;&lt;/span&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;h2&gt;Oh my, won’t this get explosively large?&lt;/h2&gt;

&lt;p&gt;Good question, and the truth is that yes, this could get large as you were to spelunk the object graph.&amp;#160; The good news is that we’re incredibly lazy about loading this, we will only flush out the properties collection on demand, and we won’t generate a ModelItem until it is requested.&amp;#160; When we combine this with the View virtualization work we have done, we will only ever load as much in the WF designer as you need.&amp;#160;&amp;#160; This keeps the overhead minimal, and in does not represent a substantial memory overhead.&lt;/p&gt;

&lt;h1&gt;Why should I be careful about ModelItem.GetCurrentValue()&lt;/h1&gt;

&lt;p&gt;One might be tempted to just say “Hey, I’m in C#, I’ll just call GetCurrentValue() and party on that.&amp;#160; If you do that, you are entering dangerous waters where you can mess up the data model.&amp;#160; Since the underlying instance doesn’t likely support any change notification mechanism, the model item tree will get out of sync with the underlying instance description.&amp;#160; This will manifest itself in problems at the designer because our serialization is based off the instance, not the ModelItem tree (note, that’s a vs2010 implementation detail that could change in a subsequent release).&amp;#160; The net result though is that you will get your view out of sync with your instance and serialization and that’s generally considered problematic.&amp;#160; &lt;/p&gt;

&lt;h1&gt;Summary&lt;/h1&gt;

&lt;p&gt;Wow, that’s a longer post than I intended.&amp;#160; What have we covered:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The Modelitem tree and why we need it &lt;/li&gt;

  &lt;li&gt;The relationship between the underlying instance and ModelItem/ModelProperty &lt;/li&gt;

  &lt;li&gt;The shape and use of ModelItem / ModelProperty &lt;/li&gt;

  &lt;li&gt;Imperative programming against the tree &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What haven’t we covered yet&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ModelItemCollection and ModelItemDictionary &lt;/li&gt;

  &lt;li&gt;How to use Sources and Parents to understand how the object sits in the graph and manipulation we can do for fun and profit &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ll get there.&amp;#160; In the meantime, if you have questions, let me know. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;**** Minor update on 10/29 to fix a bug in the code ****&lt;/p&gt;

&lt;p&gt;This is the way to use ModelTreeManager to generate ModelItems (Line 3 is the critical piece that was missing):&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &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;   2:  &lt;/span&gt;ModelTreeManager mtm = &lt;span class="kwrd"&gt;new&lt;/span&gt; ModelTreeManager(ec);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&lt;strong&gt;mtm.Load(&lt;span class="kwrd"&gt;new&lt;/span&gt; Sequence());&lt;/strong&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;mtm.Root.Properties[&lt;span class="str"&gt;&amp;quot;Activities&amp;quot;&lt;/span&gt;].Collection.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; WriteLine());&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;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9914364" width="1" height="1"&gt;</description></item><item><title>WF4 Designer Bloggers</title><link>http://blogs.msdn.com/b/mwinkle/archive/2009/10/28/wf4-designer-bloggers.aspx</link><pubDate>Wed, 28 Oct 2009 17:29:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9914205</guid><dc:creator>mwinkle</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/mwinkle/rsscomments.aspx?WeblogPostID=9914205</wfw:commentRss><comments>http://blogs.msdn.com/b/mwinkle/archive/2009/10/28/wf4-designer-bloggers.aspx#comments</comments><description>&lt;p&gt;I wanted to put a quick note up as the team is starting to blog a little more frequently and putting some interesting content out there.&amp;#160; A few places to check out to hear from the folks on the team&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/endpoint"&gt;Endpoint&lt;/a&gt; – This is the general WF team blog, and has had some good posts &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://blogs.msdn.com/endpoint/archive/2009/10/26/going-to-pdc-want-to-meet-the-team.aspx"&gt;Going to PDC? Want to Meet the Team?&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;&lt;a href="http://blogs.msdn.com/endpoint/archive/2009/10/21/client-profile-in-net-4.aspx"&gt;Client Profile in .NET 4&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;&lt;a href="http://blogs.msdn.com/endpoint/archive/2009/10/20/wf4-changes-between-beta-1-and-beta-2.aspx"&gt;WF4 Changes between Beta1 and Beta2&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/cathyk"&gt;Cathy Dumas&lt;/a&gt; – Cathy is the PM on my team focused on the expression editing experience and the designer UX&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://blogs.msdn.com/cathyk/archive/2009/10/27/vb-expression-example-manipulating-generic-lists.aspx"&gt;VB Expressions Example: Manipulating Generic Lists&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="VB for C# Developers"&gt;VB for C# developers&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/kushals"&gt;Kushal Shah&lt;/a&gt; – Kushal is the PM on my team for debugging and Visual Studio integration&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://blogs.msdn.com/kushals/archive/2009/10/27/adding-activities-on-the-designer-programmatically.aspx"&gt;Adding Activities on the designer programmatically&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;&lt;a href="http://blogs.msdn.com/kushals/archive/2009/10/26/adding-variables-expressions-and-bindings-programmatically.aspx"&gt;Adding Variables, Expressions and Bindings Programmatically&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;&lt;a href="WF 4.0 Templates - Beta2"&gt;WF4 Templates – Beta 2&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;What blogs are you reading for WF4 content?&amp;#160; What kind of stuff would you like to hear more about?&amp;#160; Let us know!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9914205" 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/vs2010/">vs2010</category></item></channel></rss>
