Building a Custom Activity in Windows Workflow Foundation

Activities are the building blocks of Windows Workflow Foundation (WF) workflows. They represent the basic steps within a workflow, which is constructed as a tree of activities. Activities make up the individual units of execution, and they allow for re-use. You can compose a solution by assembling activities, which themselves can be compositions of more than one activity. There are two types of WF activity: basic and composite. A basic activity is custom coded to provide its function set. A composite activity is built out of other existing activities.

A WF base activity library provides out-of-the-box activities, but you also can write custom activities or obtain them from third-party sources. The following are some common activities included in the activity library:

  • Code: Executes the associated code
  • Delay: Delays execution of the workflow for a specified duration
  • IfElse: Executes different activities based on the condition
  • InvokeWebService: Invokes a web service call from within a workflow
  • Suspend: Suspends execution of the workflow
  • Terminate: Terminates execution of the workflow
  • While: Executes associated activities as long as the condition is true, where the condition can be based on declarative rules set at design time or based on code

As you can see, some powerful capabilities are available by default. You can use any of these to arrange a workflow. Along with being rules driven, activities can support transactions and sequential control. The activities' declarative rules support is very powerful because it allows you to alter or change the logic without recompiling code.

Custom Activities

WF is a very powerful framework for building workflow-enabled applications, but its existing out-of-the-box activities likely won't enable you to accomplish everything you want. That's where custom activities come in. Rather than just embedding code, you can model custom application logic as activities in WF solutions and use it to encapsulate reusable business logic. This ensures that you stay within the WF execution model, as well as helping to ensure visibility and control of workflow solutions. It also is essential for the ability to provide dynamic updates.

A specific activity component model controls building custom activities. Each activity has a set of associated components. You associate the components with the activity by using attributes on the activity definition. If a particular component is not specified, then the parent's attributes are applied instead. The components are:

  • Designer: Controls the visible aspects of the activity within the workflow designer
  • Validator: Used at design time, provides hints and information to the user (such as when mandatory properties have not been defined)
  • Serializer
  • Code Generator

One of the properties that you can control in your custom activity is the base class. A number of types are available, including the following:

  • System.Workflow.Activities.CallExternalMethodActivity
  • System.Workflow.Activities.HandleExternalMedthodActivity
  • System.Workflow.Activities.SequenceActivity
  • System.Workflow.Activities.SequentialWorkflowActivity
  • System.Workflow.Activities.StateActivity
  • System.Workflow.Activities.StateMachineWorkflowActivity
  • System.Workflow.ComponentModel.Activity
  • System.Workflow.ComponentModel.CompositeActivity

System.Workflow.Activities.SequenceActivity is the default activity type.

Building a Custom Activity

The following components are required to build the examples in this article:

I downloaded them and set up a .NET Framework 3.0 Virtual PC environment. I've found this to be a good practice for trying out new things without the risk of messing up my current environment and while preserving various environments. It is especially handy when you intermittently need to support a particular environment that is outside your normal development.

The example is a "Hello World!" sequential activity similar to the one built in "Get Ready for Windows Workflow Foundation." In this case, you'll turn the prior sequential workflow into a composite activity that you can use in its entirety. To begin, use the following steps to create a sequential workflow within Visual Studio 2005:

  1. Create a new project. This example uses C#, Workflow, Sequential Workflow Console Application as the project type.
  2. When you create the workflow project, it will use the workflow definition and code in the same file by default. I deleted it and added a new item Sequential Workflow (with code separation) and named it HelloWorkflow.xoml.
  3. Create another new project to add to the solution. This example uses C#, Workflow, Workflow Activity Library as the project type. I chose to name the project HelloWorldActivityLibrary.
  4. When you create the activity library project, it will use the activity definition and code in the same file by default. I deleted it and added a new item Activity (with code separation) and named it HelloWorldActivity.xoml.
  5. Add a property of bool type to the code behind file. Set the default value for the property to false. I chose to name the property IsTrue.
  6. Drag an IfElse activity to the top of the workflow designer.
  7. In the toolbox, you will find a Windows Workflow group. Drag a code activity onto the Sequential Workflow designer in the IfElse activity. I named my activity helloActivity.
  8. A Smart Tag on the control will indicate the property ExecuteCode is not set. The ExecuteCode property specifies the name of the code method that will be invoked by the runtime. Set the property as the name of what you called your activity followed by _ExecuteCode. I used helloActivity_ExecuteCode.
  9. Add Console.WriteLine("Hello World!"); to the event handler that was added. Additionally, add Console.ReadLine(); to the event handler.
  10. Add a terminate activity to the right branch of the IfElse activity.
  11. Use the Smart Tag on the ifElseBranchActivity1 to set a declarative rule condition. This will allow you to use the designer to set the logic condition to use. You should use the expression this.IsTrue == true, which will base the condition on the IsTrue property of the sequential workflow.
  12. Build the HelloWorldActivityLibrary project. Figure 1 shows a diagram of the completed composite activity.
  13. Figure 1. Diagram of the Completed Composite Activity

  14. Return to the HelloWorkflow in the console project. In your toolbox in Visual Studio, you will now notice an additional tab called HelloWorldActivityLibrary, which contains the HelloWorldActivity. Drag an instance of the HelloWorldActivity onto the designer.
  15. Set a breakpoint in the workflow designer on the IfElse activity by right-clicking it and choosing Breakpoint > Insert Breakpoint. Build and execute your project in debug mode. You'll notice that the "Hello World!" will be skipped because your condition is set to false by default.
  16. You've exposed IsTrue as a property on your custom activity. If you go back to the design view for the HelloWorkflow and go to the properties on the HelloWorldActivity you added, you'll see the IsTrue property. Change the value to true and rebuild and execute the project. You'll notice that this time the condition will be true and "Hello World!" will be displayed to the console.

