当你自定义控件时,你封装的控件属性,在访问时能访问但是却不能赋值给它,相当于指针指向了黑盒子,因此我们用Replicator控件来解决它。当然Replicator控件还有其他功能。。。。。。。。。。。。。。
当你自定义控件时,你封装的控件属性,在访问时能访问但是却不能赋值给它,相当于指针指向了黑盒子,因此我们用
Replicator控件来解决它。当然
Replicator控件还有其他功能,其中对于工作流来说,审批过程中人员数的不确切这个问题也很容易的解决了。
Replicator控件
属性:
ExecutionType 指定activity的执行模式,是顺序还是状态。
InitialChildData 指定将包含复制器的初始子实例数据的集合。
条件:
UntilCondition 请指定导致复制器的内容activity停止执行的条件;
ChildInitialized 请指定初始化子活动的实例时要调用的方法。
在工作流中引用自定义控件的步骤:
一、OnWorkflowActivated 工作流启动方法 :初始化工作流程。我们用Form和Contact类来解析初始化表单的数据,在microsoft.office.workflow.utility命名空间里。
转换初始化表单数据到一个哈希表
获得原始工作流的信息
设置复制器执行类型
使用内置的方法来解析出人
给每个联系人创建一个任务添加到replicator中,replicator创建列表中的每个子项
准备replicator 的数据
源代码:

初始化工作流程
private void OnWorkflowActivated(object sender, ExternalDataEventArgs e)

{
//Convert the initiation form data to a hashtable
//转换启动表单数据到一个哈希表
this.initFormData = Form.XmlToHashtable(this.workflowProperties.InitiationData);

//Get the originator of the workflow
//获得原始工作流的信息
this.workflowOriginator = Contact.FromPrincipal(this.workflowProperties.OriginatorUser);
this.workflowName = this.workflowProperties.Workflow.ParentAssociation.Name;
this.itemDisplayName = this.workflowProperties.Item.DisplayName;
//Set the replicator execution type
//设置复制器执行类型
this.replicatorExecutionType = (this.initFormData["CreateTasksInSerial"] as string) == "true" ?
ExecutionType.Sequence : ExecutionType.Parallel;

//Use the built-in methods to parse out the people
//使用内置的方法来解析出人
Contact[] contacts = Contact.ToContacts((this.initFormData["Reviewers"] as string), this.workflowProperties.Web);
//Determine if we want to expand groups that were entered into the form.
//定义我们想要扩充进入表单的组
if ((this.initFormData["GroupTasks"] as string) == "false")

{
//Expand the groups (recursively)
bool reachedMaxCount = false;
contacts = Contact.ExpandGroups(this.workflowProperties.Web, contacts,
ApprovalWorkflowSample.MaxExpansionCount, out reachedMaxCount);
}

//Add the data to the replicator so that we can generate a task for each contact.
//The replicator will create a child for each item in the list.
//给每个联系人创建一个任务添加到replicator中,replicator创建列表中的每个子项
this.replicatorInitialChildData = new List<SPWorkflowTaskProperties>();
//Determine the due date of the task (if any)
//定义任务的日期
DateTime dueDate = DateTime.MinValue;

//Due date from a serial approval workflow
//串行审批流程的日期
if ((this.replicatorExecutionType == ExecutionType.Sequence) && (!string.IsNullOrEmpty(this.initFormData["TimePerTaskVal"] as string)))

{
dueDate = DateTime.Now.AddDays(Convert.ToInt32(this.initFormData["TimePerTaskVal"]));
}
//Due date from a parallel approval workflow
//并行审批流程的日期
else if ((this.replicatorExecutionType == ExecutionType.Parallel) && (!string.IsNullOrEmpty(this.initFormData["DueDate"] as string)))

{
dueDate = Convert.ToDateTime(this.initFormData["DueDate"]);
}

//Prepare the replicator data
//准备 replicator 的数据
string contactNames = "";

foreach (Contact contact in contacts)

{
contactNames += string.Format(" {0},", contact.DisplayName);

SPWorkflowTaskProperties taskProperties = new SPWorkflowTaskProperties();
taskProperties.AssignedTo = contact.LoginName;
taskProperties.Description = string.IsNullOrEmpty(this.initFormData["Description"] as string) ? "No instructions were provided." : this.initFormData["Description"] as string;
taskProperties.DueDate = dueDate;

this.replicatorInitialChildData.Add(taskProperties);
}

//Trim the trailing ',' from the string
//用","分割字符串
contactNames = contactNames.Substring(0, contactNames.Length - 1);

//Set the wss user id of the workflow originator
//设置原始工作流的用户ID
int workflowOriginatorId = this.workflowOriginator.PrincipalID;

//Setup the "workflow started" history data
//设置workflow started的历史记录数据
this.logWorkflowStartedHistoryActivity.HistoryDescription = string.Format("{0} was started. Participants:{1}",
this.workflowName, contactNames);
this.logWorkflowStartedHistoryActivity.UserId = workflowOriginatorId;

//Setup the "workflow completed" history data
//设置workflow completed的历史记录数据
this.logWorkflowCompletedHistoryActivity.HistoryDescription = string.Format("{0} was completed.", this.workflowName);
this.logWorkflowCompletedHistoryActivity.HistoryOutcome = string.Format("{0} on {1} has successfully completed. All participants have completed their tasks.",
this.workflowName, this.itemDisplayName);
this.logWorkflowCompletedHistoryActivity.UserId = workflowOriginatorId;
}

