返回首页

在Visual Studio 2005创建顺序工作流的一个例子:?|作者注
这三个部分组成的文章,是一种适应创建顺序工作流()在MSDN库中发现的教程之一。重新制作同一样品的主要目的是让读者更清晰和执行步骤,以创建一个工作流的解释。我的朋友和社会的同龄人大多表示理解工作流创建过程中定义的步骤了浓浓的不满。他们列举了某些示例网页彻底不确切,不够明确,遵循的步骤。
MSDN教程包括三个练习功能在这些URL:{A}
在这篇文章中,保持完整的重大演习中,我已解释过,详细步骤,任务和编码部分,并包括一些图表,这样它会更容易为任何人都可以开始创建顺序工作流。简介
这个示例应用程序是一个简单的费用报告文本字段输入金额和一个按钮来提交的费用报告。工作流使用规则评估的数量,并要求率先批准,如果金额小于1000,或从经理的批准,如果金额大于或等于1000。如果是必要的,审批工作流通讯的应用程序,并显示一个下拉面板,包含批准和拒绝按钮。按一下其中一个按钮是时,应用程序响应工作流程的通知,并继续处理该事件的工作流程。
本演练包含三个主要步骤,每一步都下和子任务:创建费用报表项目。创建Windows应用程序创建顺序工作流主机的顺序工作流创建开支报告服务。定义工作流参数定义IExpenseReportService接口创建费用报告的顺序工作流类库 创建CallExternalMethod活动创建HandleExternalEvent活动1。创建费用报表项目创建Windows应用程序
在Visual Studio 2005,选择新项目; C#项目类型下,选择Windows应用程序。
更改默认窗体的名称"MainFormquot;项目显示,拖放控制,并设计下图中的的布局。
{S0}
下面是一个表的控制,并在形式定义其属性。
控制
属性



的MainForm简单的费用报告
标签

LABEL1
金额
标签

Label2的结果
的TextBox

量的TextBox

结果标签

ApprovalState批准
按钮

submitButton提交
按钮
approveButton

批准
按钮

rejectButton拒绝
面板

Panel1的
里面添加PANEL1 approveButton和rejectButton。
金额文本框的KeyPress和TextChanged事件添加两个事件处理方法。
确保您已经取代了在Program.cs的代码运行的应用程序的默认形式。{C}
最后,要完成这第一步,添加以下程序集的引用。System.Workflow.ActivitiesSystem.Workflow.ComponentModelSystem.Workflow.Runtime
生成应用程序。创建顺序工作流
在Visual Studio 2005,从菜单中选择新建项目,C#项目类型下,选择工作流,模板右侧面板上,选择"顺序工作流库。
名称的项目ExpenseReportWorkflow。
(Workflow1.designer.cs)在工作流设计文件默认情况下创建,修改代码中的IntializeComponent方法如下:

this.Name = "ExpenseReportWorkflow"; 

this.CanModifyActivities = false; 

生成项目。主机的顺序工作流
执行工作流程,您必须创建WorkflowRuntime类的一个实例。然后,创建一个主机类,并通过使用CreateWorkflow方法在您的工作流的类型规范。然后,您可以从返回WorkflowInstance对象调用Start方法开始执行您的工作流程。因为不依赖于外部事件执行顺序工作流,它会立即开始。要承载Windows工作流运行时引擎
返回到您的Windows应用程序,并添加你刚才在前面的任务创建一个类库(ExpenseReportWorkflow.dll)的参考。
在MainForm类中,声明如下领域:
private WorkflowRuntime workflowRuntime = null; 

private WorkflowInstance workflowInstance = null; 

在构造方法,调用InitializeComponent方法后,添加以下代码。这将启动运行,但不执行任何的工作流程,直到应用程序通知启动工作流。
this.workflowRuntime = new WorkflowRuntime(); 

workflowRuntime.StartRuntime(); 

创建一个通用的事件处理程序,在WorkflowRuntime对象的WorkflowCompleted事件。
workflowRuntime.WorkflowCompleted += 

      new EventHandler<WorkflowCompletedEventArgs> 