Here is a copy of the code that my project created. You should see a Program.cs that contains the main execution point for the console application and contains auto-generated code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;

namespace HelloWorldWorkflow
   class Program
      static void Main(string[] args)
         using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
            AutoResetEvent waitHandle = new AutoResetEvent(false);
            workflowRuntime.WorkflowCompleted += delegate(object sender,
               WorkflowCompletedEventArgs e) {waitHandle.Set();};
            workflowRuntime.WorkflowTerminated += delegate(object sender,
               WorkflowTerminatedEventArgs e)

            WorkflowInstance instance =


Building a Custom Activity in Windows Workflow Foundation

Here is the code from the HelloWorldActivity.xoml.cs code-behind file:

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;

namespace HelloWorldActivityLibrary
   public partial class HelloWorldActivity : SequenceActivity
      private bool isTrue = false;
      public bool IsTrue
         get { return this.isTrue; }
         set { this.isTrue = value; }

      private void helloActivity_ExecuteCode(object sender, EventArgs e)
         Console.Write("Hello World!");

Although this is a fairly simple example, it gives you an idea of how to build a sequential workflow. You could expand the example to use the IfElse activity to display the "Hello World!" text based on various languages, or you could just further explore other activities.

Other Considerations

Here are a few additional items about custom activities that you may find beneficial:

  • Get in the habit of including only basic accessor get and set functionality in your properties, and do not include code in the constructor either. I've been told this will help you avoid issues when using SharePoint and WF together.
  • When building custom activities, ensure that your custom activity goes through a dehydration cycle during testing to ensure it behaves properly.
  • Building a basic activity (pure custom code) isn't really that much different from building a composite. You have more items, such as the component model, to consider, but for the most part the steps are the same.
  • Depending on the purpose of your activity, you may want to further explore the ToolboxItem, Designer, Theme, and Validator classes to enrich the developer experience when using your custom activity.

Custom Logic For Workflows

Custom activities that contain custom logic for workflows ensure that the logic operates within the workflow model and allow transparency and dynamic update. Hopefully, this tutorial got you started on building your own custom activities and prepared you to continue building more.

Future Columns

The topic of the next column is yet to be determined. It will likely cover either state machine workflow or building rules-based workflows using WF. However, if you have something in particular that you would like to see explained here, you could reach me at

About the Author

Mark Strawmyer (MCSD, MCSE, MCDBA) is a senior architect of .NET applications for large and mid-size organizations. Mark is a technology leader with Crowe Chizek in Indianapolis, Indiana. He specializes in architecture, design, and development of Microsoft-based solutions. Mark was honored to be named a Microsoft MVP for application development with C# for the fourth year in a row. You can reach Mark at

About the Author

Mark Strawmyer

Mark Strawmyer is a Senior Architect of .NET applications for large and mid-size organizations. He specializes in architecture, design and development of Microsoft-based solutions. Mark was honored to be named a Microsoft MVP for application development with C# for the fifth year in a row. You can reach Mark at


  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Moving from an on-premises environment to Office 365 does not remove the need to plan for disruptions or reduce the business risk requirements for protecting email services. If anything, some risks increase with a move to the cloud. Read how to ease the transition every business faces if considering or already migrating to cloud email. This white paper discusses: Setting expectations when migrating to Office 365 Understanding the implications of relying solely on Exchange Online security Necessary archiving …

  • Complex hybrid environments can make it difficult to track interdependencies, increasing the risk of disrupting critical business services. In this white paper by EMA, you'll learn how application discovery and dependency mapping can help you: Meet granular targets for availability, cost, and time-to-revenue for cloud services. Accelerate mean time to repair (MTTR) while communicating better with stakeholders. Manage even the most complex hybrid environments more efficiently and effectively Understand the …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date