一、动态添加或移除工作流活动

  首先添加一个顺序的空白工作流。

  

  然后添加一个Winform程序,界面如下:

  

  代码如下:

namespace WinForm
{
public partial class Form1 : Form
{
private WorkflowRuntime workflowRuntime = null;
private WorkflowInstance workflowInstance = null;
private WorkflowChanges wfchange = null; public Form1()
{
InitializeComponent();
workflowRuntime = new WorkflowRuntime();
workflowRuntime.StartRuntime();
} private void button1_Click(object sender, EventArgs e)
{
Type type = typeof(WorkflowConsoleApplication1.Workflow1);
workflowInstance = workflowRuntime.CreateWorkflow(type);
Activity Act = workflowInstance.GetWorkflowDefinition();
wfchange = new WorkflowChanges(Act); CodeActivity code1 = new CodeActivity("codeactivity1");
code1.ExecuteCode += delegate(object s, EventArgs ea)
{
MessageBox.Show("工作流被调用!");
};
wfchange.TransientWorkflow.Activities.Insert(, code1);
} private void button2_Click(object sender, EventArgs e)
{
workflowInstance.ApplyWorkflowChanges(wfchange);
workflowInstance.Start();
}
}
}

  效果如下:

  

二、动态添加或移除容器活动

  向工作流的容器类型复合活动中动态添加一个子活动。

  添加一个Sequence容器,然后通过代码向其内部动态添加一个Code类型的子活动。

  

  添加一个Winform程序,界面不变:

namespace WinForm
{
public partial class Form1 : Form
{
private WorkflowRuntime workflowRuntime = null;
private WorkflowInstance workflowInstance = null;
private WorkflowChanges wfchange = null; public Form1()
{
InitializeComponent();
workflowRuntime = new WorkflowRuntime();
workflowRuntime.StartRuntime();
} //添加一个工作流
private void button1_Click(object sender, EventArgs e)
{
Type type = typeof(WorkflowConsoleApplication1.Workflow1);
workflowInstance = workflowRuntime.CreateWorkflow(type);
Activity Act = workflowInstance.GetWorkflowDefinition();
wfchange = new WorkflowChanges(Act); //创建一个Code活动
CodeActivity code1 = new CodeActivity("codeactivity1");
code1.ExecuteCode += delegate(object s, EventArgs ea)
{
MessageBox.Show("sequenceActivity里的Code工作流被调用!");
}; //添加工作流到容器中
SequenceActivity seq = (SequenceActivity)wfchange.TransientWorkflow.Activities["sequenceActivity1"];
seq.Activities.Add(code1);

} //移除一个工作流
private void button3_Click(object sender, EventArgs e)
{
Activity Code1 = wfchange.TransientWorkflow.Activities["codeactivity1"];
SequenceActivity seq = (SequenceActivity)wfchange.TransientWorkflow.Activities["sequenceActivity1"];
seq.Activities.RemoveAt(0
);
} //执行
private void button2_Click(object sender, EventArgs e)
{
workflowInstance.ApplyWorkflowChanges(wfchange);
workflowInstance.Start();
}
}
}

  改动的部分就是红色部分代码,添加删除一个活动一样是Add、Remove。

三、动态修改判断条件

  在WWF提供的各种活动空间中,像IfElse和While这两种基于规则模式的活动是需要设置其逻辑判断条件的。该判断条件分为两种类型,一种是"Code Condition",利用程序代码来定义其逻辑的判断条件,另外一种是"Declarative Rule Condition"。

  首先建立一个顺序类型的工作流项目,然后添加一个IfElse活动到该工作流设计界面,将IfElse活动空间的两条分支分别命名为"IfBranch"和"ElseBranch"。每条分支添加一个Code活动控件。工作流界面如下:

  

  将默认的判断条件设置为如下:

  

  工作流代码如下:

    public sealed partial class Workflow1 : SequentialWorkflowActivity
{
public int condition;
public int Condition
{
get { return condition; }
set { condition = value; }
} public Workflow1()
{
InitializeComponent();
} private void Code1(object sender, EventArgs e)
{
MessageBox.Show("If分支被执行!");
} private void Code2(object sender, EventArgs e)
{
MessageBox.Show("Else分支被执行!");
}
}

  创建一个Winform程序,界面如下:

  

  代码如下:

namespace WinForm
{
public partial class Form1 : Form
{
private WorkflowRuntime workflowruntime;
private WorkflowInstance workflowinstance; public Form1()
{
InitializeComponent();
workflowruntime = new WorkflowRuntime();
workflowruntime.StartRuntime();
} //添加一个工作流
private void button1_Click(object sender, EventArgs e)
{
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("Condition", Convert.ToInt32(this.textBox2.Text));
Type wftype = typeof(WorkflowConsoleApplication1.Workflow1);
workflowinstance = workflowruntime.CreateWorkflow(wftype, parameters);
//WWF对所有运行中的工作流都可以通过"WorkflowChanges"对象来实现修改
//GetWorkflowDefinition得到工作流活动的集合
WorkflowChanges workflowchanges = new WorkflowChanges(workflowinstance.GetWorkflowDefinition());
//将工作流所有的活动进行克隆,克隆出来的对象保存在comactivity中
CompositeActivity comactivity = workflowchanges.TransientWorkflow;
//RunleDefinitions类专门用于对".rules"文件进行操作
RuleDefinitions ruleDefinitions = (RuleDefinitions)comactivity.GetValue(RuleDefinitions.RuleDefinitionsProperty);
//获取所有的逻辑判断集合
RuleConditionCollection conditions = ruleDefinitions.Conditions;
//从Condition对象中获取具体的"Condition1"逻辑判断的信息,"Condition1"以"Declarative Rule Condition"方式定义判断条件的名称
RuleExpressionCondition condition1 = (RuleExpressionCondition)conditions["Condition1"];
//对原工作流的condition1逻辑判断条件进行修改
(condition1.Expression as CodeBinaryOperatorExpression).Right = new CodePrimitiveExpression(Convert.ToInt32(this.textBox1.Text));
//将修改后的信息应用回工作流实例
workflowinstance.ApplyWorkflowChanges(workflowchanges);
//重新启动工作流
workflowinstance.Start();
}
}
}

  运行效果如下:

   

  留意到判断条件已经完全改为为Winform中的判断条件。

四、动态添加StateActivity活动

  在状态机工作流中同样可以动态加载或修改原有的业务流程。

  首先定义一个接口如下:

    [ExternalDataExchange]
public interface IClass
{
//入党申请
event EventHandler<ExternalDataEventArgs> AdmittedIntoParty;
//介绍人意见
event EventHandler<ExternalDataEventArgs> SponsorCommit;
//党委会审批
event EventHandler<ExternalDataEventArgs> PCApproved;
}

  新建一个状态机工作流如下:

  

  前两个EventDriven里面添加两个HandleExternalEvent,并绑定刚刚定义的接口里的事件。

  

  新建一个Winform程序如下:

  

  从上至下分别是button1、2、3、4。

  代码如下:

namespace WinForm
{
public partial class Form1 : Form, ClassLibrary1.IClass
{
private WorkflowRuntime workflowruntime;
private WorkflowInstance workflowinstance;
private ExternalDataExchangeService exterserv; public event EventHandler<ExternalDataEventArgs> AdmittedIntoParty;
public event EventHandler<ExternalDataEventArgs> SponsorCommit;
public event EventHandler<ExternalDataEventArgs> PCApproved; public Form1()
{
InitializeComponent(); workflowruntime = new WorkflowRuntime();
exterserv = new ExternalDataExchangeService(); workflowruntime.AddService(exterserv);
exterserv.AddService(this); workflowruntime.StartRuntime(); Type wftype = typeof(WorkflowConsoleApplication1.Workflow1);
workflowinstance = workflowruntime.CreateWorkflow(wftype);
workflowinstance.Start();
} private void Form1_Load(object sender, EventArgs e)
{
SetStateComboBox();
} private void SetStateComboBox()
{
comboBox1.Items.Clear(); StateMachineWorkflowInstance StateMachineInstance = new StateMachineWorkflowInstance(workflowruntime, workflowinstance.InstanceId); ReadOnlyCollection<StateActivity> states = StateMachineInstance.States; foreach (StateActivity allState in states)
{
this.comboBox1.Items.Add(allState.Name);
}
} private void button1_Click(object sender, EventArgs e)
{
AdmittedIntoParty(null, new ExternalDataEventArgs(workflowinstance.InstanceId));
this.button1.Enabled = false;
} private void button2_Click(object sender, EventArgs e)
{
Activity root = workflowinstance.GetWorkflowDefinition();
WorkflowChanges changes = new WorkflowChanges(root); //创建一个状态活动
StateActivity sponsorsubmit = new StateActivity();
sponsorsubmit.Name = "介绍人提交意见"; //创建一个EventDrivenActivity
EventDrivenActivity sponsoreven = new EventDrivenActivity();
sponsoreven.Name = "SponsorEvent";
//向状态活动中添加EventDrivenActivity
sponsorsubmit.Activities.Add(sponsoreven); //创建一个HandleExternalEventActivity
HandleExternalEventActivity sponsorHandle = new HandleExternalEventActivity();
sponsorHandle.Name = "SponsorHandle";
sponsorHandle.InterfaceType = typeof(ClassLibrary1.IClass);
sponsorHandle.EventName = "SponsorCommit";
//sponsorHandle.Invoked +=new EventHandler<ExternalDataEventArgs>(sponsorHandle_Invoked);
//向EventDrivenActivity中添加HandleExternalEventActivity活动
sponsoreven.Activities.Add(sponsorHandle); //向EventDrivenActivity中添加SetStateActivity活动
SetStateActivity setSponsorapproved = new SetStateActivity();
//由于工作流是默认命名,所以1和2都已经存在
setSponsorapproved.Name = "setStateActivity3";
setSponsorapproved.TargetStateName = "党委会审批";
sponsoreven.Activities.Add(setSponsorapproved); //将状态活动添加进WorkflowChanges
changes.TransientWorkflow.Activities.Add(sponsorsubmit); //将动态加载的活动更新至工作流
workflowinstance.ApplyWorkflowChanges(changes); SetStateComboBox(); this.button2.Enabled = false;
} private void button3_Click(object sender, EventArgs e)
{
StateMachineWorkflowInstance stateInstance = new StateMachineWorkflowInstance(workflowruntime, workflowinstance.InstanceId);
stateInstance.SetState("介绍人提交意见"); SponsorCommit(null, new ExternalDataEventArgs(workflowinstance.InstanceId)); this.button3.Enabled = false;
this.button2.Enabled = false;
} private void button4_Click(object sender, EventArgs e)
{
PCApproved(null, new ExternalDataEventArgs(workflowinstance.InstanceId));
this.button1.Enabled = false;
this.button2.Enabled = false;
this.button4.Enabled = false;
}
}
}

  显示结果如下:

  

  当点击添加介绍人意见后,整个状态机工作流会在党委审批前,增加一个状态State,介绍人是否已提交意见。

1、取得工作流定义的对象,然后将它作为"WorkflowChanges"对象保存。
2、创建一个State对象,并设置其Name为"介绍人提交意见"。
3、往State内部添加一个EventDriven。
4、往EventDriven里面添加一个HandleExternalEvent子活动。并与接口中定义的事件进行绑定。
5、通过SetStateActivity活动的TargetStateName设置状态间的迁移关系,注意SetStateActivity活动也是EventDriven的子活动,也应该将它添加到EventDriven当中去。
6、将改动应用回工作流。