(workflowRuntime_WorkflowCompleted);

,还添加了相应的事件处理方法。
void workflowRuntime_WorkflowCompleted(object sender, 

WorkflowCompletedEventArgs e) 

{ 

}

submitButton_Click方法,创建一个本地类型的对象,等于你在前面的任务中创建的工作流类型。创建该类型的工作流对象,并启动它。
Type type = typeof(ExpenseReportWorkflow); 

// Start the workflow 



workflowInstance = workflowRuntime.CreateWorkflow(type);

workflowInstance.Start(); 

现在,建设项目。2。创建开支报告服务
为了使您的Windows窗体应用程序和您的顺序工作流之间的沟通,定义标记的接口与ExternalDataExchangeAttribute,并落实在你的窗体类,接口。之间的形式和工作流程更容易沟通,你会使用ExternalDataExchangeService加入Windows窗体类的服务,您的工作流程可以访问。定义工作流参数
在本练习中的第一个任务是创建工作流程中的两个属性。这些特性可以使您通过从Windows窗体应用程序中的参数,或接收来自工作流的参数。
宿主应用程序可以设置该属性之前的工作流程执行CreateWorkflow方法调用期间传递一个参数集合。返回参数返回到主机应用程序执行完毕后,你可以定义一个属性的get方法。宿主应用程序可以访问WorkflowCompletedEventArgs对象传递给WorkflowCompleted事件。 WorkflowCompletedEventArgs对象包含了所有的工作流程中包含get方法中定义的属性。
在您的ExpenseReportWorkflow类库项目中的工作流类,包括名为quot一个财产; set访问器; amountquot。
private int reportAmount = 0; 

public int Amount 

{ 

    set 

    { 

        this.reportAmount = value; 

    } 

}

包括一个名为get访问的结果另一个属性。
private string reportResult = ""; 

public string Result 

{ 

    get 

    { 

        return this.reportResult; 

    } 

} 

返回到您的Windows应用程序,SimpleExpenseReport; submitButton_Click,修改代码如下。
Type type = typeof(ExpenseReportWorkflow.ExpenseReportWorkflow); 

// Construct workflow parameters 



Dictionary<string, object> properties = 

                  new Dictionary<string, object>(); 

properties.Add("Amount", Int32.Parse(this.amount.Text)); 

// Start the workflow 



workflowInstance = workflowRuntime.CreateWorkflow(type, properties); 

workflowInstance.Start(); 

新的代码将创建一个ExpenseReportWorkflow类型和金额属性Dictionary对象中添加工作流实例。
在MainForm类的workflowRuntime_WorkflowCompleted方法,显示的工作流返回的结果,和清晰的金额文本字段。
if (this.result.InvokeRequired) 

{ 

    this.result.Invoke(new EventHandler<WorkflowCompletedEventArgs> 

    (this.workflowRuntime_WorkflowCompleted), sender, e); 

} 

else 

{ 

    this.result.Text = e.OutputParameters["Result"].ToString(); 

    // Clear fields 



    this.amount.Text = string.Empty; 

}

生成项目再次检查错误,如果有的话。定义IExpenseReportService接口
在这第二个任务,定义服务接口前面提到的实施工作流使用的方法来调用一个方法是在Windows窗体类定义。此外,两个事件被定义为主机应用程序的通知某些事件发生时的工作流程。这将使主机应用程序和工作流程,相互沟通。
添加一个新的接口文件,在ExpenseReportWorkflow项目选择Project - GT;添加新项- GT;接口。
装饰与ExternalDataExchange属性的接口,导入命名空间如下。
using System.Workflow.Activities; 

[ExternalDataExchange] 

public interface IExpenseReportService 

{ 

    void GetLeadApproval(string message); 

    void GetManagerApproval(string message); 

    event EventHandler<ExternalDataEventArgs> ExpenseReportApproved; 

    event EventHandler<ExternalDataEventArgs> ExpenseReportRejected; 

} 

修改MainForm类,使其实现IExpenseReportService接口。
public class MainForm : Form, IExpenseReportService 

