Task 2: Create the HandleExternalEvent Activities
At this point, the workflow has done the following:
Received one parameter from the host application.
Evaluated the Amount parameter to determine which party is responsible for approving or rejecting the expense report.
Notified the host application that approval is needed before it continues.
In this task, you use the ListenActivity activity, together with the HandleExternalEventActivity activities, to listen for specific events that the host application raises. When an approval or rejection event is raised, the workflow continues, sets the result, and then finishes.
Each branch of a ListenActivity activity is an EventDrivenActivity. The first activity of the composite EventDrivenActivity must be an activity that implements the IEventActivity interface. The HandleExternalEventActivity activity is used in each EventDrivenActivity branch of the ListenActivity to listen for the ExpenseReportApproved event or the ExpenseReportRejected event raised by the host application.
Note
Although you are encouraged to follow the exercises in a linear manner, it is not required. You can start on this exercise by opening the sample solution and proceeding to the steps in the following procedure.
Modifying the ExpenseReportWorkflow
In this step, you must modify the workflow so that it can listen for specific events that the host application raises.
To modify the ExpenseReportWorkflow
In the ExpenseReportWorkflow class, create a new method named approveEvent_Invoked that accepts a Object named sender and an ExternalDataEventArgs named e as parameters.
In the approveEvent_Invoked method, set the reportResult member field equal to the string value "Report Approved".
void approveEvent_Invoked(object sender, ExternalDataEventArgs e) { this.reportResult = "Report Approved"; }
In the ExpenseReportWorkflow class, create a new method named rejectEvent_Invoked that accepts a Object named sender and an ExternalDataEventArgs named e as parameters.
In the rejectEvent_Invoked method, set the reportResult member field equal to the string value "Report Rejected".
private void rejectEvent_Invoked(object sender, ExternalDataEventArgs e) { this.reportResult = "Report Rejected"; }
In the ExpenseReportWorkflow class, create the following private fields.
Type Name ListenActivity
listenApproveReject
EventDrivenActivity
eventDriven1
EventDrivenActivity
eventDriven2
HandleExternalEventActivity
approveEvent
HandleExternalEventActivity
rejectEvent
private ListenActivity listenApproveReject; private EventDrivenActivity eventDriven1; private EventDrivenActivity eventDriven2; private HandleExternalEventActivity approveEvent; private HandleExternalEventActivity rejectEvent;
In the InitializeComponent method, create an instance of each field that is declared in the previous step.
This must be done after the line that sets the CanModifyActivities to true.
this.eventDriven1 = new EventDrivenActivity(); this.eventDriven2 = new EventDrivenActivity(); this.listenApproveReject = new ListenActivity(); this.approveEvent = new HandleExternalEventActivity(); this.rejectEvent = new HandleExternalEventActivity();
Following the line that set the ParameterBindings of the invokeGetManagerApproval object in the InitializeComponent method, add the approveEvent object to the Activities collection of the eventDriven1 object by using the Add method, and passing the approveEvent object as a parameter to that method.
Set the Name property of the eventDriven1 object to the value "eventDriven1".
this.eventDriven1.Activities.Add(this.approveEvent); this.eventDriven1.Name = "eventDriven1";
Add the rejectEvent object to the Activities collection of the eventDriven2 object by using the Add method and passing the rejectEvent object as a parameter to that method.
Set the Name property of the eventDriven2 object to the value "eventDriven2".
this.eventDriven2.Activities.Add(this.rejectEvent); this.eventDriven2.Name = "eventDriven2";
Add the eventDriven1 object to the Activities collection of the listenApproveReject object by using the Add method, and passing the eventDriven1 object as a parameter to that method.
Add the eventDriven2 object to the Activities collection of the listenApproveReject object by using the Add method, and passing the eventDriven2 object as a parameter to that method.
Set the Name property of the listenApproveReject object to the value "listenApproveReject".
this.listenApproveReject.Activities.Add(this.eventDriven1); this.listenApproveReject.Activities.Add(this.eventDriven2); this.listenApproveReject.Name = "listenApproveReject";
Set the EventName property for the approveEvent object to the value "ExpenseReportApproved".
Set the InterfaceType property of the approveEvent object to the System.Type of the IExpenseReportService.
Set the Name property of the approveEvent object to the value "approveEvent".
Add a generic EventHandler of the ExternalDataEventArgs type named approveEvent_Invoked to the Invoked event that is raised by the approveEvent object.
this.approveEvent.EventName = "ExpenseReportApproved"; this.approveEvent.InterfaceType = typeof(IExpenseReportService); this.approveEvent.Name = "approveEvent"; this.approveEvent.Invoked += new System.EventHandler<ExternalDataEventArgs>(this.approveEvent_Invoked);
Set the EventName property for the rejectEvent object to the value "ExpenseReportRejected".
Set the InterfaceType property of the rejectEvent object to the System.Type of the IExpenseReportService.
Set the Name property of the rejectEvent object to the value "rejectEvent".
Add a generic EventHandler of the ExternalDataEventArgs type named rejectEvent_Invoked to the Invoked event that is raised by the rejectEvent object.
this.rejectEvent.EventName = "ExpenseReportRejected"; this.rejectEvent.InterfaceType = typeof(IExpenseReportService); this.rejectEvent.Name = "rejectEvent"; this.rejectEvent.Invoked += new System.EventHandler<ExternalDataEventArgs>(this.rejectEvent_Invoked);
Add the listenApproveReject object to the Activities collection of the workflow.
Make sure that you add this object after the line that adds the evaluateExpenseReportAmount object.
this.Activities.Add(this.evaluateExpenseReportAmount); this.Activities.Add(this.listenApproveReject); this.Name = "ExpenseReportWorkflow"; this.CanModifyActivities = false;
Raising the Event from the Host Application
To raise the event from the host application
In the approveButton_Click method of the MainForm class, raise the ExpenseReportApproved event, passing null (Nothing in Visual Basic) and a new ExternalDataEventArgs object that is initialized with the workflowInstance InstanceId as parameters.
Set the Height property of the form equal to the MinimumSize.Height property.
Set the Enabled property of the submitButton Button control to true.
private void approveButton_Click(object sender, EventArgs e) { // Raise the ExpenseReportApproved event back to the workflow reportApproved(null, new ExternalDataEventArgs (this.workflowInstance.InstanceId)); this.Height = this.MinimumSize.Height; this.submitButton.Enabled = true; }
In the rejectButton_Click method of the MainForm class, raise the ExpenseReportRejected event, passing null (Nothing in Visual Basic) and a new ExternalDataEventArgs object that is initialized with the workflowInstance InstanceId as parameters.
Set the Height property of the form equal to the MinimumSize.Height property.
Set the Enabled property of the submitButton Button control to true.
private void rejectButton_Click(object sender, EventArgs e) { // Raise the ExpenseReportRejected event back to the workflow reportRejected(null, new ExternalDataEventArgs (this.workflowInstance.InstanceId)); this.Height = this.MinimumSize.Height; this.submitButton.Enabled = true; }
Build and run the application.
When you submit an expense report amount, the form expands to show the Approve and Reject buttons and a message that is received from the workflow. Clicking one of the buttons does the following:
Collapses the form.
Raises an event back to the workflow.
Retrieves the Results property from the workflow.
Displays it on the form.
Compiling the Code
For information about compiling your code, see Compiling the Code.
For a finished version of the tutorial, see Completed Sequential Workflow Tutorial.
See Also
Reference
ListenActivity
EventDrivenActivity
IEventActivity
CallExternalMethodActivity
HandleExternalEventActivity
ExternalDataEventArgs
Copyright © 2007 by Microsoft Corporation. All rights reserved.
Last Published: 2010-03-04