How to: Create an Activity

This topic applies to Windows Workflow Foundation 4 (WF4).

Activities are the core unit of behavior in WF. An activity’s execution logic can be implemented in managed code or it can be implemented by using other activities. This topic demonstrates how to create a simple activity by using code to implement its execution logic and an activity whose implementation is defined by using other activities. These activities are used in the following topics, How to: Create a Workflow and How to: Run a Workflow.

Note

To view a video walkthrough of this topic or to download a completed version of the tutorial, see Windows Workflow Foundation (WF4) - Getting Started Tutorial.

To create the activity library project

  1. Open Visual Studio 2010 and choose New, Project from the File menu.

  2. Expand the Other Project Types node in the Installed Templates list and select Visual Studio Solutions.

  3. Select Blank Solution from the Visual Studio Solutions list. Ensure that .NET Framework 4 is selected in the .NET Framework version drop-down list. Type GettingStartedTutorial in the Name box and then click OK.

  4. Right-click GettingStartedTutorial in Solution Explorer and choose Add, New Project.

    Dd489453.Tip(en-us,VS.100).gifTip:
    If the Solution Explorer window is not displayed, select Solution Explorer from the View menu.

  5. In the Installed Templates list, select Visual C#, Workflow (or Visual Basic, Workflow). Ensure that .NET Framework 4 is selected in the .NET Framework version drop-down list. Select Activity Library from the Workflow list. Keep the default settings and then click OK.

    Note

    Depending on which programming language is configured as the primary language in Visual Studio, the Visual C# or Visual Basic node may be under the Other Languages node in the Installed Templates list.

  6. Right-click Activity1.xaml in Solution Explorer and select Delete. Click OK to confirm.

To create the ReadInt activity

  1. Choose Add New Item from the Project menu.

  2. In the Installed Templates list, select Workflow. Select Code Activity from the Workflow list.

  3. Type ReadInt into the Name box and then click Add.

  4. Replace the existing ReadInt definition with the following definition.

    Public NotInheritable Class ReadInt
        Inherits NativeActivity(Of Integer)
    
        <RequiredArgument()>
        Property BookmarkName() As InArgument(Of String)
    
        Protected Overrides Sub Execute(ByVal context As NativeActivityContext)
            Dim name As String
            name = BookmarkName.Get(context)
    
            If name = String.Empty Then
                Throw New ArgumentException("BookmarkName cannot be an Empty string.",
                    "BookmarkName")
            End If
    
            context.CreateBookmark(name, New BookmarkCallback(AddressOf OnReadComplete))
        End Sub
    
        ' NativeActivity derived activities that do asynchronous operations by calling 
        ' one of the CreateBookmark overloads defined on System.Activities.NativeActivityContext 
        ' must override the CanInduceIdle property and return True.
        Protected Overrides ReadOnly Property CanInduceIdle As Boolean
            Get
                Return True
            End Get
        End Property
    
        Sub OnReadComplete(ByVal context As NativeActivityContext, ByVal bookmark As Bookmark, ByVal state As Object)
            Result.Set(context, Convert.ToInt32(state))
        End Sub
    
    End Class
    
    public sealed class ReadInt : NativeActivity<int>
    {
        [RequiredArgument]
        public InArgument<string> BookmarkName { get; set; }
    
        protected override void Execute(NativeActivityContext context)
        {
            string name = BookmarkName.Get(context);
    
            if (name == string.Empty)
            {
                throw new ArgumentException("BookmarkName cannot be an Empty string.",
                    "BookmarkName");
            }
    
            context.CreateBookmark(name, new BookmarkCallback(OnReadComplete));
        }
    
        // NativeActivity derived activities that do asynchronous operations by calling 
        // one of the CreateBookmark overloads defined on System.Activities.NativeActivityContext 
        // must override the CanInduceIdle property and return true.
        protected override bool CanInduceIdle
        {
            get { return true; }
        }
    
        void OnReadComplete(NativeActivityContext context, Bookmark bookmark, object state)
        {
            this.Result.Set(context, Convert.ToInt32(state));
        }
    }
    
    public sealed class ReadInt : NativeActivity<int>
    {
        [RequiredArgument]
        public InArgument<string> BookmarkName { get; set; }
    
        protected override void Execute(NativeActivityContext context)
        {
            string name = BookmarkName.Get(context);
    
            if (name == string.Empty)
            {
                throw new ArgumentException("BookmarkName cannot be an Empty string.",
                    "BookmarkName");
            }
    
            context.CreateBookmark(name, new BookmarkCallback(OnReadComplete));
        }
    
        // NativeActivity derived activities that do asynchronous operations by calling 
        // one of the CreateBookmark overloads defined on System.Activities.NativeActivityContext 
        // must override the CanInduceIdle property and return true.
        protected override bool CanInduceIdle
        {
            get { return true; }
        }
    
        void OnReadComplete(NativeActivityContext context, Bookmark bookmark, object state)
        {
            this.Result.Set(context, Convert.ToInt32(state));
        }
    }
    

    Note

    The ReadInt activity derives from NativeActivity instead of CodeActivity, which is the default for a code activity based activity project. CodeActivity can be used if the activity provides a single result, which is exposed through the Result argument, but CodeActivity does not support the use of bookmarks, so NativeActivity is used.

