views:

40

answers:

3

Is this possible? I know it is for MS since they have WF activity packs but I'm not sure how it's done. It would be nice to be able to have Activities with Body blocks to insert other activities, buttons, etc. If not too much trouble and/or time consuming that is.

A: 

You need to start with a NativeActivity instead of a CodeActivity. The NativeActivity lets you schedule child activities through its execution context. There is no template for the NativeActivity, instead you just create a class and derive from NativeActivity.

Maurice
Thanks Maurice. So NativeActivity allows me to create activities that display an execution body on the VS workflow designer? I would love to be able to write Activities like sequence, parallel, while, foreach, etc. that have execution blocks where a user of my activity could drop other activities inside of my activity.
jlafay
Any input on this? You didn't really address the actual context of my question.
jlafay
Check this blog post from Matt which pretty sounds like the what you are looking for: http://blogs.msdn.com/b/mwinkle/archive/2009/12/24/swiss-cheese-and-wf4-or-an-introduction-to-activityaction.aspx
Maurice
+1  A: 

Its easy enough if you follow a few rules. Here's an example of a NativeActivity that has a child:

[Designer(typeof(MyActivityDesigner)), ContentProperty("Child")]
public sealed class MyActivity : 
    NativeActivity, IActivityTemplateFactory
{
    // this "activity delegate" holds our child activity
    public ActivityAction Child { get; set; }

    // may be necessary to do this
    protected override void 
        CacheMetadata(NativeActivityMetadata metadata)
    {
        metadata.AddDelegate(Child);
    }

    protected override void 
        Execute(NativeActivityContext context)
    {
        // do some work here, then
        context.ScheduleAction(Child);
    }

    // better to use a template factory than a constructor to do this!
    Activity IActivityTemplateFactory
        .Create(System.Windows.DependencyObject target)
    {
        return new MyActivity
        {
            // HAVE to have this set, or it fails in the designer!
            Child = new ActivityAction()
        };
    }
}

Note a few things: We use an Activity Delegate type to hold our child. Second, we implement IActivityTemplateFactory to configure our activity for the designer. Its always better/more stable to do this than set stuff up in the constructor. We will be binding to a property of the delegate, so we have to set an instance; otherwise the binding will fail.

When we execute, all you have to do is schedule your child when appropriate and return. You shouldn't block, of course.

Then, in the designer, you'd bind to Child like this:

<sap:WorkflowItemPresenter
    HintText="Add children here!"
    Item="{Binding Path=ModelItem.Child.Handler}" />
Will
Could you possibly tell me which namespace you're using in order to use the Designer attribute?
jlafay
for future reference, just search MSDN for "DesignerAttribute" or whatever you're looking for. It'll tell you the assembly it is located in, which in this case is System.ComponentModel
Will
A: 

The Pro WF : Windows Workflow in .Net 4 book by Bruce Bukovics also has lots of examples. You might want to check that out.

dmelinosky
Thanks dmelinosky, I just picked it up actually and I'm digging pretty deep into it. To anyone else starting with WF or WF4, definitely pick up that book, it's excellent.
jlafay