SharePoint 2007 Workflow – Using the OnWorkflowItemDeleted activity

Introduction

One of the most exciting features included in SharePoint 2007 is workflow support and the possibility of developing our own custom workflows (for more information about workflow development in the SharePoint 2007 platform please click here).

While it is possible to develop workflows to automate a series of activities without any human intervention, the full power of workflows in the SharePoint platform can only be achieved with human-oriented workflows. These workflows are characterized by creating and assigning tasks to users that must complete them in order to fulfill the purpose of the workflow. Some examples of out of the box human-oriented workflows that are included with MOSS 2007 are Approval, Collect Feedback and Issue Tracking.

In the SharePoint world, the most common usage of human-oriented workflows is in the context of document libraries, to perform some work when a new document is uploaded into a document library. Typically, in such scenario, tasks are created and assigned to users throughout the workflow lifetime that will complete them until the workflow purpose has been fulfilled. Having the workflow goal to be achieved is the desired and most common scenario, but unexpected actions may occur before the end of the workflow such as a user to delete the document. The following example will show you how to handle this situation in a custom workflow by using the OnWorkflowItemDeleted activity.

Example

The OnWorkflowItemDeleted activity can be used within a custom workflow to handle an item deletion in any SharePoint list. In this example, this activity will be used to delete all uncompleted tasks associated with the deleted item. After dragging and dropping the OnWorkflowItemDeleted activity into the workflow designer, the Invoke property must be set to the event handler that will perform the work.

For the purpose of this example, please consider the simple approval workflow in the following image:

In this workflow, a parallel activity with two branches is used. One contains the main workflow logic while the other contains a OnWorkflowItemDeleted activity that will handle the item deletion. The Invoke event property was set to be handled by an event handler method called OnWorkflowItemDeleted_Invoked. Let’s take a look at the code:

public sealed partial class ApprovalWorkflow : SequentialWorkflowActivity
{
    /// <summary>
    /// Handles the workflow item deleted event.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void OnWorkflowItemDeleted_Invoked(object sender, ExternalDataEventArgs e)
    {
        //delete uncompleted tasks when 
        //an item is deleted
        SPWorkflow workflowInstance = 
            workflowProperties.Workflow;
        SPWorkflowTaskCollection taskCollection = 
            GetWorkflowTasks(workflowInstance);
        for (int i = taskCollection.Count; i > 0; i--)
        {
            SPWorkflowTask task = 
                taskCollection[i - 1];
            using (SPWeb web = 
                workflowProperties.Web)
            {
                if (task[SPBuiltInFieldId.TaskStatus]
                    .ToString() != SPResource.GetString
                    (new CultureInfo((int)web.Language, false),
                    "WorkflowTaskStatusComplete", new object[0]))
                {
                    task.Delete();
                }
            }
        }
    }

    /// <summary>
    /// Reads the workflow tasks. This method 
    /// is implemented because the Tasks property
    /// of the SPWorkflow instance takes a 
    /// while to be populated.
    /// </summary>
    public static SPWorkflowTaskCollection 
        GetWorkflowTasks(SPWorkflow workflowInstance)
    {
        SPWorkflowTaskCollection taskCollection = null;
        bool tasksPopulated = false;
        while (!tasksPopulated)
        {
            try
            {
                taskCollection = workflowInstance.Tasks;
                tasksPopulated = true;
            }
            catch { }
        }

        return taskCollection;
    }
}

In the previous example, the following actions are being performed:

  • In the OnWorkflowItemDeleted_Invoked event handler, the workflow instance task collection is obtained by calling the GetWorkflowTasks method;
  • The task collection is iterated and the each task status is checked to verify if it is still uncompleted;
  • If so, the task is deleted.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>