一起学WF3.5【12】

发布时间:2016-12-11 2:34:34 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"一起学WF3.5【12】",主要涉及到一起学WF3.5【12】方面的内容,对于一起学WF3.5【12】感兴趣的同学可以参考一下。

在宿主应用程序程序中检索工作流数据 上节中,我们已经创建好了外部服务类和工作流。现在试着在宿主应用中创建和启用工作流,并接收来自工作流的消息和数据。 界面设计如下图,具体上节已有描述: 同样复制WorkflowFactory类到项目中以复用。 在宿主中关键要做的是勾住MVDataUpdate事件以便使应用程序知道接收数据的时间。 在“RetrieveMV Data”的点击响应函数中,加如下代码: MVDataService.WorkflowMVDataServicedataService =              MVDataService.WorkflowMVDataService.CreateDataService(                            _workflowInstance.InstanceId,                             _workflowRuntime);   dataService.MVDataUpdate+= new EventHandler<MVDataService.MVDataAvailableArgs>(dataService_MVDataUpdate); 定义事件处理函数dataService_MVDataUpdate函数:(略,见附件代码),捕捉了数据获取完成事件并填充了ListView控件。 用InvokeWorkflow调用外部工作流 InvokeWorkflow可用来在正在执行的工作流中启动另一个工作流。 可按如下方法做一个例子: 新建一个顺序工作流库命名为“Workflow1”。在工作流设计器上拖一个Code活动, 可令它输出一个提示信息。同样新建一个顺序工作流库命名为Workflow2。在工作流器上上拖一个Code活动并令它输出另一个信息。编译Workflow2,并为Workflow1添加对它的引用。 回到Workflow1的设计器上,拖一个InvokeWorkflow活动到设计器上。这个新活动的有一个属性“TargetWorkflow”,点击它的浏览弹出“浏览和选择一个.NET类型”的对话框,选择Workflow2。 同样建立宿主应用。添加如下代码启动Workflow1: WorkflowInstanceinstance = workflowRuntime.CreateWorkflow(typeof(Workflow1.Workflow1)); Instance.Start(); 为宿主应用添加工作流完成事件的处理程序代码如下,以使两个工作流在完成时通知我们: if(e.WorkflowDefinition is Workflow1.Workflow1)             {                Console.WriteLine("Workflow1 completed.");             }             else             {                Console.WriteLine("Workflow2 completed.");             } 要设置AutoResetEvent,以便强制应用程序等待工作流完成。编译运行如下图,输出信息的顺序可能会有所不同:   逻辑流活动 WF提供了基于运行时的条件进行逻辑处理控制流的活动。包括IfElse活动、While活动和Replicator活动。 对于条件的处理既可以依靠CodeCondition处理,也可使用RuleCondition,后者使用了WF的基于规则的处理方式。 示例:Qustioner应用程序 本示例依然是一个Windows Form应用程序。它会回答你三个问题,问题内容可修改,你可指定这三个问题是各自独立还是相互关联。 当工作流开始执行时你要把这些问题和相关的情况传入工作流。相互关联的问题只有在前面的问题回答正确时才被进一步提出;各自独立的问题要求你必须回答。   按照上一章的模式,我们需要生成一个活动以实现宿主应用和工作流之间的通信。创建项目命名为QuestionService活动。创建过程不再赘述,项目的结构与之前的类似,我们把精力集中在实现工作流上。   使用IfElse活动实现 IfElse活动要求你提供一个条件表达式,它其实是一个EventHandler,有一个ConditionalEventArgs参数,有一个Boolean类型的Result属性。IfElse活动根据Result的值来选择执行分支的哪一支,两个分支都可作为其他活动的容器。 在QuestionService项目中已使用工具生成了一个通信活动:SendResponseDataToHost。 工作流项目被命名为QuestionFlow,在设计视图上,拖一个IfElse活动。在其Condition属性设置为代码条件,展开后  输入AskQuestion1。拖两个Code活动到左右两个分支,左边的ExcudeCode设置为AffirmQ1,右边的设置为NegateQ1。 工作流类需要设置如下字段和属性包含三个问题,作为启动工作流时的参数: privatestring[] _questions = null; publicstring[] Questions { get{ return_questions; } set{ _questions = value; } } 添加Dependent属性标记这些问题是否关联: privatebool_dependent = true; publicboolDependent { get{return_dependent; } set{_dependent = value; } } 回答的结果应作如下存储: private bool[] _response = null; 它的初始化在构造器里进行: _response =new bool[3]; _response[0]= false; _response[1]= false; _response[2]= false; AskQuestion1事件处理添加如下代码: DialogResultresult = MessageBox.Show(Questions[0], "Questioner:", MessageBoxButtons.YesNo,MessageBoxIcon.Question); e.Result =(result == DialogResult.Yes); NegateQ1添加如下代码: _response[0]= false; if(Dependent) { // Negateremaining answers. _response[1]= false; _response[2]= false; } AffirmQ1添加: _response[0]= true; 以上就完成了对第一个问题的回答。对于第2、3个问题同样加两个IfElse活动进去。事件处理程序分别为AskQuestion2、NegateQ2、AffirmQ2…。 AskQuestionQ2的代码如下: if(_response[0]== false&& Dependent) { // No need toask! e.Result =false; } else { // Ask thequestion! DialogResultresult = MessageBox.Show(Questions[1], "Questioner:", MessageBoxButtons.YesNo,MessageBoxIcon.Question); e.Result =(result == DialogResult.Yes); } NegateQ2如下: _response[1]= false; if(Dependent) { // Negateremaining answer _response[2]= false; } AffirmQ2如下: _response[1]= true;   同样,AskQuesionQ3代码如下: if(_response[1]== false&& Dependent) { // No need toask! e.Result =false; } else { // Ask thequestion! DialogResultresult = MessageBox.Show(Questions[2], "Questioner:", MessageBoxButtons.YesNo,MessageBoxIcon.Question); e.Result =(result == DialogResult.Yes); NegateQ3代码如下: _response[2]= false; AffirmQ3代码如下: _response[2]= true;   拖SendResponseDataToHost活动到工作流设计器上第三个IfEsle下边。把它的response属性设置为三个False(点浏览按钮后弹出的Boolean集合编辑器中设置)。 还需要把保存了问题问答结果的数组的值和SendResponseDataToHost活动联系起来。我们拖一个Code活动到第三个IfElse活动和SendResponseDatToHost之间。把它的ExecuteCode属性设置为CopyResponse,其代码如下: sendResponseDataToHost1.responses= _response; 好了,编译运行。   使用While活动实现 上例如果使用While活动实现会更好些。我们将使用While活动替换上例。同样它也使用ConditionalEventArgs来返回你的判断结果,如果Result属性为true继续循环,false则终止循环。 在工作流设计视图中拖一个While活动。在它的Condtion属性中输入TestComplete。 拖一个Code活动到WhileActivity1中,把它的ExecuteCode属性值设为AskQuestion。 把SendResponseDataToHost活动拖入放在While活动下。 同样需要设置上例中的一些字段和属性,包括存储问题的数组和属性,是否依赖的字段和属性以及回答的数组和属性。 添加如下代码: private Int32_qNum = 0; TestComplete事件处理程序添加如下代码: if(_qNum>= Questions.Length) { // Assignoutgoing data. sendResponseDataToHost1.responses= _response; // Done, soexit loop. e.Result =false; } else { // Not done,so continue loop. e.Result =true; } 在AskQuestion事件处理程序中添加如下代码: DialogResultresult = MessageBox.Show(Questions[_qNum], "Questioner:", MessageBoxButtons.YesNo,MessageBoxIcon.Question); _response[_qNum]= (result == DialogResult.Yes); // Checkresponse versus dependency if(!_response[_qNum]&& Dependent) { // Negateremaining questions while(_qNum< Questions.Length) { // Negatethis question _response[_qNum]= false; // Next question ++_qNum; } } // if else { // Set up fornext iteration ++_qNum; } 同样放一个Code活动到While活动下把问题结果数组传给SendResponseDataToHost活动。编译执行。

上一篇:requestWindowFeature()的应用
下一篇:java接口和抽象类

相关文章

相关评论