上一节我们学习了怎样通过参数传递数据,这节我们就说说通过事件传递数据的方法,由于这节除了我们自己写的一部分代码外,还需要用到另外需要触发事件的ExpenseApplication外部应用程序和所用事件示例代码,所以请下载示例程序源代码,根据需要添加项目的引用。
另外,我们将学习到怎样使用if/else 根据条件处理工作流 ,还将学习根据定制活动有条件的处理工作流。我们将在制作一个简单的处理费用支出报表的工作流中学习到这些概念。当工作流在报表数据提交的时候将接收到一个事件,这个事件的参数将把包含实际的费用支出报表数据提交到进程。如果报表的支出费用少于1000,工作流将自动提交,否则,将自动拒绝。
首先,创建一个名称为ExpenseWorkflows的空工作流项目。
添加一个含有单独代码的顺序工作流。默认名称就叫Workflow1.xoml
我们将使用HandleExternalEvent 和 CallExternalMethod 这两个活动来和支出报表建立联系,在这之前,先给我们的解决方案添加一个现有项目ExpenseLocalServices(从下载的源代码中可以找到这个项目),然后给我们的项目ExpenseWorkflows添加一个引用,引用这个现有项目。
添加提交支出报表的活动
1. 在Workflow1这个类中我们需要添加两个成员变量供将来使用,一个变量名称为reportArgs,用于接收报表提交这个事件的参数对象。另外一个变量将保存报表的支出费用。
(Snippet: Lab01_Ex03_Task03_MemberVariables)
public partial class Workflow1 : SequentialWorkflowActivity
{
public ExpenseLocalServices.ExpenseReportSubmittedEventArgs reportArgs =
default(ExpenseLocalServices.ExpenseReportSubmittedEventArgs);
public int amount = default(System.Int32);
}
2. 打开workflow1.xoml的设计视图。
3. 从工具箱中找到HandleExternalEvent 这个活动拖拽到我们的工作流设计视图中,将其Name属性设置为expenseReportSubmitted1。如图:
4. 点击红色的叹号选择Property ‘InterfaceType’ is not set.来设置InterfaceType属性。
5. 点击[…]按钮将出现 .NET Type Browser 对话框。从引用程序集目录树中选择 ExpenseLocalServices.IExpenseService 。如下图所示:
6.现在我们的工作流设计视图expenseReportSubmitted1上还有一个叹号,是因为我们的EventName还没有设置。同样点选它,设置EventName属性。点击下拉列表框,选择ExpenseReportSubmitted。
7.继续设置expenseReportSubmitted1的属性,找到e这个属性,点[…]按钮,选择Bind to an existing member选项卡下的Workflow1---reportArgs.也就是把这个提交事件的e参数和我们定义的成员变量reportArgs绑定。
8.双击设计视图中的expenseReportSubmitted1创建Invoked事件。
(Snippet: Lab01_Ex03_Task03_ReportSubmittedInvoked)
public void ReportSubmitted_Invoked(object sender, EventArgs e)
{
Console.WriteLine("ReportSubmitted_Invoked");
//给我们的成员变量amount设置事件触发得到的值
this.amount = this.reportArgs.Report.Amount;
}
添加自动审批活动到我们的工作流
1. 我们将添加一个定制活动(我们还没学到怎么定制活动,所以先直接引用做好的定制活动吧,在下载的源代码里的ExpenseActivities,可以看一下,其实很容易理解,就象我们做定制控件。:))来判断所做的提交是否进行自动审批。
2. 单击工具|选择工具箱项
3. 选择 .NET Framework组件 选项卡并单击浏览…
4. 导航到我们代码源文件的ExpenseWorkflows\ExpenseActivities\bin\Debug\ExpenseActivities.dll.将其添加。
5. 现在我们的工具箱会多一个新的选项卡叫做ExpenseActivities,里面有两个新的活动:AutoApprove 和 GetManager。
6. 现在把我们把一个新的定制活动AutoApprove拖拽到我们的工作流设计视图。
7. 现在我们的工作流设计视图有两个活动,如图:
8. 在设计视图中选择活动autoApprove1 ,设置其Amount属性,绑定到Workflow1.amount。
给工作流添加条件
1. 从工具箱中找到IfElse活动拖拽到设计视图中autoApprove1的下面。
2. 将其(Name)属性设置为EvaluateExpenseReport。
3. 选择IfElse左边活动分支设置:(Name属性设置为IfAutoApproveReport;Condition属性设置为Declaritive Rule Condition。
4. 展开Condition的“+”,设置其中的ConditionName属性为AutoApproveCondition。
5. 对Expression属性编辑表达式:this.autoApprove1.Approved。如图:
6. 选择EvaluateExpenseReport右边的活动分支将其(Name)属性改为ElseRejected.
给支出报表是否通过添加逻辑判断
1. 从工具箱中选择CallExternalMethod活动添加到标签为IfAutoApproveReport的条件分支里面,设置这个活动(Name)属性为approveExpenseReport1。
2. 象上面我们设置HandleExternalEvent活动时一样,我们把InterfaceType属性按照相同的方法设置成ExpenseLocalService.IExpenseService。
3. MethodName属性选择下拉列表框中的ApproveExpenseReport方法。
4. 同样的,我们还要设置properties属性,选择report,设置如下所示:
5. 现在,左边的IfAutoApproveReport条件分支我们配置完毕了。接下来配置右边的条件分支ElseRejected。
6. 添加另一个CallExternalMethod活动到ElseRejected,设置Name属性为rejectExpenseReport1。
7. 选择InterfaceType属性设置为:ExpenseLocalService.IExpenseService。
8. 选择MethodName属性设置为:RejectExpenseReport。
9. 选择Report属性绑定到:reportArgs.Report.
10. 现在我们的工作流设计视图如图所示:
调试工作流
到现在,我们的工作流就做完了。接下来我们要调试它,看他的执行过程。
不过,这里我们还需要借助两个项目,来触发我们所做的工作流事件。
1.进入ExpenseWorkflows\ExpenseHost\bin\Debug目录,复制ExpenseHost.exe 和ExpenseHost.exe.config到我们的项目文件目录:ExpenseWorkflows\ExpenseWorkflows\bin\Debug。
还有ExpenseWorkflows\ExpenseApplication\这个项目(一会调试用)。
2. 现在需要配置我们的ExpenseWorkflows项目,将其设置为启动项目,然后右击项目选择属性,选择调试,在启动操作选择“启动外部程序”,浏览到ExpenseWorkflows\ExpenseWorkflows\bin\Debug\ExpenseHost.exe。
3. 现在可以按F5启动调试了,当然,为了看整个项目的执行过程,我们可以给各个工作流和其他感兴趣的位置设置断点来详细学习工作流的执行过程。
Task 7 – Test the Expense Reporting Workflow
测试支出报表工作流
1. Compile and run the ExpenseWorkflows project under the Visual Studio debugger by pressing F5 or selecting the Debug | Start Debugging menu command.
2. 点F5启动调试,将显示如下界面,执行ExpenseHost命令行程序。
4. 运行 ExpenseApplication.exe (在如下目录:ExpenseWorkflows\ExpenseApplication\bin\Debug)。
我们提交一条报表数据,金额填写了1500,
5. 在VS2005给活动 expenseReportSubmitted1设置断点
6. 然后单步执行可以看到 ReportSubmitted_Invoked 事件处理的代码.
7. 继续单步执行到活动 rejectExpenseReport1 。
8. 看到我们的支出报表请求被拒绝了,这里会调用方法我们设置的RejectExpenseReport来更新刚才我们的那条report记录,将起状态设置为拒绝。
9. 我们可以看到应用程序状态
10. 点击Refresh Reports
变成了拒绝(Rejected)。
11. 如果输入小于1000的数,会看到
12. 状态为通过。
大家可以仔细阅读一下这些项目的代码,然后调试一遍,应该就能了解其中工作的过程和工作流中HandleExternalEventActivity和CallExternalMethodActivity的使用方法了。