添加以下的委托声明和声明的形式运行期间发生的事件。请记住,我们有两个按钮quot; acceptqu​​ot;"rejectquot;的形式来提高相应的事件。
private delegate void GetApprovalDelegate(string message); 

private event EventHandler<ExternalDataEventArgs> reportApproved; 

private event EventHandler<ExternalDataEventArgs> reportRejected; 

此外,这两个事件添加事件处理程序。
接下来的事情,你做的是非常重要的。因为形式是一个服务IExpenseReportService的实现,它应该被添加到ExternalDataExchangeService类。
这样做,创建一个在MainForm类ExternalDataExchangeService的实例。
private ExternalDataExchangeService exchangeService = null; 

修改如下的构造方法中的代码。
this.workflowRuntime = new WorkflowRuntime(); 

this.exchangeService = new ExternalDataExchangeService(); 



workflowRuntime.AddService(exchangeService); 

exchangeService.AddService(this); 

workflowRuntime.StartRuntime(); 

落实两个在IExpenseReportService MainForm类中定义的方法。
public void GetLeadApproval(string message) 

{ 

} 

public void GetManagerApproval(string message) 

{ 

} 

生成项目,并检查错误。创建顺序工作流ClassLibrary费用报表
工作流启动quot; IfElseActivityquot;,以确定是否一个经理或牵头人必须批准的金额属性,设置工作流程开始执行时指定的值。
它决定了这个后,工作流调用在宿主应用程序中定义的方法,要求批准或拒绝金额用户输入。主机应用程序批准或拒绝按钮被点击时,提出了相应的事件,这是由HandleExternalEventActivity活动之一,工作流程正在等待处理。一旦事件之一,是提出和处理工作流,工作流设置Result属性,并完成其处理。创建CallExternalMethod活动
在ExpenseReportWorkflow项目的工作流设计器,并拖动quot; IfElseActivityquot;从工具箱中的控制权。
从工具箱拖动CallExternalMethodActivity下降IfElseActivity如果分支。从工具箱拖到另一个CallExternalMethodActivity和下降的IfElseActivity else分支。
名称妥善下面给出的活动。
类型

IfElseActivity
ifEvaluateAmount

elseLeadApprove
IfElseBranchActivity
elseManagerApprove
CallExternalMethodActivity
invokeLeadApproval
CallExternalMethodActivity
invokeManagerApproval
选择"elseLeadApprove矩形框,按F4打开属性窗口。设置quot; Conditionquo​​t;属性来quot;代码Conditionquo​​t。展开"; Conditionquo​​t;财产。
设置为DetermineApprovalContact条件的值。
下同名称写在一个辅助方法。
void DetermineApprovalContact(object sender, ConditionalEventArgs e) 

{ 

    if (this.reportAmount < 1000) 

    { 

        e.Result = true; 

    } 

    else 

    { 

        e.Result = false; 

    } 

} 

现在,设置为CallExternalMethodActivity框的属性以及。
选择invokeLeadApproval框,并设置以下属性:
属性

接口
SimpleExpenseReport.IExpenseReportService(要做到这一点,单击椭圆形按钮的属性在角落,在显示的对话框中选择类型)
消息
"铅批准neededquot;
methodName中
GetLeadApproval(单击下拉列表,选择这种方法)
选择invokeManagerApproval框,并设置以下属性:
属性

接口
SimpleExpenseReport.IExpenseReportService(要做到这一点,单击椭圆形按钮的属性在角落,在显示的对话框中选择类型)
消息
"经理审批neededquot;
methodName中
GetManagerApproval(单击下拉列表,选择这种方法)
的代码添加在IExpenseReportService在MainForm类如下定义两个方法:
public void GetLeadApproval(string message) 

{ 

    if (this.approvalState.InvokeRequired) 

        this.approvalState.Invoke(new GetApprovalDelegate 



                (this.GetLeadApproval), message); 

    else 

    { 

        this.approvalState.Text = message; 

        this.approveButton.Enabled = true; 

        this.rejectButton.Enabled = true; 

        // expand the panel 

    

        this.Height = this.MinimumSize.Height + this.panel1.Height; 

        this.submitButton.Enabled = false; 

    } 

} 



