Click here to Skip to main content
15,896,063 members
Articles / Programming Languages / C#

SharePoint 2010 State Machine Workflows with Custom Task Forms (InfoPath) using VS 2010 - Part 1 of 3

Rate me:
Please Sign up or sign in to vote.
4.79/5 (15 votes)
3 Dec 2012CPOL13 min read 132.3K   3.6K   45  
A tutorial on SharePoint 2010 Custom State Machine Workflows with Custom Task forms in InfoPath 2010. An example based tutorial, where I simulate the Recruitment Process of an organization.
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Linq;
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;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.WorkflowActions;

namespace RecruitmentProcess
{
    public sealed partial class RecruitmentWorkflow : StateMachineWorkflowActivity
    {
        public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();

        public Guid createTaskInitialClearanceTaskId = default(System.Guid);
        public SPWorkflowTaskProperties createTaskInitialClearanceTaskProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties onTaskChangedInitialClearanceBeforeProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties onTaskChangedInitialClearanceAfterProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();

        public Guid createTaskTechnicalClearanceTaskId = default(System.Guid);
        public SPWorkflowTaskProperties createTaskTechnicalClearanceTaskProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties onTaskChangedTechnicalClearanceAfterProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties onTaskChangedTechnicalClearanceBeforeProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();

        public Guid createTaskHRClearanceTaskId = default(System.Guid);
        public SPWorkflowTaskProperties createTaskHRClearanceTaskProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties onTaskChangedHRClearanceAfterProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties onTaskChangedHRClearanceBeforeProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();

        public Guid createTaskAcceptedTaskId = default(System.Guid);
        public SPWorkflowTaskProperties createTaskAcceptedTaskProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties onTaskChangedAcceptedAfterProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties onTaskChangedAcceptedBeforeProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();

        public Guid createTaskRejectedTaskId = default(System.Guid);
        public SPWorkflowTaskProperties createTaskRejectedTaskProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties onTaskChangedRejectedAfterProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
        public SPWorkflowTaskProperties onTaskChangedRejectedBeforeProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();

        public RecruitmentWorkflow()
        {
            InitializeComponent();
        }

        #region Workflow Activated

        private void onWorkflowActivatedInitial_Invoked(object sender, ExternalDataEventArgs e)
        {

        }

        #endregion Workflow Activated

        #region Initial Clearance

