综合应用WPF/WCF/WF/LINQ之四:创建一个StateMachineWorkflow

简介:
这里,我们将实现最为简单的一种情况:员工提出申请,然后先由员工的领导审批,再由领导的领导审批,依次类推,直到公司最高领导。
  对于这样的一个请假审批的流程,我们实现Workflow的实质在于,由Workflow来确定审批人和请假单的状态。从这个角度来考虑问题,则问题将会清晰很多:每次Workflow运行时,我们需要设置该请假单的后续审批人和状态。因此,我们可以将Workflow分成四种状态:初始状态,设置状态,等待状态和结束状态。其中设置状态用于设置该请假单的后续审批人和状态,等待状态则用于接受外部用户的审批请求。
  下面我们将一步一步的实现这个Workflow:
  1、在Eallies.OA.Workflow.Interface项目中添加一个Interface,由于该Workflow需要与外部用户交互,我们需要处理外部事件和调用外部方法。在Workflow中,处理外部事件和调用外部方法时,都需要指定一个Interface。
  在这个Interface中,我们需要添加LeaveApprove事件以及UpdateLeaveApproverByLeaveId和UpdateLeaveStatusByLeaveId方法,分别用于处理外部审批事件以及更新请假单审批人和状态。
    1  using System;
    2  using System.Collections.Generic;
    3  using System.Linq;
    4  using System.Text;
    5  using System.Workflow.Activities;
    6  using Eallies.OA.Workflow.Args;
    7  using Eallies.OA.Info;
    8  using Eallies.OA.Info.Enum;
    9 
   10  namespace Eallies.OA.Workflow.Interface
   11 {
   12     [ ExternalDataExchange]
   13      public  interface  ILeaveInterface
   14     {
   15          event  EventHandler< LeaveArgs> LeaveApprove;
   16 
   17          void UpdateLeaveApproverByLeaveId( int leaveId,  int leaveApprover);
   18          void UpdateLeaveStatusByLeaveId( int leaveId,  LeaveStatusEnum leaveStatus);
   19     }
   20 }
  2、在Eallies.OA.Workflow.Args项目中添加一个Class项目,用于实现自定义的EventArgs。实现自定义的EventArgs的意义在于,在我们审批请假单时,需要传入请假单的审批人和状态等信息,但一个事件只能接受sender和e两个参数,实现这个自定义的EventArgs后,我们就可以将无限量的参数通过e这个参数传入了。
    1  using System;
    2  using System.Collections.Generic;
    3  using System.Linq;
    4  using System.Text;
    5  using System.Workflow.Activities;
    6  using Eallies.OA.Info;
    7  using Eallies.OA.Info.Enum;
    8 
    9  namespace Eallies.OA.Workflow.Args
   10 {
   11     [ Serializable]
   12      public  class  LeaveArgs :  ExternalDataEventArgs
   13     {
   14          private  LeaveApproveResultEnum _LeaveApproveResult;
   15          private  EmployeeInfo _EmployeeInfo;
   16 
   17          public  LeaveApproveResultEnum LeaveApproveResult
   18         {
   19              get {  return  this._LeaveApproveResult; }
   20              set {  this._LeaveApproveResult =  value; }
   21         }
   22 
   23          public  EmployeeInfo EmployeeInfo
   24         {
   25              get {  return  this._EmployeeInfo; }
   26              set {  this._EmployeeInfo =  value; }
   27         }
   28 
   29          public LeaveArgs( Guid instanceId,  LeaveApproveResultEnum leaveApproveResult,  EmployeeInfo employeeInfo)
   30             :  base(instanceId)
   31         {
   32              this._LeaveApproveResult = leaveApproveResult;
   33              this._EmployeeInfo = employeeInfo;
   34         }
   35     }
   36 }
  3、在Eallies.OA.Workflow项目下添加一个State Machine Workflow项目。

  4、进入该Workflow的后台代码编辑界面,添加LeaveId、EmployeeInfo和LeaveApproveResult属性,分别用于保存请假单号、当前操作人信息和审核结果信息。
    1          public  Int32 LeaveId
    2         {
    3              get {  return ( Int32)GetValue(LeaveIdProperty); }
    4              set { SetValue(LeaveIdProperty,  value); }
    5         }
    6 
    7          public  static  readonly  DependencyProperty LeaveIdProperty =
    8              DependencyProperty.Register( "LeaveId"typeof( Int32),  typeof( LeaveWorkflow));
    9 
   10          public  EmployeeInfo EmployeeInfo
   11         {
   12              get {  return ( EmployeeInfo)GetValue(EmployeeInfoProperty); }
   13              set { SetValue(EmployeeInfoProperty,  value); }
   14         }
   15 
   16          public  static  readonly  DependencyProperty EmployeeInfoProperty =
   17              DependencyProperty.Register( "EmployeeInfo"typeof( EmployeeInfo),  typeof( LeaveWorkflow));
   18 
   19          public  LeaveApproveResultEnum LeaveApproveResult
   20         {
   21              get {  return ( LeaveApproveResultEnum)GetValue(LeaveApproveResultProperty); }
   22              set { SetValue(LeaveApproveResultProperty,  value); }
   23         }
   24 
   25          public  static  readonly  DependencyProperty LeaveApproveResultProperty =
   26              DependencyProperty.Register( "LeaveApproveResult"typeof( LeaveApproveResultEnum),  typeof( LeaveWorkflow));
  5、回到该Workflow的设计界面中,从工具栏上拖入4个StateActivity,分别命名为Initial、Setting、Waiting和Completed。在名为Initial的StateActivity上右键,选择Set as Initial State,在名为Completed的StateActivity上右键,选择Set as Completed State。

  6、在名为Initial的StateActivity中,从工具栏中拖入一个StateInitializationActivity,并双击进入该Activity的设计界面。
  在这个设计界面中,从工具栏拖入一个SetStateActivity,并设置其TargetStateName属性为Setting。这意味着,一启动该Workflow,则首先进入设置状态。

  7、在名为Setting的StateActivity中,从工具栏中拖入一个EventDrivenActivity,并双击进入该Activity的设计界面。
  在这个设计界面中,从工具栏拖入一个DelayActivity,在其下再拖入一个IfElseActivity。
  点击IfElseActivity的左边分支,并设置其Condition属性为Code Condition。这时,Condition属性前面出现一个加号图标,点击该图标,设置下面的Condition为CheckEmployeeManager。这时进入后台代码编辑器。
    1          private  void CheckEmployeeManager( object sender,  ConditionalEventArgs e)
    2         {
    3              try
    4             {
    5                 e.Result = ( this.EmployeeInfo.EmployeeManager.HasValue ==  true);
    6             }
    7              catch
    8             {
    9                  throw;
   10             }
   11         }
  上面的代码意味着,如果该EmployeeInfo的EmployeeManager属性有值,即不是最高领导,则执行IfElseActivity的左边分支,否则执行右边分支。
  8、回到前面的EventDrivenActivity的设计界面,从工具栏中拖入一个CallExternalMethodActivity到左边分支,设置其IInterfaceType属性为Eallies.OA.Workflow.Interface.ILeaveInterface,MethodName属性为UpdateLeaveApproverByLeaveId,leaveId属性为Activity=LeaveWorkflow, Path=LeaveId,leaveApprover属性为Activity=LeaveWorkflow, Path=EmployeeInfo.EmployeeManager.Value。该CallExternalMethodActivity用于设置该请假单的审批人。
  与上面的操作相似,再拖入一个CallExternalMethodActivity,并设置属性。该CallExternalMethodActivity用于设置该请假单的状态。
  与前面的操作相似,再拖入一个SetStateActivity,并设置其TargetStateName属性为Waiting。这意味着,设置完属性后,等待下一次领导审批事件。
  右边分支的设置类似。

  9、与上述7~8步骤类似,设置名为Waiting的StateActivity。

  10、至此Workflow设置完毕。








