Creating Custom Activities in Windows Workflow

There are two main types of custom activity: a custom activity that encapsulates a discrete task and a custom composite activity that groups a collection of lower-level activities into a higher-level activity.

A custom activity inherits directly or indirectly from the Activity class; a custom composite activity inherits directly or indirectly from the CompositeActivity class. You can annotate an Activity class with attributes that describe various design-time and run-time characteristics of the activity.

Activity Type



You use custom activities to implement distinct tasks in a single reusable activity such as an activity to send an e-mail message to a user. You can define the To and From address, in addition to the mail server to use as properties of the activity, and then implement logic to send the e-mail message in the Execute method for the activity.

Custom composite

You use custom composite activities to encapsulate reusable sequences of activities. This enables you to define a sequence of activities once and then distribute the custom composite activity throughout your workflow implementation. This reduces development time in your application.

You define activity classes by creating a Workflow Activity Library project in Visual Studio.

Defining Properties in a Custom Activity

When you design custom activities, there are three types of property at your disposal: instance properties, which apply to each instance of the activity and can be changed at run time; meta properties, which apply to all instances of the activity and are usually used to describe something in the activity itself; and dependency properties, which enable other activities in the workflow to access and work with properties in your activity

Property Types

Instance properties are modifiable at run time. You can assign a literal value at design time or you can bind the property to instance data in the workflow that contains the activity. You can also modify the value of the property directly during workflow execution.

You can implement an instance property in the same way as you implement a normal .NET Framework property or you can implement it as a dependency property.

There are several property attributes that you use to define the property behaviors.

Meta properties are immutable at run time. You must assign a literal value at design time. Meta properties relate to activities in the same way that attributes relate to classes in the .NET Framework.

For example, System.Workflow.ComponentModel.Activity.Name is a string that represents the activity name, is metadata, and is set at design time and embedded in the compiled workflow so that it cannot be changed.

When you define an activity class, you typically define most of its properties as dependency properties rather than instance properties or meta properties. Dependency properties provide a centralized repository of the state of a workflow, which is accessible from any activities in the workflow. The Activity class inherits from DependencyObject, which means that all activities inherit the capability to get and set dependency properties in a workflow. You can bind dependency properties to available values in the workflow, such as workflow fields, properties, and methods, and to other activity property values

WF provides several attributes that you can use to annotate a property in an activity. For example, you can use the Browsable attribute to specify that the property should appear in the Visual Studio Properties window.

The following code examples show how to define an instance property that is named ToAddress for the SendEmailActivity class. The ToAddress property specifies the e-mail address for the recipient of the e-mail message. The property is annotated with attributes that provide Visual Studio with information that describes how to display the property in the Properties window.

[Visual C#]

        private string _toAddress;





        [Description("Please specify the e-mail address of the recipient.")]

        [Category("E-mail message")]

        public string ToAddress


            get { return toAddress; }

            set { toAddress = value; }




   [Visual Basic]

    Private _toAddress As String


    <DesignerSerializationVisibility( _

        DesignerSerializationVisibility.Visible)> _

    <Browsable(True)> _

    <Description("Please specify the e-mail address of the recipient.")> _

    <Category("E-mail message")> _

    Public Property ToAddress() As String


            Return _toAddress

        End Get


        Set(ByVal value As String)

            _toAddress = value

        End Set

    End Property


The following code examples show how to define a dependency property that is named FromAddress for the SendEmailActivity class. The FromAddress property specifies the e-mail address for the sender of the e-mail message. The property is a string and has a default value of


Visual Basic

    Public Shared FromAddressProperty As DependencyProperty = _

    DependencyProperty.Register( _

                          "FromAddress", _

                           GetType(String), _

                           GetType(SendEmailActivity), _

                           New PropertyMetadata(