Saturday, February 19, 2011

InvokeWorkflow activity inside a replicator activity

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.

From stackoverflow
  • 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.

  • Yes, but my question was, how do I pass these values from the Replicator activity to the InvokeWorkflow activity. What events should I use to find out the current InvokeWorkflow activity (since there will be multiple InvokeWorkflow activities started by the Replicator activity). I know that I can use the InitialData property of the Replicator activity to pass in values to the child activities, its just I don't know how to get these values back and pass them to the correct InvokeWorkflow activity.

    Thanks

  • 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.

0 comments:

Post a Comment