Creating SharePoint 2010 State Machine Workflows in Visual Studio 2010

SharePoint Visual How To

Summary:  Learn how to use the State Machine Workflow template in Microsoft Visual Studio 2010 to build a Microsoft SharePoint 2010 state machine workflow.

Applies to: SharePoint Foundation 2010 | SharePoint Server 2010 | Visual Studio | Visual Studio 2008 | Visual Studio 2010

Provided by:   Ben Hedges, Point8020

Overview

Microsoft Visual Studio 2010 provides a State Machine Workflow template that enables you to build workflow solutions for Microsoft SharePoint 2010 by using a graphical design surface. Unlike sequential workflows, which transition from activity to activity, state machine workflows transition from state to state.

Code It

This SharePoint Visual How To describes the following steps for creating and deploying a state machine workflow to a SharePoint 2010 site:

  1. Creating a prerequisite document library named Projects.

  2. Adding state activities for stateInProgress, stateReview, and stateFinished.

  3. Configuring state initialization and events for each state.

  4. Configuring code that determines state transitions.

Prerequisites

This workflow requires a specific document library named Projects.

To create the Projects document library

  1. On the Site Actions menu, click More Options.

  2. In the installed items list, click Document Library.

  3. On the right side of the screen, in the name box, type Projects, and then click Create.

Creating a Workflow

Begin by creating a SharePoint State Machine Workflow project in Visual Studio 2010.

To create a SharePoint State Machine Workflow project in Visual Studio 2010

  1. In Visual Studio, on the File menu, click New, and then click Project.

  2. In the Installed Templates section, expand either Visual Basic or C#, expand SharePoint, and then click 2010.

  3. In the template pane, click State Machine Workflow.

  4. In the Name box, type stateWorkflow. Leave the default values in the other fields, and click OK.

  5. In the SharePoint Customization Wizard, in the What local site do you want to use for debugging? list, select your site, and then click Next.

  6. On the Specify the workflow name for debugging page, leave the default name, and ensure that List Workflow is selected. Click Next.

  7. On the Select the lists you will use when debugging page, in the list labeled The library or list to associate your workflow with, select Projects. Leave the other options with their default settings, and click Next.

  8. On the Specify the conditions for how your workflow is started page, click Finish.

The design surface appears with the Workflow1IntitalState activity.

To add states to the workflow

  1. From the Windows Workflow 3 group in the Toolbox, drag three State activities onto the design surface.

  2. Click the WorkFlow1InitialState activity, and in the Properties pane, in the Name property, rename this state to InitialState.

  3. Click the stateActivity1 activity, and in the Properties pane, in the Name property, rename this state to stateInProgress.

  4. Click the stateActivity2 activity, and in the Properties pane, in the Name property, rename this state to stateReview.

  5. Click the stateActivity3 activity, and in the Properties pane, in the Name property, rename this state to stateFinished.

    Figure 1 shows the three states that were added to the design surface.

    Figure 1. Adding states to the design surface


    Adding states to the design surface

To set an initial and completed state

  1. Right-click the state that is labeled InitialState, and then click Set as Initial State.

  2. Right-click the state that is labeled stateFinished, and then click Set as Completed State.

To configure the InitialState activity

  1. In the InitialState activity, double-click eventDrivenActivity1. A new view appears.

    Figure 2. Initial State activity


    Initial state workflow

  2. Drag a SetState activity from the Toolbox, and drop it under the onWorkflowActivated1 activity.

  3. In the Properties pane, in the TargetStateName property, click the drop-down list, and select stateInProgress.

  4. Click Workflow1 on the design surface to return to the full workflow view.

