VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Objective-C编程 >
  • WF编程系列之工作流编写方式纯XAML

制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
 

  2.3 纯XAML

  下面是一段纯XAML的工作流定义:

<SequentialWorkflowActivity
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
 x:Class="MyWorkflow">
 <WhileActivity>
  <CodeActivity/>
 </WhileActivity>
</SequentialWorkflowActivity>

  这段XAML的根元素是SequentialWorkflowActivity.WF的根活动可以是SequentialWorkflowActivity或StateMachineWorkflowActivity.这两个类以不同方式管理其子活动的执行过程.SequentialWorkflowActivity顺序地执行它的子活动直到最后一个活动完成.所以在顺序工作流(Seqential Workflow)中活动的先后顺序很重要,顺序决定了活动什么时候被执行.关于StateMachineWorkflowActivity将在以后的章节详述.

  定义工作流的XAML文件的扩展名是.xoml.

  我们的工作流中只有一个包含CodeActivity的WhileActivity.定义这个工作流的XAML其实就是将工作流中的对象以”树”的形式表示出来.XAML在循环内部创建了一个CodeActivity,我们没有定义任何代码和While的条件,所以这个工作流暂时还不能通过验证.

  我们像讨论类一样讨论XML元素(如<WhileActivity>),其实这些元素就是类.因为XAML是通过将XML映射到.NET类型来工作的,其中XAML的元素映射到类,元素的特性(attribute)映射到类的属性(property).每个XML名称空间则对应于一个或更多的.NET名称空间.

  XML中的名称空间和.NET中的很类似.二者都用来避免同名实体之间的名称冲突.我们的XAML文件中有两个名称空间,workflow是第一个名称空间,因为它没有前缀,所以它还是默认的名称空间.第二个名称空间是XAML,它使用x:前缀.

 

  XAML名称空间比较特别,因为它会将指令传给工作流编译器.比如x:Class特性会告诉编译器工作流定义中待创建的新类名称.我们的XAML会被编译为包含一个类的程序集,这个类的名称就是MyWorkflow.

  我们先删除WhileActivity并让XAML可以被编译.

<SequentialWorkflowActivity
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 x:Class="MyWorkflow"
 >
 <CodeActivityExecuteCode="SayHello"/>
 <x:Code>
  <![CDATA[ 
  privatevoidSayHello(objectsender,EventArgse)
  {
   Console.WriteLine("Hello,workflow!");
  }
  ]]>
 </x:Code>
</SequentialWorkflowActivity>

  现在这个工作流通过了验证,因为CodeActivity已经有了用来定义ExecuteCode事件的event handler.一般来说,CodeActivity并不这样使用,CodeActivity应该使用一些计算和逻辑来检查并改变工作流的状态,而我们现在只是向控制台输出一条消息.这个例子演示了如何在XAML中使用内嵌代码.内嵌代码通常也是不被采用的,许多开发人员喜欢使用精准的类并且认为内嵌代码是七宗罪之一.

  如果我们真的需要从工作流内部向控制台输出消息,我们可以将这个行为封装到一个自定义活动中.封装了行为的自定义活动可以作为控件来重复使用.

  2.3.1 在XAML中使用自定义活动

  自定义活动继承自System.Workflow.ComponentModel.Activity,它允许我们在工作流中使用针对特定领域的控件(活动).为了实现自定义活动,我们需要覆盖(Override)一个虚方法-Execute.下面的代码是一个可以向控制台输出消息的自定义活动.

  •  
 

usingSystem.Workflow.ComponentModel;
namespaceOdeToCode.WinWF.Activities
{
 publicclassWriteLineActivity:Activity
 {
   protectedoverrideActivityExecutionStatusExecute
       (ActivityExecutionContextexecutionContext)
   {
    Console.WriteLine(_message);
    returnActivityExecutionStatus.Closed;
   }
   privatestring_message;
   publicstringMessage
   {
    get{return_message;}
    set{_message=value;}
   }
 }
}

  我们为自定义活动创建了一个公有属性-Message.我们可以通过XAML里的Message特性来设置这个属性的值,而无需使用内嵌代码.

<SequentialWorkflowActivity
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:otc="http://schemas.OdeToCode.com/WinWF/Activities"
 x:Class="MyWorkflow">
 <otc:WriteLineActivityMessage="Hello,workflow!"/>
</SequentialWorkflowActivity>

  请注意,我们定义了一个新的XML名称空间(http://schemas.OdeToCode.com/WinWF/Activities)来表示自定义活动.工作流编译器将如何使用这个名称空间来查找WriteLineActivity控件呢?答案是通过程序集级别的元数据(metadata),因为这个元数据负责提供XML名称空间和.NET名称空间之间的映射.

  [assembly:XmlnsDefinition("http://schemas.OdeToCode.com/WinWF/Activities","OdeToCode.WinWF.Activities")]

 

  XAML编译器会从被引用的程序集中查找XmlnsDefinition特性.当它找到了上面的定义,编译器就会知道应该将http://schemas.OdeToCode.com/WinWF/Activities映射到该程序集的CLR名称空间OdeToCode.WinWF.Activities.

  另一个映射名称空间的方式是在XAML中直接嵌入CLR名称空间和程序集名称.假设我们的自定义活动所在程序集中叫做Foo.dll,则在XAML中这样写:

  xmlns:otc="clr-namespace:OdeToCode.WinWF.Activities;assembly=Foo" 当我们需要在工作流内部使用一个非原创的类型(我们无法向其中添加元数据)时,这种方式很有用.

  我们的工作流几乎已经准备好了,但是在首次执行之前还需要将XAML转换为CLR指令.

  所以,下一篇,工作流编译!

  XAML名称空间比较特别,因为它会将指令传给工作流编译器.比如x:Class特性会告诉编译器工作流定义中待创建的新类名称.我们的XAML会被编译为包含一个类的程序集,这个类的名称就是MyWorkflow.

  我们先删除WhileActivity并让XAML可以被编译.

<SequentialWorkflowActivity
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 x:Class="MyWorkflow"
 >
 <CodeActivityExecuteCode="SayHello"/>
 <x:Code>
  <![CDATA[ 
  privatevoidSayHello(objectsender,EventArgse)
  {
   Console.WriteLine("Hello,workflow!");
  }
  ]]>
 </x:Code>
</SequentialWorkflowActivity>

  现在这个工作流通过了验证,因为CodeActivity已经有了用来定义ExecuteCode事件的event handler.一般来说,CodeActivity并不这样使用,CodeActivity应该使用一些计算和逻辑来检查并改变工作流的状态,而我们现在只是向控制台输出一条消息.这个例子演示了如何在XAML中使用内嵌代码.内嵌代码通常也是不被采用的,许多开发人员喜欢使用精准的类并且认为内嵌代码是七宗罪之一.

  如果我们真的需要从工作流内部向控制台输出消息,我们可以将这个行为封装到一个自定义活动中.封装了行为的自定义活动可以作为控件来重复使用.

  2.3.1 在XAML中使用自定义活动

  自定义活动继承自System.Workflow.ComponentModel.Activity,它允许我们在工作流中使用针对特定领域的控件(活动).为了实现自定义活动,我们需要覆盖(Override)一个虚方法-Execute.下面的代码是一个可以向控制台输出消息的自定义活动.


相关教程