        private void createTaskInitialClearance_MethodInvoking(object sender, EventArgs e)
        {
            try
            {
                //Create a new TaskId for the Task
                this.createTaskInitialClearanceTaskId = Guid.NewGuid();

                //TaskProperties field is used to configure the Task Details.
                this.createTaskInitialClearanceTaskProperties.Title = "Initial Clearance";
                //You can assign a Task to an user or to a group. Here we assign the task to HR-Group
                this.createTaskInitialClearanceTaskProperties.AssignedTo = @"Trigyn\Rupesh.Tarwade";

                SPListItem listItem = this.workflowProperties.Item;
                this.createTaskInitialClearanceTaskProperties.ExtendedProperties["ows_title"] = SharePointHelper.GetFieldValue(listItem, "Title");
                this.createTaskInitialClearanceTaskProperties.ExtendedProperties["ows_technology"] = SharePointHelper.GetFieldValue(listItem, "Technology");
                this.createTaskInitialClearanceTaskProperties.ExtendedProperties["ows_experience"] = SharePointHelper.GetFieldValue(listItem, "Experience");

                //Task Type corresponds to TaskURN specified in Elements.xml
                this.createTaskInitialClearanceTaskProperties.TaskType = 1;

                this.createTaskInitialClearanceTaskProperties.DueDate = DateTime.Today.AddDays(5.0);
            }
            catch (Exception ex)
            {
                //Logging is used so that we can debug the errors in the workflow.
                System.Diagnostics.EventLog.WriteEntry("Recruitment Workflow", ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
            }
        }

        private void onTaskChangedInitialClearance_Invoked(object sender, ExternalDataEventArgs e)
        {
            try
            {
                this.onTaskChangedInitialClearanceAfterProperties = this.onTaskChangedInitialClearance.AfterProperties;
                this.onTaskChangedInitialClearanceBeforeProperties = this.onTaskChangedInitialClearance.BeforeProperties;

                //Set the PercentComplete property to 1.0 (i.e. 100%) to indicate that the task has been completed.
                this.onTaskChangedInitialClearanceAfterProperties.PercentComplete = (float)1.0;

                //Get the value of Remarks Column (InfoPath Form) by using the ExtendedProperties property
                string remarks = this.onTaskChangedInitialClearanceBeforeProperties.ExtendedProperties["Remarks"].ToString();

                SPListItem listItem = this.workflowProperties.Item;

                //Write the remarks value to the list item
                if (listItem != null && listItem.Fields.ContainsField("InitialRemarks"))
                {
                    listItem["InitialRemarks"] = remarks;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("Recruitment Workflow", ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
                //throw ex;
            }
        }

        private void InitialClearanceApprovalProcess(object sender, ConditionalEventArgs e)
        {
            try
            {
                //if (this.onTaskChangedInitialClearanceAfterProperties.PercentComplete == (float)1.0 && 
                //   this.onTaskChangedInitialClearanceAfterProperties.ExtendedProperties["Status"] != null &&
                //   this.onTaskChangedInitialClearanceAfterProperties.ExtendedProperties["Status"].ToString().Contains("Approved"))
                //{
                e.Result = true;
                //}
                //else
                //{
                //   e.Result = false;
                //}
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("Recruitment Workflow", ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
            }
        }

        #endregion Initial Clearance

        #region Technical Clearance

        private void createTaskTechnicalClearance_MethodInvoking(object sender, EventArgs e)
        {
            try
            {
                //Create a new TaskId for the Task
                this.createTaskTechnicalClearanceTaskId = Guid.NewGuid();

                //TaskProperties field is used to configure the Task Details.
                this.createTaskTechnicalClearanceTaskProperties.Title = "Technical Clearance";

                //You can assign a Task to an user or to a group. Here we assign the task to HR-Group

                SPListItem listItem = this.workflowProperties.Item;
                //Write the remarks value to the list item
                if (listItem != null)
                {
                    //Check if TechnicalInterviewAssignedTo Field has a value, and Assign this Task to the value of this Field
                    //if (listItem.Fields.ContainsField("TechnicalInterviewAssignedTo"))
                    //{
                    //   this.createTaskTechnicalClearanceTaskProperties.AssignedTo = listItem["TechnicalInterviewAssignedTo"].ToString();
                    //}

                    this.createTaskTechnicalClearanceTaskProperties.AssignedTo = @"Trigyn\Rupesh.Tarwade";

                    //To send InitialRemarks to the InfoPath Form, we add it to the ExtendedProperty of the TaskProperties
                    //ExtendedProperties is a hashtable (Key-Value pair). 
                    //The Key will be the name of field we have used in ItemMetaData.xml and Value will be the value of remarks
                    if (listItem.Fields.ContainsField("InitialRemarks"))
                    {
                        if (this.createTaskTechnicalClearanceTaskProperties.ExtendedProperties.ContainsKey("InitialComments"))
                        {
                            this.createTaskTechnicalClearanceTaskProperties.ExtendedProperties["InitialComments"] = listItem["InitialRemarks"].ToString();
                        }
                        else
                        {
                            this.createTaskTechnicalClearanceTaskProperties.ExtendedProperties.Add("InitialComments", listItem["InitialRemarks"].ToString());
                        }
                    }
                }

                //Task Type corresponds to TaskURN specified in Elements.xml
                this.createTaskTechnicalClearanceTaskProperties.TaskType = 2;

                this.createTaskTechnicalClearanceTaskProperties.DueDate = DateTime.Today.AddDays(2.0);
            }
            catch (Exception ex)
            {
                //Logging is used so that we can debug the errors in the workflow.
                System.Diagnostics.EventLog.WriteEntry("Recruitment Workflow", ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
            }
        }

        private void onTaskChangedTechnicalClearance_Invoked(object sender, ExternalDataEventArgs e)
        {
            try
            {
                this.onTaskChangedTechnicalClearanceAfterProperties = this.onTaskChangedTechnicalClearance.AfterProperties;
                this.onTaskChangedTechnicalClearanceBeforeProperties = this.onTaskChangedTechnicalClearance.BeforeProperties;

                //Set the PercentComplete property to 1.0 (i.e. 100%) to indicate that the task has been completed.
                this.onTaskChangedTechnicalClearanceAfterProperties.PercentComplete = (float)1.0;

                //Get the value of Remarks Column (InfoPath Form) by using the ExtendedProperties property
                string remarks = this.onTaskChangedTechnicalClearanceBeforeProperties.ExtendedProperties["Remarks"].ToString();

                SPListItem listItem = this.workflowProperties.Item;

                //Write the remarks value to the list item
                if (listItem != null && listItem.Fields.ContainsField("TechnicalInterviewRemarks"))
                {
                    listItem["TechnicalInterviewRemarks"] = remarks;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("Recruitment Workflow", ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
                //throw ex;
            }
        }

        private void TechnicalClearanceApprovalProcess(object sender, ConditionalEventArgs e)
        {
            try
            {
                //if (this.onTaskChangedTechnicalClearanceAfterProperties.PercentComplete == (float)1.0 && this.onTaskChangedTechnicalClearanceAfterProperties.ExtendedProperties["Status"].ToString().Contains("Approved"))
                //{
                e.Result = true;
                //}
                //else
                //{
                //   e.Result = false;
                //}
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("Recruitment Workflow", ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
            }
        }

        #endregion Technical Clearance

        #region HR Clearance

        private void createTaskHRClearance_MethodInvoking(object sender, EventArgs e)
        {
            try
            {
                //Create a new TaskId for the Task
                this.createTaskInitialClearanceTaskId = Guid.NewGuid();

                //TaskProperties field is used to configure the Task Details.
                this.createTaskInitialClearanceTaskProperties.Title = "Initial Clearance";
                //You can assign a Task to an user or to a group. Here we assign the task to HR-Group
                this.createTaskInitialClearanceTaskProperties.AssignedTo = @"Trigyn\Rupesh.Tarwade";

                //Task Type corresponds to TaskURN specified in Elements.xml
                this.createTaskInitialClearanceTaskProperties.TaskType = 2;

                this.createTaskInitialClearanceTaskProperties.DueDate = DateTime.Today.AddDays(5.0);
            }
            catch (Exception ex)
            {
                //Logging is used so that we can debug the errors in the workflow.
                System.Diagnostics.EventLog.WriteEntry("Recruitment Workflow", ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
            }
        }

        private void onTaskChangedHRClearance_Invoked(object sender, ExternalDataEventArgs e)
        {
            try
            {
                this.onTaskChangedHRClearanceAfterProperties = this.onTaskChangedHRClearance.AfterProperties;
                this.onTaskChangedHRClearanceBeforeProperties = this.onTaskChangedHRClearance.BeforeProperties;

                //Set the PercentComplete property to 1.0 (i.e. 100%) to indicate that the task has been completed.
                this.onTaskChangedHRClearanceAfterProperties.PercentComplete = (float)1.0;

                //Get the value of Remarks Column (InfoPath Form) by using the ExtendedProperties property
                string remarks = this.onTaskChangedHRClearanceBeforeProperties.ExtendedProperties["Remarks"].ToString();

                SPListItem listItem = this.workflowProperties.Item;

                //Write the remarks value to the list item
                if (listItem != null && listItem.Fields.ContainsField("HRRemarks"))
                {
                    listItem["HRRemarks"] = remarks;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("Recruitment Workflow", ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                LogToHistoryListActivity log = new LogToHistoryListActivity();
                log.HistoryDescription = ex.StackTrace;
                //throw ex;
            }
        }

        private void HRClearanceApprovalProcess(object sender, ConditionalEventArgs e)
        {
            e.Result = true;
        }

        #endregion HR Clearance

        #region Accepted

        private void createTaskAccepted_MethodInvoking(object sender, EventArgs e)
        {

        }

        private void onTaskChangedAccepted_Invoked(object sender, ExternalDataEventArgs e)
        {

        }

        #endregion Accepted

        #region Rejected

        private void createTaskRejected_MethodInvoking(object sender, EventArgs e)
        {

        }

        private void onTaskChangedRejected_Invoked(object sender, ExternalDataEventArgs e)
        {

        }

        #endregion Rejected
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Consultant
India India
I have been designing and developing systems in .NET since 2006. Started out with .NET 1.1, and progressed through to current version. Started working with SharePoint 2010 in 2011, and am currently gaining experience in SharePoint Online and hosted apps.

Comments and Discussions