SharePoint Workflow: Getting Replicator ChildData within a CreateTask Activity

Disclaimer: the following code requires version 3.5 of the .Net Framework, but can easily be modified to run using .Net 2.0

Scenario

So I was asked to develop a fairly straight forward approval activity in which several users were to be assigned an approval task in parallel. Microsoft offers its ReplicatorActivity to accomplish just this. The gotcha is that when running the ReplicatorActivity in parallel, the CurrentIndex property of the replicator is always the last index value of its child data. So how do you know which ChildData item the replicator is currently executing upon?

Solution

What I came up with seems a little hacky, but has been working beautifully for me. Here it goes…

The replicator contains a DynamicActivities property which holds references to each of the replicated activities it creates. Using Linq, we can easily convert this collection to a list, and then determine the index of the current activity within our newly converted activity list. The following example shows how I am using this method to access the current child data from within a CreateTask activity:

        private void createTask_Invoked(object sender, EventArgs e)
        {
            var createTask = (CreateTask)sender;
            string approver = (string)WorkflowUtils
                .GetReplicatorChildData(createTask);
 
            ...
 
        }

And the magic happens within our WorkflowUtils helper class:

    public static class WorkflowUtils
    {
        public static Activity GetTopMostReplicatorChild(Activity activity)
        {
            var parent = activity.Parent;
            if (parent == null)
                return null;
 
            if (parent is ReplicatorActivity)
                return activity;
 
            return GetTopMostReplicatorChild(activity.Parent);
        }
 
        public static object GetReplicatorChildData(Activity activity)
        {
            var topMostChild = GetTopMostReplicatorChild(activity);
            var replicator = (ReplicatorActivity)topMostChild.Parent;
 
            int currentIndex = replicator.DynamicActivities
                .ToList()
                .IndexOf(topMostChild);
 
            return replicator.CurrentChildData[currentIndex];
        }
    }

7 Responses to “SharePoint Workflow: Getting Replicator ChildData within a CreateTask Activity”

  • Kiril Says:

    It works! cool!
    Thank you!

  • WG Says:

    Nice…Thanks.

  • Sajin Says:

    We can use InitializeChildData method to get the current data.

    Eg:-

    Test(object sender, ReplicatorChildEventArgs e)
    {

    string item = e.InstanceData.ToString();
    }

  • Flank Says:

    Sajin, we can if we are creating task, but on complete task, we can’t

  • dejawue Says:

    Seems to work fine, but problem is when multiple tasks are created and users complete their tasks in order as they are assigned in SPUserField.
    The current index will be the lowest used. i.e. First assigned user (with index 0) complete the task then all other users will be indexed 0 in their activities.

  • dejawue Says:

    Problem is when any instance of replicators children ends, indexes may have changed

  • dejawue Says:

    Ok, the solution is handle ChildCompleted event of the replicator:

    private void RemoveChildData(object sender, ReplicatorChildEventArgs e)
    {
    int CurrentIndex = Replikator.CurrentChildData.IndexOf(e.InstanceData);
    Replikator.CurrentChildData.RemoveAt(CurrentIndex);
    }

    Thanks for this post. It’s greate.

Leave a Reply