-
练习二 —— 使用参数向工作流中接收数据
这个练习中,你会修改我们在上面创建的工作流,使它在运行起来后,可以向内部接收数据。你还可以在Code活动中修改代码来显示输入的数据值。最后,你会将我们上个练习中的项目,改为一个Windows窗体宿主程序。它可以允许我们输入值,并创建一个我们自己的工作流示例。
注意:当工作流运行起来后,有两个接收数据的方法。他们是参数和事件。如果使用参数,工作流必须使用一个包含参数名和参数类型定义的列表。这些参数会在宿主陈故乡启动一个新的工作流实例后,传递近来。如果使用事件,工作流作者会加入一个可以接收事件和事件相关数据的活动。事件由宿主定义,而且一个自定义的活动会被用来处理事件响应。我们将会在这个练习中使用参数,而在练习三中会使用基于事件的活动。
任务1 —— 为工作流定义参数
- 在解决方案资源管理器中双击Workflow1.xoml文件,以打开Visual Studio 工作流设计视图。
- 在工作流设计视图中右键单击背景,选择代码视图,或在菜单中选择视图|代码。
- 进入Workflow1类中,加入一个字符串类型的字段:firstName,并将它重构为一个属性。如下代码:
1: private string firstName;
2:
3: public string FirstName
4: {
5: get { return firstName; }
6: set { firstName = value; }
7: }
- 使用相同的方法再加入另一个属性:LastName。如下代码:
1: private string lastName;
2:
3: public string LastName
4: {
5: get { return lastName; }
6: set { lastName = value; }
7: }
任务2 —— 修改代码活动
- 在这个练习中,我们会使用一个Windows窗体应用程序作为工作流的宿主。因此我们想要从工作流中显示一个消息框,我们就需要添加一个指向Windows窗体的引用。选择项目|添加引用。
- 在添加引用对话框的.NET选项卡中,从列表中选择System.Windows.Forms并点击OK按钮。
- 在解决方案管理器中右键单击Workflow1.xoml.cn文件。选择察看代码。此时就会导航到Workflow1.xoml.cs源文件中的codeActivity1_CodeHandler。这个方法就是代码活动的处理方法。
- 修改codeActivity1_CodeHandler方法中的代码,来获得参数值,并且显示用一个消息框显示FirstName和LastName的值。
1: private void codeActivity1_CodeHandler(object sender, EventArgs e)
2: {
3: //Console.WriteLine("Hello,World!");
4: System.Windows.Forms.MessageBox.Show("Hello World: " + FirstName + " " + LastName);
5: }
任务3 —— 运行修改后的工作流
现在我们准备测试修改后的工作流。和我们在练习一中使用控制台应用程序不同的是,在这里我们添加一个Windows窗体应用程序和一些预定义的代码作为我们工作流的宿主。
- 在Visual Studio中,选择文件|新建|新项目菜单,向打开的HelloWorldWorkflow解决方案中添加一个新的项目:WinFormTestHost。
- 右键单击刚刚建立的WinFormTestHost项目,选择设为启动项目菜单。
- 按照如下界面设计窗体。其中,窗体的显示文本为“Hello World Workflow”。两个文本框的ID分别为txtFirstName和txtLastName。按钮的ID为btnStartWorkflow。调整文本框的宽度为150。调整按钮的宽度为100。调整窗体的高度为120。
- 现在我们要确认WinFormTestHost应用程序可以使用新的工作流。在解决方案资源管理器中右键单击WinFormTestHost的引用文件夹,选择添加引用,添加HelloWorldWorkflow项目的引用。
- 在添加引用对话框中,选择项目选项卡。
- 在列表中选择HelloWorldWorkflow项目,点击OK关闭对话框。然后再添加新的引用。
- 我们还需要确认WinFormTestHost已经包含Windows Workflow Foundation系统的程序集。在解决方案资源管理器中右键单击WinFormTestHost项目的引用文件夹,选择添加引用。
- 在添加引用对话框中,选择.NET选项卡,滑动到下方,并选择如下图所示实体。
- 在解决方案资源管理器中,右键单击Workflow1.xoml文件,选择查看代码,来打开工作流的Code-Beside类。
- 设置一个断点在codeActivity1_CodeHandler方法上。
- 在解决方案中,右键单击Form1.cs文件,选择查看代码,来打开窗体的code-beside代码。
- 在Using区域,添加如下代码,来引用工作流系统程序集。
1: using System.Workflow.ComponentModel;
2: using System.Workflow.Runtime;
3: using System.Workflow.Runtime.Hosting;
- 在Form1类中添加三个私有变量,如下所示:
1: private WorkflowRuntime wr;
2: private string workflowAssembly = "";
3: private string workflowTypeName = "";
- 在Form1的构造函数中,初始化工作流的程序集名和工作流的类别名。将如下代码添加到构造函数中:
1: workflowAssembly = "HelloWorldWorkflow";
2: workflowTypeName = "HelloWorldWorkflow.Workflow1";
- 在Form1中,为窗体添加关闭事件处理程序。切换到设计视图,右键单击窗体,选择属性。在属性窗口中选择事件按钮。此时切换到了事件列表。在行为组中找到FormClosed事件并双击。此时在Form1窗体的Code-beside代码中自动生成了Form1_FormClosed事件处理程序。按照如下代码所示编写Form1_FormClosed事件处理:
1: private void Form1_FormClosed(object sender, FormClosedEventArgs e)
2: {
3: if (wr != null)
4: {
5: if (wr.IsStarted)
6: {
7: wr.StopRuntime();
8: }
9: }
10: }
- 接下来,需要为按钮添加启动工作流、传递参数的代码。返回设计视图,双击btnStartWorkflow按钮。此时,在Form1窗体的Code-beside代码中会自动生成btnStartWorkflow_Click事件代码。按照如下代码编写btnStartWorkflow_Click事件处理的实现:
1: private void btnStartWorkflow_Click(object sender, EventArgs e)
2: {
3: if (wr == null)
4: {
5: wr = new WorkflowRuntime();
6: wr.StartRuntime();
7: }
8: Dictionary<string, object> parameters = new Dictionary<string, object>();
9: parameters.Add("FirstName", txtFirstName.Text);
10: parameters.Add("LastName", txtLastName.Text);
11:
12: WorkflowInstance instance = wr.CreateWorkflow(typeof(HelloWorldWorkflow.Workflow1), parameters);
13: instance.Start();
14: }
- 按F5,编译并运行解决方案,或者选择调试|开始调试菜单命令。
- WinFormTestHost应用程序将会运行,并显示包含输入First和Last Name的字段。
- 在两个文本框中分别输入First Name 和 Last Name。
- 单击Start Workflow按钮来实例化一个HelloWorldWorkflow.Workflow1的新实例。并将FirstName 和LastName值作为参数传递到工作流中。
- Visual Studio 将会中断调试到codeActivity1_CodeHandler方法。选择调试|继续调试菜单可以继续运行工作流。
- 当Code活动完成运行后,你会看到一个消息框,显示出了作为参数传递到工作流中的FirstName和LastName两个值。
- 关闭WinFormTestHost应用程序来停止宿主程序和调试。