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
In the ExpenseReportWorkflow class, create the following private member variables.
Type Name IfElseActivity
evaluateExpenseReportAmount
ifNeedsLeadApproval
IfElseBranchActivity
elseNeedsManagerApproval
CallExternalMethodActivity
invokeGetLeadApproval
CallExternalMethodActivity
invokeGetManagerApproval
private IfElseActivity evaluateExpenseReportAmount; private IfElseBranchActivity ifNeedsLeadApproval; private IfElseBranchActivity elseNeedsManagerApproval; private CallExternalMethodActivity invokeGetLeadApproval; private CallExternalMethodActivity invokeGetManagerApproval;
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();
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.
After the code that you created in the previous step, create a local WorkflowParameterBinding variable named workflowparameterbinding1.
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();
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.
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.
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";
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.
Add a generic EventHandler named DetermineApprovalContact of the ConditionalEventArgs type to the Condition event of the ifElseLogicStatement object.
Set the Condition property of the ifNeedsLeadApproval object to ifElseLogicStatement.
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";
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.
Set the Name property of the elseNeedsManagerApproval object to the value "elseNeedsManagerApproval".
this.elseNeedsManagerApproval.Activities.Add(this.invokeGetManagerApproval); this.elseNeedsManagerApproval.Name = "elseNeedsManagerApproval";
Create a private method in the ExpenseReportWorkflow class named DetermineApprovalContact that accepts a Object named sender and a ConditionalEventArgs object named e as parameter.
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
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.
Set the MethodName property of the invokeGetLeadApproval object to the value "GetLeadApproval".
Set the Name property of the invokeGetLeadApproval object to the value "invokeGetLeadApproval".
Set the ParameterName property of the workflowparameterbinding1 object to the value "message".
Set the Value property of the workflowparameterbinding1 object to the value "Lead approval needed".
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);
Set the InterfaceType property of the invokeGetManagerApproval object to the Type of the IExpenseReportService interface.
Set the MethodName property of the invokeGetManagerApproval object to the value "GetManagerApproval".
Set the Name property of the invokeGetManagerApproval object to the value "invokeGetManagerApproval".
Set the ParameterName property of the workflowparameterbinding2 object to the value "message".
Set the Value property of the workflowparameterbinding2 object to the value "Manager approval needed".
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);
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
In the MainForm class in the GetLeadApproval method, create an If statement to determine whether InvokeRequired is true for the approvalState Label control.
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.
If InvokeRequired is false, set the Text property of the approvalState Label control equal to the message parameter.
Set the Enabled property of the approveButton and rejectButton Button controls to true and the submitButton Button control to false.
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; } }
In the MainForm class in the GetManagerApproval method, create an If statement to determine whether InvokeRequired is true for the approvalState Label control.
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.
If InvokeRequired is false, set the Text property of the approvalState Label control equal to the message parameter.
Set the Enabled property of the approveButton and rejectButton Button controls to true and the submitButton Button control to false.
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; } }
Build and run the application.
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.
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