Возникла необходимость написания рабочего процесса утверждения/согласования документа в силу того, что стандартное не подходит (да и то, что в SharePoint Designer тоже не подошло). Работа, в сущности, происходит с Activity CreateTask и другими Activity, который связаны с ним: onTaskCreated, onTaskChanged и прочие. Сама работа с элементами в целом не сложна, если знать тонкости, конечно. Решил все эти события и Activity связанные с заданием запихнуть в один класс. Покажу как это выглядит примерно.
Создаём свой класс:
[Serializable]
public class ApprovalTask : SequenceActivity
{
private string _prefix = "_ap_task";
private string _path_prefix = string.Empty;
private SPWorkflowActivationProperties _WorkflowProperties; // параметры р.б.
public Microsoft.SharePoint.WorkflowActions. CreateTaskWithContentType _Task; // задание
public SPWorkflowTaskProperties _TaskProperties; // параметры задания
private System.Workflow.ComponentModel.ActivityBind _activityCreateTask;
...
}
Наследуем его от SequenceActivity, что позволяет добавлять в него другие Activity. Как пример, рассмотрю Activity по созданию задания.
Добавляем конструктор:
public ApprovalTask(SPWorkflowActivationProperties workflowProperties, string AssignedTo, int Index)
{
_WorkflowProperties = workflowProperties;
_AssignedTo = AssignedTo;
_Index = Index;
_path_prefix = "Tasks[" + _Index.ToString() + "]";
Initialize();
AddActivities();
}
Для элементов рабочего процесса обязательно задавать корреляцию. Экземпляры своего класса храним в массиве созданном в рабочем процессе.
public List<ApprovalTask> Tasks = new List<ApprovalTask>();Поэтому _path_prefix так и выглядит. Эта переменная используется для настройки корреляции.
AddActivities добавляет созданные Activity в список Activity нашего класса:
public void AddActivities()
{
this.Activities.Add(this._Task);
}
Initialize() производит начальную инициализацию элементов:
public void Initialize()
{
_Task = new CreateTaskWithContentType();
_TaskProperties = new Microsoft.SharePoint.Workflow. SPWorkflowTaskProperties();
_Token = new System.Workflow.Runtime.CorrelationToken();
_Token.Name = _prefix + "_TaskToken2";
_Token.OwnerActivityName = "Workflow1";
_Task.CorrelationToken = _Token;
_Task.Name = _prefix + "_Task2";
_Task.TaskId = Guid.NewGuid();
_activityCreateTask.Name = "Workflow1";
_activityCreateTask.Path = _path_prefix + "._TaskProperties";
_Task.SetBinding(Microsoft.SharePoint.WorkflowActions. CreateTaskWithContentType.TaskPropertiesProperty, ((System.Workflow.ComponentModel.ActivityBind) (_activityCreateTask)));
_Task.TaskProperties = _TaskProperties;
_Task.MethodInvoking += new System.EventHandler(ApprovalTask_MethodInvoking);
}
_activityCreateTask используется для настройки корреляции. У него необходимо задать два свойства: имя владельца (в нашем случае рабочий процесс с именем Workflow1) и путь до переменной.
Собственно всё. Теперь необходимо в рабочем процессе добавить Activity в WorkFlow во время выполнения. Что-то вроде:
Tasks.Add(new ApprovalTask(workflowProperties, _AssignedTo, Tasks.Count));
WorkflowChanges changes = new WorkflowChanges(this);
((SequenceActivity)changes.TransientWorkflow. GetActivityByName("sequenceActivity1")). Activities.Add(Tasks[0]);
this.ApplyWorkflowChanges(changes);