1、例子 1 地址:http:/ StateInitialization、EventDrivenActivity 和StateFinalization 3 个活动。StateInitialization:用来初始化状态,一般在这个活动内部添加 CreateTask 实现任务的创建。StateFinalization:当状态结束时被执行。 EventDrivenActivity:用来接受事件,一般在内部放置一个 OnTaskChange 活动等待任务完成。SetState:用来实现流程状态的跳转。SetState 活动一般放置在 OnTaskChange 活动后,在任务完成后按照任务表单域设置流程状
2、态。拖曳 4 个 State 活动到设计器中。分别改名为preApprovalActivity、approvalActivity、reSubmitActivity 和 completeActivity。通过右键菜单,将completeActivity 活动设置为终止状态,如图。1 双击 Workflow1InitialState 活动中的“EventDriven“活动,在其中添加一个 SetState 活动,设置其 TargetState 为“preApprovalActivity“。2 添加 CreateTask 活动,创建审批任务。拖曳 stateInitializationActivit
3、y 到preApprovalActivity 内部,双击“stateInitializationActivity“,在stateInitializationActivity 内部添加一个 CreateTask 活动,改名为“createPreApprovalTask“,指定其 CorrelationToken 为“preApprovalTaskToken“,将其 SpecialPermission 属性绑定到工作流的 preApprovalTaskSpecialPermissions 字段TaskId 属性绑定到工作流的 preApprovalTaskId 字段TaskProperties 属
4、性绑定到工作流的 preApprovalTaskProperties 字段如图所示。3 处理 createPreApprovalTask 的 MethodInvoking 方法,代码如下。private void createPreApprovalTask_MethodInvoking(object sender, EventArgs e)preApprovalTaskId = Guid.NewGuid();preApprovalTaskProperties.Title = “文档预审“;preApprovalTaskProperties.TaskType = 0; /审批任务采用第一个任务表
5、单preApprovalTaskProperties.AssignedTo = “codeartuser1“; /指定审批人/设置任务编辑权限preApprovalTaskSpecialPermissions.Clear(); preApprovalTaskSpecialPermissions.Add(preApprovalTaskProperties. AssignedTo, SPRoleType.Contributor);以上代码将文档预审任务分配给 user1。4 添加 OnTaskChanged 活动,等待任务完成,并进行处理。返回到工作流设计器界面,拖曳EventDriven 活动到
6、 preApprovalActivity,双击“EventDriven“活动,在 EventDriven 活动中添加 OnTaskChanged 活动,改名为“onPreApprovalTaskChanged“。设置 CorrelationToken 属性跟 createPreApprovalTask 活动一致,将 AfterProperties 和 BeforeProperties 属性均绑定到preApprovalTaskProperties 字段,将 TaskId 属性绑定到 preApprovalTaskId 字段,如图所示。5 处理 Invoked 事件,代码如下。private v
7、oid onApprovalTaskChanged_Invoked(object sender, ExternalDataEventArgs e) /获取到产生事件的 OnTaskChanged 活动 OnTaskChanged onTaskChangedActivity = (OnTaskChanged)sender;SPWorkflowTaskProperties taskProp = onTaskChangedActivity.AfterProperties;/按照表单中 approvalState 域设置审批状态this.approvalState = (ApprovalState)E
8、num.Parse(typeof(ApprovalState), taskProp.ExtendedProperties“approvalState“.ToString(), true);string comments = “ + taskProp.ExtendedProperties“comments“;/记录日志this.workflowProperties.Workflow.CreateHistoryEvent( (int) SPWorkflowHistoryEventType.WorkflowComment, 0, this.workflowProperties.OriginatorU
9、ser, this.approvalState.ToString(),“审批用户:“ + taskProp.AssignedTo + “;审批时间:“ + DateTime.Now + “;审批意见:“ + comments, “);6 设置状态转换逻辑。添加一个 IfElse 活动到 EventDriven 活动中,并添加一个条件分支。设置第 1 个分支的 Condition 为规则条件,名称为“IsApproval“,表达式为:this.approvalState = ApprovalState.Approval在第 1 个分支中添加 1 个 SetState 活动,设置其 TargetS
10、tate 为 approvalActivity。设置第 2 个分支的 Condition 为规则条件,名称为“IsReSubmit“,表达式为:this.approvalState = ApprovalState.ReSubmit在第 2 个分支中添加 1 个 SetState 活动,设置其 TargetState 为“reSubmitActivity“。设置第 3 个分支的 Condition 为规则条件,名称为“IsComplete“,表达式为:this.approvalState = ApprovalState.Complete在第 3 个分支中添加 1 个 SetState 活动,设置
11、其 TargetState 为 completeActivity。最后的 EventDriven 活动设计器效果如图所示。7 按照同样的步骤,完成 approvalActivity 活动和 reSubmitActivity 活动的设置。最终的设计器如图所示。从以上的流程可以看出示例项目中实现的流转逻辑:preApprovalActivity 可以转向reSubmitActivity、approvalActivity 或 completeActivity,而 reSubmitActivity 只能转回preApprovalActivity,approvalActivity 只能转向 comple
12、teActivity。例子 2 地址:http:/ / Report Information. private string employeeName; private string mngrEmail; private string mngrName; private double reportTotal; private string domain; Add properties for each field. You do not have to provide setters; getters are sufficient. 给每个字段添加属性把下面代码添加到 onReportWork
13、flowActivated_Invoked 中C#/ Read in Expense Report form values. employeeName = workflowProperties.ItemEmployee Name.ToString(); mngrName = workflowProperties.ItemManager Name.ToString(); mngrEmail = workflowProperties.ItemManager Email Address.ToString();reportTotal = (double)workflowProperties.ItemR
14、eport Total; domain = workflowProperties.ItemDomain.ToString(); 关于如何设置 infopath 表单字段域,请看 Creating a Custom Approval Workflow for SharePoint Server 2007 Using SharePoint Designer 2007把下面代码添加到 createReportTask_MethodInvoking 中C#/ Create unique Task Id.taskId = Guid.NewGuid(); / Set task properties. ta
15、skProperties.TaskType = 1; taskProperties.Title = Expense Report Approval; taskProperties.StartDate = DateTime.Today; taskProperties.PercentComplete = 0.0f; taskProperties.AssignedTo = Domain + + ManagerName;把下面代码添加到 onTaskChangedReportReviewed_Invoked 中C#/ Retrieve report approval value from task f
16、orm. string selVal = afterProperties.ExtendedPropertiesoptApproval.ToString();int val = 0; if (!String.IsNullOrEmpty(selVal) if (Int32.TryParse(selVal, out val) if (val = 1) isReportApproved = true; / Show that the task is in progress. taskProperties.PercentComplete = 50; 把下面代码添加到 IsReportRejected 方
17、法中C#/ Check to see if report is rejected.if (!isReportApproved) e.Result = true; Add the following code to the IsReportApproved method. 把下面代码添加到 IsReportApproved 方法中C#/ Check to see if report is approved.if (isReportApproved) e.Result = true; 把下面代码添加到 completeTaskReportApproved_MethodInvoking 和compl
18、eteTaskReportRejected_MethodInvoking 方法中C#/ Complete the task. taskProperties.PercentComplete = 100; 现在添加日志代码。把下面代码添加到 logToHistoryReportSubmittedState_MethodInvoking 方法中。C#LogToHistoryListActivity log = (LogToHistoryListActivity)sender;if (log != null) log.HistoryDescription = Report Submitted; 重复上
19、面的步骤,把上面代码添加到 logToHistroyReportApprovedState_MethodInvoking 和logToHistoryReportRejectedState_MethodInvoking 方法中,修改 Report Submitted 为 Report Approved 或者 Report Rejected。修改 Workflow.xml 文件你要确定在 Workflow.xml 中包含你的费用报销流程表单添加下面的元素作为 MetaData 的子元素。XmlTask1_FormURNurn:schemas-microsoft-comffice:infopath:
20、 ExpenseReportApprovalForm: -myXSD-2008-04-09T15-47-41/Task1_FormURN 用你自己的费用报销表单的 URN 替换上面的 URN。你可以通过,在设计器中打开你的表单,然后点文件-属性查看。添加 TaskListContentTypeId 属性到 Workflow 元素中。XmlCopy CodeTaskListC 注意: 如果你的表单不能正确显示,请检查上面的编号是否正确。把 CodeBesideClass 的值为 ExpenseReportStateMachineWF.ExpenseReportStateMachineWorkfl
21、ow。修改 Feature.xml 文件你要确保 Feature.xml 中包含你的费用报销表单。修改 Feature.xml把下面代码作为 ElementManifests 的子元素XmlCopy CodeElementFile Location= ExpenseReportApprovalFormStateMachineWF.xsn / 例子 3State 活动可以只包含一个 StateInitialization 活动、一个 StateFinalization 活动、一个或多个 EventDriven 活动,以及嵌套状态的一个或多个 State 活动。在程序控制权传递到某个状态活动并开始
22、执行时,该状态活动将检查是否存在 StateInitialization 活动。如果存在,则执行该活动。同样地,某个状态活动在将控制权传递给另一个状态时,会检查是否存在 StateFinalization 活动。如果存在,则执行该活动。需要注意 StateInitialization 活动和 StateFinalization 活动也都是复合活动,这一点很重要。与 State 活动不同,对于这些活动可以包含的活动的限制非常少。也就是说,顺序工作流中可以使用的所有活动都可以放在这些活动中。请注意,不能将 SetState 活动放入 StateFinalization 活动中,这一点很重要。否则没
23、有任何意义,因为如果这样做,则只有在执行 SetState 活动后才会执行 StateFinalization 活动。SetState 活动只能位于 StateInitialization 或 EventDriven 活动内。在实际应用中,状态机运行的时间通常很长,其生命周期中的大部分时间都是暂停于某个状态,等待来自工作流外部的输入。使用 EventDriven 活动,可以暂停执行状态以等待外部信息。具体来说,事件由外部数据服务引发,并由 EventDriven 活动接收。建立 EventDriven 活动可能有点复杂,以下步骤可以为您提供一些入门指导。1. 确定数据交换和状态转换所需的事件。
24、 2. 定义外部数据交换接口。 3. 为状态机工作流添加 EventDriven 活动。 4. 引用外部数据交换接口。 5. 实现外部数据交换接口。 6. 将外部数据接口添加到工作流运行时。7. 使用外部数据交换来交换数据和转换状态。在向 EventDriven 活动中放入活动时,我们需要遵循几条规则,这一点与 StateInitialization 和 StateFinalization 活动不同。这是由于 EventDriven 活动继承自 Sequence 活动,因此具有以下限制:第一个子活动必须能够实现公共接口 IEventActivity。所有后续活动可以为任何类型。在本示例中,使用的是 HandleExternalEvent 活动。此活动可以接收工作流运行时外部的事件。还有两个活动实现了 IEventActivity 接口,它们是 Delay 活动和 WebServiceInput 活动。