To configure the stateInProgress activity

  1. Right-click the stateInProgress activity, and then click AddStateInitialization.

  2. In the Properties pane, rename the stateInitializationActivity1 to stateInProgressInitialization.

  3. From the SharePoint Workflow options in the Toolbox, drag a CreateTask activity and add it to the stateInProgressInitialization drop area.

  4. In the Properties pane, in the CorrelationToken property, type InProgressToken, and press Enter.

  5. In the Properties pane, expand the CorrelationToken property, and in the OwnerActivityName list, select stateInProgress.

  6. In the Properties pane, in the TaskID property, click the value, and then click the ellipsis button (...).

  7. In the Bind 'TaskID' to an activity's property dialog box, click the Bind to a new member tab.

  8. In the Choose the type of member to create option list, click Create Field. Click OK.

  9. In the Properties pane, click the TaskProperties property, and then click the ellipsis button (...).

  10. In the Bind 'TaskProperties' to an activity's property dialog box, click the Bind to a new member tab.

  11. In the Choose the type of member to create option list, click Create Field, and then click OK.

  12. In the Properties pane, in the MethodInvoking property, type createTask1_MethodInvoking, and press Enter.

  13. Add the following code.

    createTask1_TaskId1 = Guid.NewGuid()
    createTask1_TaskProperties1.Title = "Finish Document"
    createTask1_TaskProperties1.AssignedTo = "CONTOSO\sanjays"
    createTask1_TaskProperties1.DueDate = Date.Now.AddDays(1.0)
    createTask1_TaskId1 = Guid.NewGuid();
    createTask1_TaskProperties1.Title = "Finish Document";
    createTask1_TaskProperties1.AssignedTo = @"CONTOSO\sanjays";
    createTask1_TaskProperties1.DueDate = DateTime.Now.AddDays(1.0);
  14. Click the Design tab, and then click Workflow1 to return to the full workflow view.

  15. Right-click the stateInProgress activity, and then click AddEventDriven.

  16. From the SharePoint Workflow options in the Toolbox, drag an onTaskChanged item to the stateInProgress drop area.

  17. In the Properties pane, click the TaskID property, and then click the ellipsis button (...).

  18. In the Bind 'TaskID' to an activity's property dialog box, on the Bind to an existing member tab, click createTask1_TaskId1. Click OK.

  19. In the Properties pane, click the AfterProperties field, and then click the ellipsis button (...).

  20. In the Bind 'AfterProperties' to an activity's property dialog box, click the Bind to a new member tab.

  21. In the Choose the type of member to create option list, click Create Field, and then click OK.

  22. In the Properties pane, click the BeforeProperties field, and then click the ellipsis button (...).

  23. In the Bind 'BeforeProperties' to an activity's property dialog box, click the Bind to a new member tab.

  24. In the Choose the type of member to create option list, click Create Field. Click OK.

  25. In the Properties pane, in the CorrelationToken property, select InProgressToken.

  26. In the Properties pane, in the Invoked property, type onTaskChanged1_Invoked, and then press Enter.

  27. Add the following code:

    onTaskChanged1_AfterProperties1 = onTaskChanged1.AfterProperties
    onTaskChanged1_BeforeProperties1 = onTaskChanged1.BeforeProperties
    onTaskChanged1_AfterProperties1 = onTaskChanged1.AfterProperties;
    onTaskChanged1_BeforeProperties1 = onTaskChanged1.BeforeProperties;
  28. Click the Design tab. From the Toolbox, in the Windows Workflow 3 group, drag an IfElse activity below the OnTaskedChange1 activity.

  29. In the Workflow1 code view, add the following code.

    Private Sub ReadyForReview(ByVal sender As Object, _
                           ByVal e As ConditionalEventArgs)
        If onTaskChanged1_AfterProperties1.PercentComplete = 1.0 Then
            e.Result = True
        Else
            e.Result = False
        End If
    End Sub
    private void ReadyForReview(object sender, ConditionalEventArgs e)
      {
          if (onTaskChanged1_AfterProperties1.PercentComplete == 1.0)
          {
              e.Result = true;
          }
          else
          {
              e.Result = false;
          }
      }
  30. Click the Design tab, and then click the ifElseBranchActivity1. In the Properties pane, click the Condition property, and then select Code Condition in the drop-down list.

  31. In the Properties pane, expand the Condition property. In the drop-down list, select ReadyForReview.

  32. From the Windows Workflow 3 group in the Toolbox, drag a SetState activity to the IfElseBranchActivity1 drop area.

  33. In the Properties pane, click TargetStateName, and then click stateReview in the drop-down list.

    Figure 3. StateInProgress activity


    StateInProgress activity

  34. On the Design surface, click Workflow1 to move back to the full workflow view.

