工作流-----WorkFlow
我们都知道对于一个OA系统来说,最重要的也是不可或缺的一个重要环节那就是对于工作流的实现,为此,最近专门在学习如何使用WorkFlow,问前辈,前辈也说道K2工作流引擎挺不错,自己同时也翻阅了一些资料,但因为自己这个OA项目主要是采用微软的ASP.NET MVC 来开发的,所以还是决定使用微软的那一套WorkFlow工作流引擎。不得不说,微软在对于客户体验这方面做的还真是不错的。为了方面学习,我也是通过一个小案例来学习WorkFlow,在这里也拿出来和大家共同分享学习。
小案例(请假工作流)
说明:
1.程序集:system.Activities
2.Xaml文件:工作流文件设计的类型,最终会被处理为一个类
3.状态机工作流(开发中使用的类型)
首先:创建一个Windows窗体应用程序,命名WorkFlowDemo

注意:为了便于工作流的展示,把当前项目的属性-----》服务,把输入类型由Windows应用程序改为控制台应用程序

接下来,简单点设计一下窗体页面

设计一下流程图:(状态机控件在工具箱)对于其中的工具使用,可以自己简单学习,很容易上手

前期工作完成接下来就是代码实现的时候了,为窗体的单击按钮注册事件
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Activities; namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} //创建一个工作流对象
WorkflowApplication wfapp;
private void btnsave_Click(object sender, EventArgs e)
{ //1.准备好工作流中需要的参数
Dictionary<string, object> dict = new Dictionary<string, object>();//用来向工作流传递参数
dict.Add("LeaveDays", int.Parse(txtDays.Text)); //2.创建一个工作流应用对象
wfapp = new WorkflowApplication(new LeaveActivity(), dict); //3.调用wfapp对象的Run方法
wfapp.Run();
} private void btnjinli_Click(object sender, EventArgs e)
{
bool result = radioButton1.Checked; //唤醒书签
wp.ResumeBookmark("经理审批", result);
} private void button2_Click(object sender, EventArgs e)
{
bool result = radioButton3.Checked;
wp.ResumeBookmark("财务总监审批", result);
}
}
}
这时,产生了工作流中一个重要的内容------书签(BookMark)
场景:在实际业务场景中,流程一般都是复杂的,不会一口气从开始走到最后,当在某一个需要暂停的时候,这时,书签很好的充当了这个使者,就好像我们平时看书,看到某一页突然有事要离开,但办完事回来还是要接着看的对不对,通常我们会在暂停的位置放置一个标签,等我们下次继续翻阅,可以很快的知道上一次暂停的位置。
步骤:
1.在项目中添加一个代码活动(CodeActivity),
【注意】
- 将继承的CodeActivity父类改成NativeActivity,
- 同时将Execute方法中的参数也要修改为NatveActivityContext
- 重写父类的CanIncludeIdIe属性
2.在该代码活动的Execute方法里创建书签
代码实现:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities; namespace WindowsFormsApplication1
{ public sealed class WaitProcess :NativeActivity
{
//输出型参数
public OutArgument<bool> Result { get; set; }
//输入型参数
public InArgument<string> BookMarkName { get; set; }
//重写父类的CanIncludeIdIe属性
protected override bool CanInduceIdle
{
get
{
return true;
}
} protected override void Execute(NativeActivityContext context)
{
//创建书签
context.CreateBookmark(context.GetValue(BookMarkName), FunCallBack);
} private void FunCallBack(NativeActivityContext context, Bookmark bookmark, object value)
{ Console.WriteLine("工作流被唤醒"); context.SetValue(Result,Convert.ToBoolean(value));
} }
}
操作结果:
点击提交申请

点击第一个审批(因为我在流程图那边设置了当天数<6时,经理审批同意后直接结束)

别急,做到这里,也只是完成了三分之一,因为你会发现当你点击提交申请,这时,关闭整个应用程序,当你下次访问,点击审批的时候,会报错,