本文转自 Eallies 51CTO博客,原文链接:http://blog.51cto.com/eallies/79051,如需转载请自行联系原作者

目录
相关文章
|
开发者 开发工具 定位技术
|
1月前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库
|
5月前
|
C#
浅谈WPF之装饰器实现控件锚点
使用过visio的都知道,在绘制流程图时,当选择或鼠标移动到控件时,都会在控件的四周出现锚点,以便于修改大小,移动位置,或连接线等,那此功能是如何实现的呢?在WPF开发中,想要在控件四周实现锚点,可以通过装饰器来实现,今天通过一个简单的小例子,简述如何在WPF开发中,应用装饰器,仅供学习分享使用,如有不足之处,还请指正。
66 1
|
9月前
|
C# Windows
WPF技术之图形系列Polygon控件
WPF Polygon是Windows Presentation Foundation (WPF)框架中的一个标记元素,用于绘制多边形形状。它可以通过设置多个点的坐标来定义多边形的形状,可以绘制任意复杂度的多边形。
480 0
|
9月前
|
C# Windows
WPF技术之RichTextBox控件
WPF RichTextBox是Windows Presentation Foundation (WPF)中提供的一个强大的文本编辑控件,它可以显示富文本格式的文本,支持多种文本处理操作。
355 0
|
5月前
|
前端开发 C# 容器
浅谈WPF之控件拖拽与拖动
使用过office的visio软件画图的小伙伴都知道,画图软件分为两部分,左侧图形库,存放各种图标,右侧是一个画布,将左侧图形库的图标控件拖拽到右侧画布,就会生成一个新的控件,并且可以自由拖动。那如何在WPF程序中,实现类似的功能呢?今天就以一个简单的小例子,简述如何在WPF中实现控件的拖拽和拖动,仅供学习分享使用,如有不足之处,还请指正。
116 2
|
9月前
|
数据挖掘 数据处理 C#
WPF技术之DataGrid控件
WPF DataGrid是一种可以显示和编辑数据的界面控件。它可以作为表格形式展示数据,支持添加、删除、修改、排序和分组操作。
189 0