Task 1: Create the CallExternalMethod Activities

In this task, you modify the sequential workflow by adding an IfElseActivity activity to determine whether a manager or a lead person must approve or reject the amount of the expense report. When this is determined, the workflow uses a corresponding CallExternalMethodActivity activity to call a method defined in the host application. The method in the host application updates the user interface, notifying the user that an approval or rejection is required, and by whom.

Note

Although you are encouraged to follow the exercises in a linear manner, it is not required. You can start this exercise by opening the project file and proceeding to the steps in the following section.

Modifying the Workflow

First, modify the workflow by adding an IfElseActivity activity to determine who must approve or reject the expense report amount.

To modify the ExpenseReportWorkflow

  1. In the ExpenseReportWorkflow class, create the following private member variables.

    Type Name

    IfElseActivity

    evaluateExpenseReportAmount

    IfElseBranchActivity

    ifNeedsLeadApproval

    IfElseBranchActivity

    elseNeedsManagerApproval

    CallExternalMethodActivity

    invokeGetLeadApproval

    CallExternalMethodActivity

    invokeGetManagerApproval

    private IfElseActivity evaluateExpenseReportAmount;
    private IfElseBranchActivity ifNeedsLeadApproval;
    private IfElseBranchActivity elseNeedsManagerApproval;
    private CallExternalMethodActivity invokeGetLeadApproval;
    private CallExternalMethodActivity invokeGetManagerApproval;
    
  2. In the InitializeComponent method of the ExpenseReportWorkflow class, create an instance of each variable that you declared in the previous step.

Note   This should be done after the call that sets the CanModifyActivities property to true but before the code that sets it to false.

this.evaluateExpenseReportAmount = new IfElseActivity();
this.ifNeedsLeadApproval = new IfElseBranchActivity();
this.elseNeedsManagerApproval = new IfElseBranchActivity();
this.invokeGetLeadApproval = new CallExternalMethodActivity();
this.invokeGetManagerApproval = new CallExternalMethodActivity();
  1. After the code created in the previous step, create a local CodeCondition variable named ifElseLogicStatement.

    This object is used in the ifNeedsLeadApproval IfElseBranchActivity to verify the Amount property.

  2. After the code that you created in the previous step, create a local WorkflowParameterBinding variable named workflowparameterbinding1.

  3. After the code that you created in the previous step, create a local WorkflowParameterBinding variable named workflowparameterbinding2.

    CodeCondition ifElseLogicStatement = new CodeCondition();
    WorkflowParameterBinding workflowparameterbinding1 =
        new WorkflowParameterBinding();
    WorkflowParameterBinding workflowparameterbinding2 =
        new WorkflowParameterBinding();
    
  4. Add the ifNeedsLeadApproval object to the Activities collection of the evaluateExpenseReportAmount object by calling the Add method and passing the ifNeedsLeadApproval object as a parameter to that method.

  5. Add the elseNeedsManagerApproval object to the Activities collection of the evaluateExpenseReportAmount object by calling the Add method and passing the elseNeedsManagerApproval object as a parameter to that method.

  6. Set the Name property of the evaluateExpenseReportAmount object to the value "evaluateExpenseReportAmount".

    this.evaluateExpenseReportAmount.Activities.Add(this.ifNeedsLeadApproval);
    this.evaluateExpenseReportAmount.Activities.Add
        (this.elseNeedsManagerApproval);
    this.evaluateExpenseReportAmount.Name = "evaluateExpenseReportAmount";
    
  7. Add the invokeGetLeadApproval object to the Activities collection of the ifNeedsLeadApproval object by calling the Add method and passing the invokeGetLeadApproval object as a parameter to that method.

  8. Add a generic EventHandler named DetermineApprovalContact of the ConditionalEventArgs type to the Condition event of the ifElseLogicStatement object.

  9. Set the Condition property of the ifNeedsLeadApproval object to ifElseLogicStatement.

  10. Set the Name property of the ifNeedsLeadApproval object to the value "ifNeedsLeadApproval".

    this.ifNeedsLeadApproval.Activities.Add(this.invokeGetLeadApproval);
    ifElseLogicStatement.Condition += new
        System.EventHandler<ConditionalEventArgs>(this.DetermineApprovalContact);
    this.ifNeedsLeadApproval.Condition = ifElseLogicStatement;
    this.ifNeedsLeadApproval.Name = "ifNeedsLeadApproval";
    
  11. Add the invokeGetManagerApproval object to the Activities collection of the elseNeedsManagerApproval object by calling the Add method and passing the invokeGetManagerApproval object as a parameter to that method.

  12. Set the Name property of the elseNeedsManagerApproval object to the value "elseNeedsManagerApproval".

    this.elseNeedsManagerApproval.Activities.Add(this.invokeGetManagerApproval);
    this.elseNeedsManagerApproval.Name = "elseNeedsManagerApproval";
    
  13. Create a private method in the ExpenseReportWorkflow class named DetermineApprovalContact that accepts a Object named sender and a ConditionalEventArgs object named e as parameter.

  14. In the DetermineApprovalContact method, verify the Amount property of the workflow class.

    If that value is less than 1000, set the Result property of the ConditionalEventArgs object to true. Otherwise, set it to false.

    void DetermineApprovalContact(object sender, ConditionalEventArgs e)
    {
        if (this.reportAmount < 1000)
        {
            e.Result = true;
        }
        else
        {
            e.Result = false;
        }
    }
    

Defining the CallExternalMethod Activities

In this step, you define the corresponding CallExternalMethodActivity. The workflow uses this to call a method that is defined in the host application.