public void GetManagerApproval(string message) 

{ 

    if (this.approvalState.InvokeRequired) 

        this.approvalState.Invoke(new GetApprovalDelegate 



            (this.GetManagerApproval), message); 

    else 

    { 

        this.approvalState.Text = message; 

        this.approveButton.Enabled = true; 

        this.rejectButton.Enabled = true; 

        // expand the panel 



        this.Height = this.MinimumSize.Height + this.panel1.Height; 

        this.submitButton.Enabled = false; 

    } 

}

生成项目并运行应用程序。你应该得到批准和拒绝按钮,此时不显示的形式。创建HandleExternalEvent活动
在这个任务中,你创建了一个包含两个HandleExternalEventActivity的活动,以捕捉批准或拒绝的事件,是由主机应用程序中提出的ListenActivity活动。批准或拒绝事件引发时,工作流继续设置的结果,然后完成。
修改ExpenseReportWorkflow类,以便它可以收听主机应用程序引发的特定事件。
创建一个新的的方法,该方法接受名为sender和一个ExternalDataEventArgs命名为参数e的对象。
void approveEvent_Invoked(object sender, ExternalDataEventArgs e) 

{ 

    this.reportResult = "Report Approved"; 

} 

private void rejectEvent_Invoked(object sender,ExternalDataEventArgs e) 

{ 

    this.reportResult = "Report Rejected"; 

}

在工作流设计,将通过从工具箱拖动ListenActivity图。
{S2}
从工具箱拖动HandleExternalEvent活动,并同时EventDrivenActivitys下降。
名称的活动,适当如下:
类型

ListenActivity
listenApproveOrReject
EventDrivenActivity
eventDriven1
EventDrivenActivity
eventDriven2
HandleExternalEventActivity
ApproveEvent
HandleExternalEventActivity
RejectEvent
选择ApproveEvent活动中,并按下F4显示属性窗口。
属性

InterfaceType
SimpleExpenseReport.IExpenseReportService(要做到这一点,单击椭圆形按钮的属性在角落,在显示的对话框中选择类型)
EventName
ExpenseReportApproved
调用
approveEvent_Invoked(单击下拉列表,选择此方法)
选择RejectEvent活动框,然后按F4显示属性窗口。
属性

InterfaceType
SimpleExpenseReport.IExpenseReportService(要做到这一点,单击椭圆形按钮的属性在角落,在显示的对话框中选择类型)
EventName
ExpenseReportRejected
调用
rejectEvent_Invoked(单击下拉列表,选择此方法)
下一步是提高从主机应用程序的事件。要做到这一点,添加代码的approvebutton_Click处理程序。
同样,添加代码的rejectbutton_Click处理程序。
// Raise the ExpenseReportRejected event back to the workflow 



reportRejected(null, new ExternalDataEventArgs (

                         this.workflowInstance.InstanceId)); 

this.Height = this.MinimumSize.Height; 

this.submitButton.Enabled = true; 

生成并运行应用程序。
当您提交费用报表的金额,形式展开,以显示"批准和拒绝按钮和一个接收到的消息是从工作流程。点击其中一个按钮执行以下操作:折叠的形式。引发事件的工作流程。检索从工作流程的结果属性。上显示的形式。
{S3}
这是步行通过创建顺序工作流结束。

回答

评论会员:游客 时间:2011/12/14
请我开发一个基于Web的图书流通系统我想用窗口的工作流程顺序,对检查出的书部分子ID和书ID可以输入参数,我如何可以读取和更新的数据库,在Windows工作流我应使用seqential工作流程库或Webservic我使用VisualStudio2005的请我在哪里可以找到有关顺序工作流程和asp.net的信息,使工作流读取和更新图书流通数据库感谢
yob
评论会员:游客 时间:2011/12/14
您好,假设你有一个Web应用程序。你将如何加载和使用顺序工作流库吗?你将如何使用IExpenseReportService接口许多感谢