二、OnReplicatorChildInitialized(InitialChildData方法: 指定将包含 复制器的初始子实例数据的集合。) :为每个复制器的子实例创建和初始化任务。
获取活动
设置任务
添加info表中的用户和检测与任务关联的用户
更新任务属性的值显示在infopath中
设置其他值
设置created by用户
源代码:

创建和初始化任务
private void OnReplicatorChildInitialized(object sender, ReplicatorChildEventArgs e)

{
//Retrieve the activities
//获取活动
WssTaskActivity task = e.Activity as WssTaskActivity;
task.createWssTask_TaskProperties1 = (SPWorkflowTaskProperties)e.InstanceData;

//Setup the task
//设置任务
task.TaskId = Guid.NewGuid();

//This does two things, adds the user to the infotable in wss (if possible) and
//allows us to check for users that can't be assigned a task.
//添加info表中的用户和检测与任务关联的用户
Contact contact = Contact.FromName(task.createWssTask_TaskProperties1.AssignedTo, this.workflowProperties.Web);
SPPrincipal contactPrincipal = contact.GetPrincipal(this.workflowProperties.Web);

if ((contactPrincipal == null) || (contactPrincipal.ID == -1))

{
//We can't assign the task to this principal - let's try the workflow owner
task.createWssTask_TaskProperties1.AssignedTo = this.workflowOriginator.LoginName;
task.createWssTask_TaskProperties1.Title = string.Format("Please approve {0} (external participant)", this.itemDisplayName);
task.createWssTask_TaskProperties1.OnBehalfEmail = contact.EmailAddress;
task.createWssTask_TaskProperties1.OnBehalfReason = "This user does not have access to this Windows SharePoint Server site.";
task.TaskAssignedTo = this.workflowOriginator;
}
else

{
//Normal task
task.createWssTask_TaskProperties1.Title = string.Format("Please approve {0}", this.itemDisplayName);
task.TaskAssignedTo = contact;
}

// update the unescaped description text which is displayed inside infopath
//更新description属性的值显示在infopath中
task.createWssTask_TaskProperties1.ExtendedProperties["BodyText"] = SPHttpUtility.HtmlDecode(task.createWssTask_TaskProperties1.Description);

//Set the remaining values
//设置其他值
task.createWssTask_TaskProperties1.PercentComplete = 0;
task.createWssTask_TaskProperties1.SendEmailNotification = true;
task.createWssTask_TaskProperties1.StartDate = DateTime.Now;
task.createWssTask_TaskProperties1.TaskType = Convert.ToInt32(this.initFormData["DefaultTaskType"]);
//Set the "created by" user
//设置created by用户
if (task.TaskCreatedBy == null)

{
task.TaskCreatedBy = this.workflowOriginator;
}
}

三、IsReplicatorDone (UntilCondition 请指定导致复制器的内容activity停止执行的条件;
):判断复制器是否已完成任务的条件。
源代码:
private void IsReplicatorDone(object sender, ConditionalEventArgs e)

{
//Have all the replicator children completed?
e.Result = this.taskReplicator1.AllChildrenComplete;
}

四、IsTaskCompleted(自定义控件的onTaskChanged的自定义方法isTaskCompleted): 任务修改了反射到自定义控件的IsTaskCompleted事件中。IsTaskCompleted事件参数TaskEventArgs包含了SPWorkflowTaskProperties (AfterProperties)属性,该属性是任务修改时存储修改时的新值。
获得任务数据
获得审批该活动的用户
获得任务结果——#和@在TaskStatus属性中显示完成
判断结果是否取消流程
判断结果是否任务已完成
源代码:
private void IsTaskCompleted(object sender, TaskEventArgs e)

{
//Get the task data
//获得任务数据
WssTaskActivity task = sender as WssTaskActivity;

//Get the name of the user who performed this action
//获取活动的当前用户
Contact contact = Contact.FromName(e.Executor, this.workflowProperties.Web);

//Get the task result - # and @ in the "TaskStatus" field indicate a completion
//获得任务结果-#和@在TaskStatus属性中显示完成
string taskResult = e.AfterProperties.ExtendedProperties["TaskStatus"] as string;

bool isTaskRejected = (taskResult == "@");
e.Result = isTaskRejected || (taskResult == "#");

//Single rejection rejects the entire workflow
//取消流程
if (isTaskRejected)

{
this.isWorkflowRejected = true;
}

//Is the task completed
//任务是否完成
if (e.Result)

{
task.TaskChangedBy = contact;
task.TaskCompletedBy = contact;
task.completeWssTask_TaskOutcome1 = isTaskRejected ? string.Format("Task rejected by {0}", contact.DisplayName) :
string.Format("Task approved by {0}", contact.DisplayName);
}
}

五、OnTaskDeleted (自定义控件onTaskDeleted的Invoked方法):删除任务事件。
获得任务数据
获得审批该活动的用户
设置友好的名称
拒绝工作流
源代码:

OnTaskDeleted
private void OnTaskDeleted(object sender, TaskEventArgs e)

{
//Get the task

WssTaskActivity task = sender as WssTaskActivity;

//Get the name of the user who performed this action
//获得审批该活动的用户
Contact contact = Contact.FromName(e.Executor, this.workflowProperties.Web);

//Set the friendly name
//设置友好的名称
task.TaskDeletedBy = contact;

//Reject the workflow
//拒绝工作流
this.isWorkflowRejected = true;
}

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述