To define the CallExternalMethod activities

  1. After the code that you created in the previous procedure in the InitializeComponent method, set the InterfaceType property of the invokeGetLeadApproval object to the Type of the IExpenseReportService interface.

  2. Set the MethodName property of the invokeGetLeadApproval object to the value "GetLeadApproval".

  3. Set the Name property of the invokeGetLeadApproval object to the value "invokeGetLeadApproval".

  4. Set the ParameterName property of the workflowparameterbinding1 object to the value "message".

  5. Set the Value property of the workflowparameterbinding1 object to the value "Lead approval needed".

  6. Add the workflowparameterbinding1 object to the ParameterBindings collection of the invokeGetLeadApproval object by calling the Add method of the ParameterBindings collection and passing the workflowparameterbinding1 object as a parameter to that method.

    this.invokeGetLeadApproval.InterfaceType = typeof(IExpenseReportService);
    this.invokeGetLeadApproval.MethodName = "GetLeadApproval";
    this.invokeGetLeadApproval.Name = "invokeGetLeadApproval";
    workflowparameterbinding1.ParameterName = "message";
    workflowparameterbinding1.Value = "Lead approval needed";
    this.invokeGetLeadApproval.ParameterBindings.Add(workflowparameterbinding1);
    
  7. Set the InterfaceType property of the invokeGetManagerApproval object to the Type of the IExpenseReportService interface.

  8. Set the MethodName property of the invokeGetManagerApproval object to the value "GetManagerApproval".

  9. Set the Name property of the invokeGetManagerApproval object to the value "invokeGetManagerApproval".

  10. Set the ParameterName property of the workflowparameterbinding2 object to the value "message".

  11. Set the Value property of the workflowparameterbinding2 object to the value "Manager approval needed".

  12. Add the workflowparameterbinding2 object to the ParameterBindings collection of the invokeGetManagerApproval object by calling the Add method of the ParameterBindings collection and passing the workflowparameterbinding2 object as a parameter to that method.

    this.invokeGetManagerApproval.InterfaceType = typeof(IExpenseReportService);
    this.invokeGetManagerApproval.MethodName = "GetManagerApproval";
    this.invokeGetManagerApproval.Name = "invokeGetManagerApproval";
    workflowparameterbinding2.ParameterName = "message";
    workflowparameterbinding2.Value = "Manager approval needed";
    this.invokeGetManagerApproval.ParameterBindings.Add
        (workflowparameterbinding2);
    
  13. Add the evaluateExpenseReportAmount object to the Activities collection of the workflow by calling the Add method of the Activities collection and passing the evaluateExpenseReportAmount object as a parameter to that method.

    this.Activities.Add(this.evaluateExpenseReportAmount);
    

Defining the Interface Methods

Next, you must define the IExpenseReportService interface methods so that the user can be notified that an approval or rejection is required.

To define the IExpenseReportService interface methods

  1. In the MainForm class in the GetLeadApproval method, create an If statement to determine whether InvokeRequired is true for the approvalState Label control.

  2. If InvokeRequired is true, call the Invoke method of the approvalState Label control passing a new GetApprovalDelegate method that uses the GetLeadApproval method as a parameter and the message parameter.

  3. If InvokeRequired is false, set the Text property of the approvalState Label control equal to the message parameter.

  4. Set the Enabled property of the approveButton and rejectButton Button controls to true and the submitButton Button control to false.

  5. Increase the Height of the form by adding the Height of the panel1 control to the Height property of the form.

    public void GetLeadApproval(string message)
    {
        if (this.approvalState.InvokeRequired)
            this.approvalState.Invoke(new GetApprovalDelegate
                (this.GetLeadApproval), message);
        else
        {
            this.approvalState.Text = message;
            this.approveButton.Enabled = true;
            this.rejectButton.Enabled = true;
    
            // expand the panel
            this.Height = this.MinimumSize.Height + this.panel1.Height;
            this.submitButton.Enabled = false;
        }
    }
    
  6. In the MainForm class in the GetManagerApproval method, create an If statement to determine whether InvokeRequired is true for the approvalState Label control.

  7. If InvokeRequired is true, call the Invoke method of the approvalState Label control passing a new GetApprovalDelegate method that uses the GetManagerApproval method as a parameter and the message parameter.

  8. If InvokeRequired is false, set the Text property of the approvalState Label control equal to the message parameter.

  9. Set the Enabled property of the approveButton and rejectButton Button controls to true and the submitButton Button control to false.

  10. Increase the Height of the form by adding the Height of the panel1 control to the MinimumSize.Height property of the form.

    public void GetManagerApproval(string message)
    {
        if (this.approvalState.InvokeRequired)
            this.approvalState.Invoke(new GetApprovalDelegate
                (this.GetManagerApproval), message);
        else
        {
            this.approvalState.Text = message;
            this.approveButton.Enabled = true;
            this.rejectButton.Enabled = true;
    
            // expand the panel
            this.Height = this.MinimumSize.Height + this.panel1.Height;
            this.submitButton.Enabled = false;
        }
    }
    
  11. Build and run the application.

  12. Enter a value in the Amount text box and then click Submit.

    The form should expand to display the Approve and Reject buttons and the message generated by the workflow.

Output from Task 1

Compiling the Code

For information about compiling your code, see Compiling the Code.

In Task 2: Create the HandleExternalEvent Activities, you complete the tutorial by adding activities to listen for specific events that are raised by the host application.

See Also

Reference

Activities
IfElseActivity
IfElseBranchActivity
CallExternalMethodActivity
InterfaceType
MethodName
ParameterName
ParameterBindings

Concepts

Using the CallExternalMethodActivity Activity
Using the IfElseActivity Activity

Other Resources

Task 2: Create the HandleExternalEvent Activities
Communications

Copyright © 2007 by Microsoft Corporation. All rights reserved.
Last Published: 2010-03-04