Reputation: 133
I have an invokeworkflow activity inside a replicator activity. The workflow that I'm trying to invoke requires 2 parameters to be passed to it, an integer and a string parameters, and these should be passed to the workflow by the replicator activity. Any ideas on how this could be done?
Thanks.
Upvotes: 0
Views: 2831
Reputation: 19142
You can declare two properties in the target workflow like this:
public static readonly DependencyProperty MyIntProperty =
DependencyProperty.Register("MyInt", typeof(int), typeof(Workflow3));
public static readonly DependencyProperty MyStringProperty =
DependencyProperty.Register("MyString", typeof(string), typeof(Workflow3));
public int MyInt
{
get { return (int)GetValue(MyIntProperty); }
set { SetValue(MyIntProperty, value); }
}
public string MyString
{
get { return (string)GetValue(MyStringProperty); }
set { SetValue(MyStringProperty, value); }
}
After that, if you check the Properties tab of the InvokeWorkflowActivity
you will see the two properties in the Parameters
category.
You can either provide constant values or you can bind them to any property of the hosting workflow.
Upvotes: 0
Reputation: 11
I realize this post is old, but for those finding this on Google with the same question, this is what you need to do:
The ReplicatorActivity exposes an event handler called ChildInitialized. Create your handler for this event and in it you will receive a ReplicatorChildEventArgs. In it, you can receive the Activity through the event args as such:
InvokerActivity activity = (e.Activity as InvokerActivity);
if (activity != null)
{
activity.MyParam = e.InstanceData as MyParamType;
}
Now when you run it, the ReplicatorActivity will call this method once for every item in the collection and will pass along the parameters for each of the InvokerActivities it will spawn.
e.InstanceData will be the next object in the collection that the Replicator is iterating through.
Upvotes: 1
Reputation: 19142
Here is a full example (note that whatever is included in the constructors can be set in the properties pane of the designer): Workflow3 is the target workflow that contains only a CodeActivity and the behind code is the following:
public sealed partial class Workflow3 : SequentialWorkflowActivity
{
public static readonly DependencyProperty MyIntProperty =
DependencyProperty.Register("MyInt", typeof(int), typeof(Workflow3));
public static readonly DependencyProperty MyStringProperty =
DependencyProperty.Register("MyString", typeof(string), typeof(Workflow3));
public Workflow3()
{
InitializeComponent();
this.codeActivity1.ExecuteCode += new System.EventHandler(this.codeActivity1_ExecuteCode);
}
public int MyInt
{
get { return (int)GetValue(MyIntProperty); }
set { SetValue(MyIntProperty, value); }
}
public string MyString
{
get { return (string)GetValue(MyStringProperty); }
set { SetValue(MyStringProperty, value); }
}
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
Console.WriteLine("Invoke WF: Int = {0}, String = {1}", this.MyInt, this.MyString);
}
}
Workflow2 is the hosting workflow that contains only a ReplicatorActivity. The ReplicatorActivity contains only a InvokeWorkflowActivity which has the TargetWorkflow set to Workflow3. The code-behind is the following:
public sealed partial class Workflow2 : SequentialWorkflowActivity
{
// Variables used in bindings
public int InvokeWorkflowActivity1_MyInt = default(int);
public string InvokeWorkflowActivity1_MyString = string.Empty;
public Workflow2()
{
InitializeComponent();
// Bind MyInt parameter of target workflow to my InvokeWorkflowActivity1_MyInt
WorkflowParameterBinding wpb1 = new WorkflowParameterBinding("MyInt");
wpb1.SetBinding(WorkflowParameterBinding.ValueProperty, new ActivityBind(this.GetType().Name, "InvokeWorkflowActivity1_MyInt"));
this.invokeWorkflowActivity1.ParameterBindings.Add(wpb1);
// Bind MyString parameter of target workflow to my InvokeWorkflowActivity1_MyString
WorkflowParameterBinding wpb2 = new WorkflowParameterBinding("MyString");
wpb2.SetBinding(WorkflowParameterBinding.ValueProperty, new ActivityBind(this.GetType().Name, "InvokeWorkflowActivity1_MyString"));
this.invokeWorkflowActivity1.ParameterBindings.Add(wpb2);
// Add event handler for Replicator's Initialized event
this.replicatorActivity1.Initialized += new EventHandler(ReplicatorInitialized);
// Add event handler for Replicator's ChildInitialized event
this.replicatorActivity1.ChildInitialized += new EventHandler<ReplicatorChildEventArgs>(this.ChildInitialized);
}
private void ReplicatorInitialized(object sender, EventArgs e)
{
// Find how many workflows I want
List<MyClass> list = new List<MyClass>();
list.Add(new MyClass() { MyInt = 1, MyString = "Str1" });
list.Add(new MyClass() { MyInt = 2, MyString = "Str2" });
list.Add(new MyClass() { MyInt = 3, MyString = "Str3" });
// Assign list to replicator
replicatorActivity1.InitialChildData = list;
}
private void ChildInitialized(object sender, ReplicatorChildEventArgs e)
{
// This is the activity that is initialized
InvokeWorkflowActivity currentActivity = (InvokeWorkflowActivity)e.Activity;
// This is the initial data
MyClass initialData = (MyClass)e.InstanceData;
// Setting the initial data to the activity
InvokeWorkflowActivity1_MyInt = initialData.MyInt;
InvokeWorkflowActivity1_MyString = initialData.MyString;
}
public class MyClass
{
public int MyInt { get; set; }
public string MyString { get; set; }
}
}
The expected outcome is the following:
Invoke WF: Int = 1, String = Str1
Invoke WF: Int = 2, String = Str2
Invoke WF: Int = 3, String = Str3
Hope that this will help you.
Upvotes: 2