这是为什么呢?因为你点击提交申请后退出,这时整个WorkFlowApplication对象也会被销毁,那么问题来了,如何做到工作流实例的具体化?
方案有很多种,你可以采用xml文件保存,也可以把它保存到数据库,而我将采取后面那种方式,那么你又会说了,数据库我该怎么设计,别担心,微软已经帮我们写好了SQL脚本,你只需要找到它们并执行一下就好了。
步骤:
步骤:
- 建立数据表
在C:\Windows\Microsoft.NET\Framework\v4.0.30319\SQL\en中可以找到两个微软写好的数据库脚本

然后数据库中先执行后者脚本,在执行前者脚本
将工作流对象往数据库中存储
引入命名空间:
using System.Activities.DurableInstancing;
using System.Runtime.DurableInstancing;
- 什么时候持久化工作流对象?
在工作流创建之后,为工作流对象注册一个事件:
wfapp.PersistableIdle += a => { return PersistableIdleAction.Unload; };
- 创建一个SqlWorkFlowInstanceStore对象
SqlWorkflowInstanceStore ss = new SqlWorkflowInstanceStore("server=.;daabase=WorkFlow;uid=sa;pwd=123;");
关联持久化的工作流对象和具体的存储实例
wfapp.InstanceStore = ss;
- 如何从数据库中加载未完成的工作流实例
创建一个存储实例对象和一个工作流对象,并将它们进行关联,
注意:重新new的WorkFlowApplication对象也要重新注册wfapp.PersistableIdle += a => { return PersistableIdleAction.Unload; };这个事件
最后调用WorkFlowApplication对象的Load(Guid guid)方法
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Activities;
using System.Activities.DurableInstancing;
using System.Runtime.DurableInstancing; namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
WorkflowApplication wfapp;
private void btnsave_Click(object sender, EventArgs e)
{ //1.准备好工作流中需要的参数
Dictionary<string, object> dict = new Dictionary<string, object>();//用来向工作流传递参数
dict.Add("LeaveDays", int.Parse(txtDays.Text));
//2.创建一个工作流应用对象
wfapp = new WorkflowApplication(new LeaveActivity(), dict); //在工作流创建之后,为工作流对象注册一个事件
wfapp.PersistableIdle += a => { return PersistableIdleAction.Unload; }; //关联持久化的工作流对象和具体的存储实例
SqlWorkflowInstanceStore ss = new SqlWorkflowInstanceStore("server=.;daabase=WorkFlow;uid=sa;pwd=123;");
wfapp.InstanceStore = ss;
//3.调用wfapp的Run方法
wfapp.Run();
} private void button1_Click(object sender, EventArgs e)
{ //从数据中加载实例
SqlWorkflowInstanceStore ss = new SqlWorkflowInstanceStore("server=.;daabase=WorkFlow;uid=sa;pwd=123;");
wfapp = new WorkflowApplication(new LeaveActivity());
wfapp.PersistableIdle += a => { return PersistableIdleAction.Unload; };
wfapp.InstanceStore = ss;
//wfapp.Load("CA15C81C-FE95-4B0B-B1F4-B5F1478BEF3C");//传入的是一个guid参数
bool result = radioButton1.Checked;
//唤醒书签
wfapp.ResumeBookmark("经理审批", result);
}
}
}
效果图:

你会发现在你的数据库表中多了一条记录,这时记录了你上一次未完成的操作(把这个Guid复制下来,放到按钮1审批的代码中Load方法中)因为是做测试用


第二次在运行,直接点击经理审批对应的审批按钮,你会发现:

同时数据库中的记录也不见了

