2
votes

I'm working with Windows Workflow 4, and I need to create a C# activity that, basically, inherits from the Sequence activity. I want it to look just like the Sequence activity, so a user can drag and drop other activities onto it from the designer. But, it acts differently in the code (maybe I want to run them in a different order, or do special actions between each one, it shouldn't matter).

How can I do this? I see a similar question was asked about this, and only one person responded with a suggestion that only applies to Windows Workflow 3. In version 4, a sequence activity can't be inherited from, to say the least.

This doesn't seem like a very far fetched concept. A Sequence activity is provided as a built in activity. So, it seems logical that it should be reproducible, or at least inheritable, so I can have a customized version of a Sequence activity.

Anyone have any ideas?

1
I ganked my version from MSDN: social.msdn.microsoft.com/Forums/ar-SA/wfprerelease/thread/… required some modification and some reflection work to get everything working, but it looks as expected. - user1228
Will: that looks great, and this should be an answer. But I am not sure how to implement it. There's the "SpacerTemplate" UserControl, and when I paste this code into VS2010, it has several errors. The class derives from IComponentConnector, but doesn't implement either of its methods. And if I implement them with NotImplementedException() stubs, I get more errors: "this.dropTarget" doesn't exist, for instance. And the activity designer code (sap:WorkflowItemsPresenter), well, I can't figure out where to put that. I'm new to workflows so I could really use a more idiot proof example. - Jay Sullivan
Ooo! Ooo! Okay, I had to change the namespace in the SpacerTemplate XAML to match the Code's namespace. Duh! That fixes the interface implementation issue (well, it compiles). Now I gotta figure out how to create that designer. I don't know where to put that sap:WorkflowItemsPresenter block of XAML. - Jay Sullivan
Your IComponentConnector issue is caused by copypasting code from the internets. This is a programming sin, and you must repent by NOT copypasting codes but by creating a new UserControl and using the example code as a GUIDE. Your issues have nothing to do with WF, they are all WPF. Slow down and understand what you are doing before doing it. - user1228
That's usually a problem with the binding. Start small, then go big. - user1228

1 Answers

8
votes

The "System.Activities.Core.Presentation.SequenceDesigner" designer is already available in WF 4. One can then compose a Sequence activity and use this designer for the outer class.

Here's a working example:

using System.Activities;
using System.Activities.Statements;
using System.Collections.ObjectModel;
using System.ComponentModel;

[Designer("System.Activities.Core.Presentation.SequenceDesigner, System.Activities.Core.Presentation")]
public class MySeq : NativeActivity
{
    private Sequence innerSequence = new Sequence();

    [Browsable(false)]
    public Collection<Activity> Activities
    {
        get
        {
            return innerSequence.Activities;
        }
    }

    [Browsable(false)]
    public Collection<Variable> Variables
    {
        get
        {
            return innerSequence.Variables;
        }
    }

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        metadata.AddImplementationChild(innerSequence);
    }

    protected override void Execute(NativeActivityContext context)
    {
        context.ScheduleActivity(innerSequence);
    }

}

This is forwarding the real behavior on to a private innerSequence, which might make this code seem useless, but note that in the Execute method it gives us a chance to do things before and after execution. If we want to provide customized behavior, we'd have to implement it instead of forwarding to an inner private activity.