WWF3动态修改工作流<第九篇>的更多相关文章

  1. SpringBoot 定时任务升级篇(动态修改cron参数)

    需求缘起:在发布了<Spring Boot定时任务升级篇>之后得到不少反馈,其中有一个反馈就是如何动态修改cron参数呢?那么我们一起看看具体怎么实现,先看下本节大纲: ()简单方式:修改 ...

  2. 第九篇 Integration Services:控制流任务错误

    本篇文章是Integration Services系列的第九篇,详细内容请参考原文. 简介在前面三篇文章,我们创建了一个新的SSIS包,学习了脚本任务和优先约束,并检查包的MaxConcurrentE ...

  3. Python之路【第九篇】:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

    Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy   Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用 ...

  4. 【译】第九篇 Integration Services:控制流任务错误

    本篇文章是Integration Services系列的第九篇,详细内容请参考原文. 简介在前面三篇文章,我们创建了一个新的SSIS包,学习了脚本任务和优先约束,并检查包的MaxConcurrentE ...

  5. (转)Python成长之路【第九篇】:Python基础之面向对象

    一.三大编程范式 正本清源一:有人说,函数式编程就是用函数编程-->错误1 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的Python语法后,大家就可以写Python代码了,然后每个 ...

  6. 第九篇 SQL Server代理了解作业和安全

    本篇文章是SQL Server代理系列的第九篇,详细内容请参考原文 在这一系列的上一篇,学习了如何在SQL Server代理作业步骤启动外部程序.你可以使用过时的ActiveX系统,运行批处理命令脚本 ...

  7. 第九篇 :微信公众平台开发实战Java版之如何实现自定义分享内容

    第一部分:微信JS-SDK介绍 微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包. 通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统 ...

  8. 第九篇 Replication:复制监视器

    本篇文章是SQL Server Replication系列的第九篇,详细内容请参考原文. 复制监视器允许你查看复制配置组件的健康状况.这一篇假设你遵循前八篇,并且你已经有一个合并发布和事务发布.启动复 ...

  9. [老老实实学WCF] 第九篇 消息通信模式(上) 请求应答与单向

    老老实实学WCF 第九篇 消息通信模式(上) 请求应答与单向 通过前两篇的学习,我们了解了服务模型的一些特性如会话和实例化,今天我们来进一步学习服务模型的另一个重要特性:消息通信模式. WCF的服务端 ...

随机推荐

  1. FB Flash Builder 安装错误 ERROR: DW050: - Microsoft Visual C++ 2010 Redistributable Package (x86): Install failed

    这个问题很可能是你的 Microsoft Visual C++ 2010 Redistributable Package (x86) 太新的缘故,所以无法安装成功,导致最终的失败. 在控制面板-程序和 ...

  2. [转][色彩 A] – 永远不要使用纯黑

    原文地址:http://www.cgjoy.com/forum.php?mod=viewthread&tid=110762&extra=page%3D1%26filter%3Dtype ...

  3. 【初识】KMP算法入门(转)

    感觉写的很好,尤其是底下的公式,易懂,链接:http://www.cnblogs.com/mypride/p/4950245.html 举个例子 模式串S:a s d a s d a s d f a  ...

  4. unity c#

    gameObject //获取当前脚本挂载到的游戏对象 在Unity中就算使用了C#进行编写脚本,要输出时不能使用Console类,应当使用print();或者Debug.log(); transfo ...

  5. 并发编程之二:wait、notify、notifyAll的使用方法

    wait().notify().notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态. public final native void wait(long timeout ...

  6. 鼎信通达gsm网关和asterisk对接的调试

    设备型号:4gsm卡,型号是DWG2000C-4Egsm网关IP地址: 10.3.6.250asteriskIP地址: 10.3.6.251 1)首先在asterisk里面添加到gsm网关的中继,并做 ...

  7. CentOS7 MongoDB安裝

    查看MongoDB的最新版官方下载地址: https://www.mongodb.com/download-center#community 使用wget命令下载安装包 ? 1 wget https: ...

  8. list,set,map,数组之间的相互转换详细解析

    1.list转setSet set = new HashSet(new ArrayList()); 2.set转listList list = new ArrayList(new HashSet()) ...

  9. sublime 安装常用插件

    1.先要安装Package Control ,ctr+` 打开控制台,复制安装脚本,脚本在https://packagecontrol.io/installation#st3获取. 2.安装插件,ct ...

  10. lassen项目启动

    1.将代码从svn下载下来 2.在下载目录打开命令窗口 shift+鼠标右键 3.mvn  clean install mvn  eclipse:clean mvn  eclipse:eclipse