1)动态子流程的场景
考虑以下工作流场景:
组长分配工作,指定接收人,每个接收人完成任务后组长立刻可以审批,不必等待其他组员。
2)QuickFlow对子流程的支持
build110821 版本之后,QuickFlow提供了ChildWorkflow和FlowchartWorkflow活动,用来实现子流程。
ChildWorkflow提供顺序子流程模型,FlowchartChildWorkflow提供Flowchart类型的子流程支持。
3) 使用步骤
3.1 确保安装了build110821或之后的版本的wsp,如果在QFD工具箱中找不到ChildWorkflow,则修改QFD目录下的ToolboxItems.txt,添加如下两行:
QuickFlow.ChildWorkflow, QuickFlow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628
QuickFlow.FlowchartChildWorkflow, QuickFlow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e17456283.2 将ChildWorkflow活动拖入设计器,将子活动添加到ChildWorkflow中,如果子活动的用户分配在各个子流程是一样的,则直接将User或Users属性绑定到工作流变量,或者设置角色名称。
3.3如果子活动用户在各个子流程分支中不一样,则需要配置属性映射:
首先创建一个Names类型的工作流变量,这个变量用来存放各个子流程分支的用户,可以写死或者用过UI代码传递变量值。
然后,设置ChildWorkflow的ChildPropertiesMapping, 将需要动态分配用户的活动的User属性绑定到工作流变量。
4)示例
4.1 画出如图所示的流程图
其中,组长分配工作,组员接受工作,组长审批工作都是Task活动
4.2 添加两个工作流变量: groupLeader, string类型,groupMembers, Names类型, 为了方便测试,可以设置groupLeader为一个账号,Names为多个账号,采用换行区分
4.3 将组长分配工作和组长审批工作的User属性绑定到groupLeader
4.4 选中ChildWorkflow活动,将InitalChildData属性绑定到groupMembers,InitalChildData的值只能绑定到Names类型的变量,Names变量中包含几个值则对应会创建几个子流程
4.5 编辑ChildPropertiesMapping属性,添加一个映射,将组员接受工作活动的User属性绑定到 groupMembers变量,如下图:
4.6 发布流程,进行测试。
示例流程下载:
5)ChildWorkflow属性列表
属性名 | 属性说明 |
InitalChildData | 用来初始化子流程的个数,InitalChildData一般需要绑定到一个Names类型的变量,Names类型实际是一个NameCollection的字符串集合,集合的元素个数决定了子流程的个数 |
ChildPropertiesMapping | 子流程活动属性映射,设置映射后,ChildWorkflow自动将子流程的属性设置为对应Names集合中的值 即:第一个子流程对应Names集合的第一个元素,第二个子流程对应Names集合的第二个元素 |
ExecutionType | 控制子流程是并行一次创建还是串行一个个创建 |
TaskTitleFormat | 可以控制子流程任务的标题格式,模式为{num}.{title}, {num}表示流程顺序号,{title}表示任务原来的名称, 即TaskTitle属性的值 |
CompeteCondition | 控制ChildWorkflow活动何时完成,若指定了CompeteCondition,则每个子流程完成后会计算CompeteCondition的值,如果返回true,无论其他流程分支有无完成,活动都会结束,未完成的任务被取消 |
6)备注
6.1 FlowchartChildWorkflow的属性跟ChildWorkflow完全一样
6.2 用FlowchartChildWorkflow时,不必(也不能)拖入Start活动,第一个拖入的活动即为 起始活动。
6.3若要实现子流程结束后统一审批,可以部分打回的效果,则可以在统一审批的时候控制Names变量的值,来控制打回给那些人。
6.4 本文的示例没有涉及到UI的开发,UI开发请看到其他文章进行。
6.5 如果子流程需要会签,则采用MultiTask活动,将其Users属性映射到Names变量,然后控制Names变量值每行多个账号,如下:
dc\user1,dc\user2
dc\user3,dc\user4
6.6 如何在UI代码中给Names变量赋值请参考其他文章。
6.7 不要在ChildWorkflow之外的规则代码中取子流程中活动的属性,比如Taskoutcome,因为动态创建的原因,这些属性可能取不到,或者只能取到最后完成的子流程产生的数据。
6.8 如果在ChildWorkflow之内的规则代码中获取内部子活动的状态,因为QuickFlow内部有活动属性同步的机制,可以取到当前最新的数据,普通的并发条件下作者做过测试,但不能保证大并发条件下没有问题
6.9 当前版本不允许跨容器拖放移动活动,即:不能将一个活动从ChildWorkflow内部拖拽到其他外部活动内部。
6.10 如果需要在ChildWorkflow后面获取到子流程某个任务活动的Outcome做判断如何做?
如果子流程内部是Task,不支持直接获取Task.Outcome,必须通过其他方法,比如用额外的工作流变量+UI代码实现
如果子流程内部是MultiTask等支持多任务的活动,则可以把Outcomes绑定到一个新的变量,比如outcomes1,outcomes1的类型是OutcomeCollection。然后用Decision判断outcomes1即可。如outcomes1.AllMatch("Approved") , this.TaskOutcomes1.MatchCount("Rejected",1); :
注意:绑定时,直接点Outcomes旁边那个图标,然后选择绑定到新变量。因为工作流的变量管理中不支持创建OutcomeCollection类型的变量。
6.11 注意:子流程活动的属性若需要根据不同的流程有不同的值,则必须设置PropertyMapping,并且,不能绑定(bind)到工作流变量。若设置了绑定,则属性映射会失效。