MSBICENTRAL
Windows Workflow Foundation
Bayer White
WF Activities Part I – Practical Use of HandleExternalEvent, IfElse & CallExternalMethod Activities
Building an Interview Workflow
This is the first article of a series of articles that I will be writing to demonstrate how to use out of the box activities that come with WF. In this example, I will show you how WF can be used to build a workflow that will handle an interviewing process. This is example is somewhat impractical because the person is only hired if they live in a certain zip code, however the example does a good job of showing how to wire up each of the activities discussed to make the selection.
Task 1 – Create a new Workflow Project
1. Open Visual Studio 2005 by going to the Start Menu | Programs | Microsoft Visual Studio 2005 | Microsoft Visual Studio 2005
2. In Visual Studio 2005, select the File | New | Project menu command.
3. Visual Studio 2005 will display the New Project dialog window.
4. In the New Project dialog window, expand Visual C# | Workflow in the Project Types tree on the left side.
5. Select the template named “Empty Workflow Project” and enter the following values:
Name: EmptyWFProject
Location: C:\Windows Workflow Foundation\ Using WF Activities

6. Right click on the EmptyWFProject project in Solution Explorer and select Add | New Item from the context menu.
In the Add New Item dialog window, select the item template named Sequential Workflow (with code separation) and click the Add button to add the new workflow to the EmptyWFProject project.

7. The new Sequential Workflow project will now contain two files: Workflow1.xoml and Workflow1.xoml.cs. Workflow1.xoml contains the XML markup that represents the workflow type. Workflow1.xoml.cs contains the code-beside class for the workflow.

Task 2 – Add a HandleExternalEvent Activity
1. Double click on the Workflow1.xoml file in Solution Explorer to open the Visual Studio workflow designer.
2. In the workflow designer, select the View | Toolbox menu command to display the toolbox with available activities.
3. You may need to expand the Windows Workflow category in the toolbox to view the Windows Workflow Foundation activities.

4. The red circle and dropdown arrow indicate that there are some issues with the activity. When we click on the down arrow we can see that we need to set some settings.

5. The EventName and InterfaceType properties need to be set for this activity. This activity is triggered by an event that is supported by an interface. Code must be written that also supports this interface so that the event is called when a certain action takes place. In our example, this activity will be triggered once the information has been entered into the system for the person interviewing. This activity will kick off our workflow.
6. Next we want to add the project that will host our workflow. If you need some background on how WF works, use the following posts as a reference.
7. The EventName and InterfaceType properties need to be set for this activity. This activity is triggered by an event that is supported by an interface. Code must be written that also supports this interface so that the event is called when a certain action takes place. In our example, this activity will be triggered once the information has been entered into the system for the person interviewing. This activity will kick off our workflow.
8. Let’s add an Existing Project that will host our workflow and also pass information to the workflow through an event.
9. Go to “Downloads” on MSBICentral for Workflow Foundation Examples and download “WF Activities Part I Host Example” and “WF Activities Part I Interview Bus Obj”.
10. After these example is downloaded, Right-click on the EmptyWFProject Solution and add these projects.

Scan through the code and see how the workflow is hosted and what information is being past to the workflow. Now that we have the host, let’s configure our “HandleExternalEvent” activity that we added to the workflow earlier. There are five properties for the activity that we want to setup.
- (Name) - Descriptive name for our activity
- EventName - Event that will activate this activity
- InterfaceType - Interface that the activity will support
- Invoked - Method that will be called from the activity once it is activated
- (Parameter) e - Parameter information that is passed to the workflow
To make sure we are able to add the parameter property lets add some code to our workflow.
1. Expand the Solution Explorer double click on the Workflow.xoml.cs.
2. Add the following code…
private string _personName = string.Empty;
public Interview.PersonArgs personArgs =
default(Interview.PersonArgs);
public string PersonName
{
get { return _personName; }
set { _personName = value; }
}
private int _zip = -1;
public int Zip
{
get { return _zip; }
set { _zip = value; }
}

