Возникла необходимость написания рабочего процесса утверждения/согласования документа в силу того, что стандартное не подходит (да и то, что в 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);