To configure the stateReview activity

  1. Right-click the stateReview activity, and then click AddStateInitialization.

  2. From the SharePoint Workflow options in the Toolbox, drag a CreateTask activity to the stateInitializationActivity1 drop area.

  3. In the Properties pane, click the (Name) property and rename it to createReviewTask.

  4. In the Properties pane, in the CorrelationToken property, type ReviewStateToken, and press Enter.

  5. In the Properties pane, expand the CorrelationToken property, and in the OwnerActivityName list, select stateReview.

  6. In the Properties pane, click the TaskID, and then click the ellipsis button (...).

  7. In the Bind 'TaskID' to an activity's property dialog box, click the Bind to a new member tab.

  8. In the Choose the type of member to create option list, click Create Field, and then click OK.

  9. In the Properties pane, click the TaskProperties property, and then click the ellipsis button (...).

  10. In the Bind 'TaskProperties' to an activity's property dialog box, click the Bind to a new member tab.

  11. In the Choose the type of member to create option list, click Create Field, and then click OK.

  12. In the Properties pane, in the MethodInvoking handler, type createReviewTask_MethodInvoking, and then press Enter.

  13. Add the following code.

    createReviewTask_TaskId1 = Guid.NewGuid()
    createReviewTask_TaskProperties1.Title = "Review Document"
    createReviewTask_TaskProperties1.AssignedTo = "CONTOSO\andyj"
    createReviewTask_TaskProperties1.DueDate = Date.Now.AddDays(1.0)
    createReviewTask_TaskId1 = Guid.NewGuid();
    createReviewTask_TaskProperties1.Title = "Review Document";
    createReviewTask_TaskProperties1.AssignedTo = @"CONTOSO\andyj";
    createReviewTask_TaskProperties1.DueDate = DateTime.Now.AddDays(1.0);
  14. Click the Design surface, and then click Workflow1 to move back to the full workflow view.

  15. Right-click the stateReview activity, and then click AddEventDriven.

  16. From the SharePoint Workflow options in the Toolbox, drag an onTaskChanged item to the stateReview drop area.

  17. In the Properties pane, set the Correlation Token to ReviewStateToken.

  18. In the Properties pane, click the TaskID property, and then click the ellipsis button (...).

  19. In the Bind 'TaskID' to an activity's property dialog box, on the Bind to an existing member tab, click createReviewTask_TaskId1, and then click OK.

  20. In the Properties pane, click the AfterProperties field, and then click the ellipsis button (...).

  21. In the Bind 'AfterProperties' to an activity's property dialog box, click the Bind to a new member tab.

  22. In the Choose the type of member to create option list, click Create Field, and then click OK.

  23. In the Properties pane, click the BeforeProperties field, and then click the ellipsis button (...).

  24. In the Bind ' BeforeProperties ' to an activity's property dialog box, click the Bind to a new member tab.

  25. In the Choose the type of member to create option list, click Create Field, and then click OK.

  26. In the Properties pane, in the Invoked handler, type onTaskChanged2_Invoked, and then press Enter.

  27. Add the following code.

    onTaskChanged2_AfterProperties1 = onTaskChanged2.AfterProperties
    onTaskChanged2_BeforeProperties1 = onTaskChanged2.BeforeProperties
    onTaskChanged2_AfterProperties1 = onTaskChanged2.AfterProperties;
    onTaskChanged2_BeforeProperties1 = onTaskChanged2.BeforeProperties;
  28. Click the Design tab. From the Toolbox, in the Windows Workflow 3 group, drag an IfElse activity below the OnTaskedChange2 activity.

  29. Open the Workflow1 code view, and add the following code.

    Private Sub ReviewFinished(ByVal sender As Object, _
                               ByVal e As ConditionalEventArgs)
         If onTaskChanged2_AfterProperties1.PercentComplete = 1.0 Then
               e.Result = True
          Else
               e.Result = False
          End If
    End Sub
    private void ReviewFinished(object sender, ConditionalEventArgs e)
            {
                if (onTaskChanged2_AfterProperties1.PercentComplete == 1.0)
                {
                    e.Result = true;
                }
                else
                {
                    e.Result = false;
                }
            }
  30. Click the Design tab, and then click the ifElseBranchActivity3. In the Properties pane, click the Condition property, and select Code Condition in the drop-down list.

  31. In the Properties pane, expand the Condition property.

  32. In the expanded condition field, select ReviewFinished in the drop-down list.

  33. From the Windows Workflow 3 group in the Toolbox, drag an IfElse activity and add it below the ifElseActivity3 activity in the Drop Activities here area.

    This creates a nested If/Else statement.

  34. Add the following code in the Workflow1 code view.

    Private Sub DocApproved(ByVal sender As Object, _
                            ByVal e As ConditionalEventArgs)
            If onTaskChanged2_AfterProperties1.Description = "<DIV>Approved</DIV>" Then
                e.Result = True
            Else
                e.Result = False
            End If
        End Sub
    private void DocApproved(object sender, ConditionalEventArgs e)
      {
          if (onTaskChanged2_AfterProperties1.Description == "<DIV>Approved</DIV>")
          {
              e.Result = true;
          }
          else
          {
              e.Result = false;
          }
      }
  35. Click the Design tab, and then click the ifElseBranchActivity5. In the Properties pane, click the Condition property, and select Code Condition in the drop-down list.

  36. In the Properties pane, expand the Condition property. In the expanded condition field, select DocApproved in the drop-down list.

  37. From the Toolbox, drag a SetState activity under the ifElseBranchActivity5 activity.

  38. In the Properties pane, click the TargetStateName property, and then select stateFinished.

  39. From the Toolbox, drag a SetState activity under the ifElseBranchActivity6 activity.

  40. In the Properties pane, click the TargetStateName property, and then select stateInProgress.

    Figure 4 shows the finished state machine workflow.

    Figure 4. Completed state machine workflow


    Completed state machine workflow

