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]; } }
January 3rd, 2009 at 9:22 am
It works! cool!
Thank you!
February 19th, 2009 at 10:41 am
Nice…Thanks.
March 14th, 2009 at 4:53 am
We can use InitializeChildData method to get the current data.
Eg:-
Test(object sender, ReplicatorChildEventArgs e)
{
string item = e.InstanceData.ToString();
}
March 17th, 2009 at 5:23 am
Sajin, we can if we are creating task, but on complete task, we can’t
August 19th, 2009 at 5:58 am
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.
August 19th, 2009 at 7:23 am
Problem is when any instance of replicators children ends, indexes may have changed
August 20th, 2009 at 6:37 am
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.