To create the Prompt activity

  1. Press CTRL+SHIFT+B to build the project. This enables the ReadInt activity in this project to be used to build the custom activity from this step.

  2. Choose Add New Item from the Project menu.

  3. In the Installed Templates list, select Workflow. Select Activity from the Workflow list.

  4. Type Prompt into the Name box and then click Add.

  5. Double-click Prompt.xaml in Solution Explorer to display it in the designer if it is not already displayed.

  6. Click Arguments in the lower-left side of the activity designer to display the Arguments pane.

  7. Click Create Argument.

  8. Type BookmarkName into the Name box, select In from the Direction drop-down list, select String from the Argument type drop-down list, and then press ENTER to save the argument.

  9. Click Create Argument.

  10. Type Result into the Name box that is underneath the newly added BookmarkName argument, select Out from the Direction drop-down list, select Int32 from the Argument type drop-down list, and then press ENTER.

  11. Click Create Argument.

  12. Type Text into the Name box, select In from the Direction drop-down list, select String from the Argument type drop-down list, and then press ENTER to save the argument.

    These three arguments are bound to the corresponding arguments of the WriteLine and ReadInt activities that are added to the Prompt activity in the following steps.

  13. Click Arguments in the lower-left side of the activity designer to close the Arguments pane.

  14. Drag a Sequence activity from the Control Flow section of the Toolbox and drop it onto the activity designer.

    Dd489453.Tip(en-us,VS.100).gifTip:
    If the Toolbox window is not displayed, select Toolbox from the View menu.

  15. Drag a WriteLine activity from the Primitives section of the Toolbox and drop it in the Sequence activity.

  16. Bind the Text argument of the WriteLine activity to the Text argument of the Prompt activity by typing Text into the Enter a VB expression box in the Properties window, and then press the TAB key two times to dismiss the IntelliSense list members window and save the property value by moving the selection off the property. This property can also be set by typing Text into the Enter a VB expression box on the activity itself.

    Dd489453.Tip(en-us,VS.100).gifTip:
    If the Properties Window is not displayed, select Properties Window from the View menu.

  17. Drag a ReadInt activity from the ActivityLibrary1 section of the Toolbox and drop it in the Sequence activity so that it follows the WriteLine activity.

  18. Bind the BookmarkName argument of the ReadInt activity to the BookmarkName argument of the Prompt activity by typing BookmarkName into the Enter a VB expression box to the right of the BookmarkName argument in the Properties Window, and then press the TAB key two times to close the IntelliSense list members window and save the property.

  19. Bind the Result argument of the ReadInt activity to the Result argument of the Prompt activity by typing Result into the Enter a VB expression box to the right of the Result argument in the Properties Window, and then press the TAB key two times.

  20. Press CTRL+SHIFT+B to build the solution.

See Also

Reference

CodeActivity
NativeActivity

Concepts

Designing and Implementing Custom Activities

Other Resources

Getting Started Tutorial
How to: Create a Workflow