Deploying the Project

Finally, deploy the project and test your workflow.

To deploy the project

  1. In Solution Explorer, right-click the project, and then click Deploy.

  2. Open the SharePoint home page.

  3. On the Quick Launch menu, click Projects, and then click Add document.

  4. In the Upload Document dialog box, click Browse, select a document, and then click Open. Click OK in the Upload dialog box.

  5. Open the Tasks library, and review the Finish Document task.

  6. Edit the Finish Document task, and in the Complete % box, type 100. Click Save.

    Note the Review Document task.

  7. Edit the Review Document task, set the status to Completed, and set Complete % to 100. In the Description, type Approved, and then click Save.

  8. Open the Projects document library and note that the document workflow is complete.

    Read It

The State Machine Workflow project in Visual Studio 2010 provides a graphical design surface in which a workflow can be built.

  • The Initial State has one activity of SetState that takes the workflow directly to the stateInProgress state.

  • The stateInProgress state has a task activity that generates a new task titled "Finish Document" and assigns the task to a specified user.

  • The stateInProgress state has an onTaskChanged activity that is invoked when the task changes. The inTaskChanged activity has an IfElse statement that compares the "percent complete" of the task to 1.0 (100%).

  • If the condition is true, the workflow transitions to the next state (stateReview). If it is false, the workflow remains at this state.

  • In the stateReview state, a task is generated with a title of "Review Document" as part of the state initialization, and again this task is assigned to a specified user.

  • The stateReview state is invoked when the task changes, and an IfElse statement compares the "percent complete" of this task with 100 percent. As before, when the task is 100 percent complete, the workflow continues.

  • When the task is 100 percent complete, a nested IfElse statement is reached within the stateReview state. The code compares the text that appears in the task description to the string "<DIV>Approved</DIV>".

  • If the string matches, the stage is considered complete and the workflow continues to StateFinished. If the string does not match, the state returns to stateInProgress.

See It

Watch the video

> [!VIDEO https://www.microsoft.com/en-us/videoplayer/embed/4b35a60e-53c9-49a7-aae6-7d09c447ec62]

Length: 00:15:37

Click to grab code

Grab the Code

Explore It

About the Author

Ben Hedges is Senior Vice President, Research and Development at Point8020. Ben is especially interested in modeling Talent Management, Compliance, and Learning and Development solutions on SharePoint. Ben has a wealth of experience fulfilling customer requirements by using Microsoft technologies.