If you're creating a custom composite activity, you might need to restrict whether a given activity can be inserted as a child at a specific point of your composite activity when working on the Workflow Designer. Fortunately, this is actually fairly easy using the designer facilities in Windows Workflow Foundation.
Let's quickly sample this by building a custom CodeFirstSequentialActivity, which is a simple sequential composite activity that requires that the first child activity in the sequence is a CodeActivity. Other than that, any other type of activity can be a child.
First, we'll create a custom designer class for our activity, which we'll inherit from the SequenceDesigner class. In it, we'll override the CanInsertActivities method, in which we'll do a simple test: If the insertion point is the first one on our composite activities, then we'll check that the first activity being dropped/inserted is indeed a CodeFirstActivity, and, if so, just return false to block the designer from inserting the child activities:
public class CodeFirstSequentialActivityDesigner : SequenceDesigner
{
public override bool CanInsertActivities(HitTestInfo insertLocation,
System.Collections.ObjectModel.ReadOnlyCollection activitiesToInsert)
{
bool canDo = base.CanInsertActivities(insertLocation, activitiesToInsert);
CompositeActivity theActivity = Activity as CompositeActivity;
if ( theActivity != null )
{
// first activity in can only be a CodeActivity
if ( insertLocation.MapToIndex() == 0 )
{
if ( !(activitiesToInsert[0] is CodeActivity) )
{
return false;
}
}
}
return canDo;
}
}
Then, it's just a matter of associating our custom designer with our activity:
[Designer(typeof(CodeFirstSequentialActivityDesigner))]
class CodeFirstSequentialActivity : CompositeActivity
{
// ...
}
A nice thing about this is that this will block Drag & Drop operations as well as custom trying to copy/paste activities into our custom composite activities, without having to handle both operations as different things.
One thing to watch out, though, is that this only takes care of the designer. You'll also want to create a custom activity validator that validates that child activities are of the right type.