3. Now lets make some references between the projects
4. Add a reference to the EmptyWFProject and WindowApplication1 project with the assembly from the Person project.
5. Add a reference to WindowApplication1 project with the assembly from the EmptyWFProject. This will allow the Host application start the workflow. Now we can setup the properties for the activity.
6. Click on the property, InterfaceType and then press the button to browse for the interface to support.

7. Enter “Interview_Invoked” for the Invoked property

After adding a value for the Invoked property, you are immediately taken the stubbed code to add logic for the event. Add the following code so that the workflow can get the values passed in from the host “WindowApplication1”
private void Interview_Invoked(object sender, ExternalDataEventArgs e)
{
PersonName = personArgs.Name;
Zip = personArgs.Zip;
}
1. Let’s make sure that everything is working so far by compiling our solution
2. Next setup the “WindowsApplication1” as the “Start External Program” for the EmptyWFProject project. When the Solution is run, the EmptyWFProject should be the startup project for the solution and will run the WindowApplication1 host.

Now that we have a starter point for the workflow that will be kicked off from our host application, we want to add in the logic for determining if we want to hire the person that was interviewed. Again, for this example all I am doing is hiring the person if their zip code falls between two values. At this time, your workflow should look like the example below.

Let’s now add an IfElse activity that will be used to determine if we can hire the person interviewed.
1. In our toolbox, there is an activity called, IfElse that we need to select, and then drag and drop on to our workflow just under our InterviewedPerson activity

2. Click on ifElseBranchActivity1 and in the properties, change the (Name) property to “Hired”.
3. Dropdown the Condition property and select System.Workflow.Activities.Rules.RuleConditionReference

4. Expand the Condition property and enter “ValidateZip” for the ConditionName. If there were already Conditions create, then they would be available through the dropdown.
6. Select the button for the Expression property.
7. The following condition editor appears. Add the following code for the condition.
8. this.Zip > 32209 && this.Zip < 32240

The above code uses the workflow property, Zip that was set by the HandleExternalEvent activity we created earlier and compares for valid zip codes.

Now that we have the logic in place for handling zip codes, let’s also rename the ifElseBranchActivity2 to “NotHired” so it is more meaningful. Since we only care if the zip of the person interviewed falls between 32209 and 32240 we do not need to add logic for the ifElseBranchActivity2 branch. Now if the zip is between 32209 and 32240 we hire and anything else we do not. Our workflow now needs to invoke the code to hire or not. If you look back at our Person class (Person.cs), it supports an interface that contains the methods to process this functionality.
void IInterview.HirePerson(string PersonName)
{
this.Salary = 70000;
}
void IInterview.NotHired(string PersonName)
{
this.Comments = "Not company material";
}
To make the call to our class we can use the CallExternalMethod activity. This activity can be wired to support an interface and call a particular method within an object that supports the same interface.
1. In the toolbox, click on the CallExternalMethod activity and drag and drop it on to the workflow within the Hired branch of the IfElse activity

2. Click on the CallExternalMethod activity and then change the property (Name) to “HirePerson”
3. Click on the property, InterfaceType and then press the button to browse for the interface to support. Just like we setup the HandleExternalEvent activity, choose the interface IInterview.

4. After selecting the interface, a method that is supported by interface can be selected by pressing the button for the MethodName property. Choose the “HirePerson” method.

5. Notice that the HiredPerson method requires a string PersonName to be passed in. For the Parameter property select the Workflow1.PersonName property that we created earlier for the workflow.

The properties the activity should like the following

6. Repeat steps 1 through 4 except this time do this…
- Add the activity by dropping it on the NotHired branch of the IfElse
- Change the property (Name) of the activity to “RejectPerson”
- Once the interface has been selected, choose “NotHired” for the MethodName property.
You should now have a functional workflow. You can right-click on the InterviewedPerson activity and set a breakpoint so that you can follow the code that is being run. Run the workflow

1. First thing that should happen is your windows application should load. Press “Start Interview” to start the WF Runtime.

Here I have entered my name and a zip that I know is a winner for getting hired. You could also enter in a zip value of ‘32209’ to see when the workflow decides not to hire a person. To step through the workflow, you can select the InterviewedPerson activity and then right-click for a menu to set a breakpoint.