好了,具体实现就这么多了,但是还存在一个问题,那就是对于某个按钮事件,你会发现重复性的代码太多了,不妨就自己去进行封装吧!做成一个属于自己的Helper!
最后,非常希望大家可以提出批评和建议。谢谢!
工作流-----WorkFlow的更多相关文章
- openerp经典收藏 深入理解工作流(Workflow)(转载)
深入理解工作流(Workflow) 原文:http://shine-it.net/index.php/topic,2494.0.html 一.工作流定义:<?xml version=" ...
- 深入理解OpenERP的工作流(Workflow)
一.工作流定义: <?xml version="1.0"?> <terp><data> <record model="w ...
- SharePoint2013工作流workflow manager配置
SharePoint2013版本的工作流较sharepoint 2010变化较大,将工作流部分从sharepoint中分离出来为单独的服务,通过与sharepoint关联使用. SharePoint2 ...
- 【转】Odoo开发之:工作流 workflow
在OpenERP中,工作流是管理一组“所做的事情”(与一些数据模型的记录关联)的人为现象.工作流提供了高级别的方式来组织记录要上做的事情. 具体地说,工作流是一个定向的路径,这里节点称为活动并且弧线称 ...
- Asp.net工作流workflow实战之工作流启动与继续(三)
工作流帮助类: //让工作流继续沿着书签的位置向下执行value是向书签传递参数 wfc.ResumeBookmark(bookmarkName,value); //把传过来的数据value作为输出参 ...
- Asp.net工作流workflow实战之书签(二)
1.winform(web程序)下使用工作流 怎样才能像控制台那样让winform或web页面窗体阻塞等待工作流的继续执行呢 2.BookMark书签 书签:和一般的书签看书的时候方便查看上次看的内容 ...
- Asp.net工作流workflow实战(一)
最近开发一个项目用到了工作流引擎,之前研究过微软的workflow所有就用它了,距离上次用有一段时间了,好多东西有点模糊了,就在此处一遍写代码一遍回忆. 首先,在我的项目中新建了.netframwor ...
- Asp.net工作流workflow实战之给书签命名(四)
之前我们的书签名字是通过手动录入的方式,在实际开发中要在流程设计的时候定义好: namespace EazyBPMS.WorkFlow { public sealed class SetStepAct ...
- 一、activiti工作流(workflow)入门介绍
activiti官方网站(官网通常很卡,不建议看,直接看我教程就行) http://www.activiti.org/ eclipse离线安装activiti插件并下载教程 https://downl ...
随机推荐
- [agc014d] Black and White Tree
Description 有一颗n个点的树,刚开始每个点都没有颜色. Alice和Bob会轮流对这棵树的一个点涂色,Alice涂白,Bob涂黑,Alice先手. 若最后存在一个白点,使得这个 ...
- 【bzoj3601】一个人的数论 莫比乌斯反演+莫比乌斯函数性质+高斯消元
Description Sol 这题好难啊QAQ 反正不看题解我对自然数幂求和那里是一点思路都没有qwq 先推出一个可做一点的式子: \(f(n)=\sum_{k=1}^{n}[(n,k)=1]k^d ...
- centos 在vm下网络不通
VMware是一款虚拟机,支持各种热门系统,我们可以在VMware虚拟机中安装其他系统以满足个人需求,但在为VMware安装CentOS6.5后,无法连接网络,这是什么原因导致的呢?下面就给大家介绍下 ...
- SVN Unable to connect to a repository at URL 不知道这样的主机: 问题解决
工具是eclipse Maven ,搭建好项目的框架后上传SVN出现如下错误: 不知道这样的主机. svn: Unable to connect to a repository at URL 'ht ...
- 老男孩Day17作业:后台管理平台编辑表格
一.作业需求: 后台管理平台 ,编辑表格: 1. 非编辑模式: 可对每行进行选择: 反选: 取消选择 2. 编辑模式: 进入编辑模式时如果行被选中,则被选中的行万变为可编辑状态,未选中的不改变 退出编 ...
- docker加速器配置
我使用docker的原因 最近自己一直在强迫自己使用docker,一方面是docker的容器化服务,使得每一个配置相互独立,易于维护.而且如果到后面如果深入了的话,通过自己编写dockerfile,那 ...
- springcloud整合bus
bus的使用主要是配合springcloud config部分来一起使用,并没有单独使用 首先建立服务端: <dependency> <groupId>org.springfr ...
- LeetCode215. 数组中的第K个最大元素
215. 数组中的第K个最大元素 问题描述 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 示例 1: 输入: [3 ...
- 【2-SAT】【并查集】NOIp模拟题 植树方案 题解
一个类似2-SAT的思想,但是简化了很多.只需要用到并查集实现. 题目描述 企鹅国打算种一批树.所谓树,就是由$N$个结点与$N-1$条边连接而成的连通无向图.企鹅国的国王对于这些树有下列要求 ...
- Codeforces - 240F 是男人就上26棵线段树
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5+11; typedef long long ll; ch ...