none
《WF编程》系列之8 - 工作流编写方式:纯XAML RRS feed

  • 常规讨论

  • 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"


    >


    <CodeActivity ExecuteCode="SayHello"
    />


    <x:Code>


    <![CDATA[


    private void SayHello(object sender, EventArgs e)

    {

    Console.WriteLine("Hello, workflow!");

    }


    ]]>


    </x:Code>

    </SequentialWorkflowActivity>

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

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

    2.3.1 在XAML中使用自定义活动

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

    using System.Workflow.ComponentModel;
    namespace OdeToCode.WinWF.Activities
    {

    public
    class WriteLineActivity : Activity
    {

    protected
    override ActivityExecutionStatus Execute
    (ActivityExecutionContext executionContext)
    {
    Console.WriteLine(_message);

    return ActivityExecutionStatus.Closed;
    }

    private
    string _message;

    public
    string Message
    {

    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:WriteLineActivity Message="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指令.
    所以,下一篇,工作流编译!

    转自:http://www.cnblogs.com/xiaoshatian/

    2009年6月25日 8:17

全部回复

  • 你好,请问一下怎么用代码来创建xoml文件呢?能否提供一下创建SequentialWorkflowActivity 属性的代码,
    比如:TestAtttibute="TestValue" 

    或者添加你自定义控件的属性 TestAtttibute ,比如:<otc:WriteLineActivity Message="Hello, workflow!"  TestAtttibute="TestValue"   />

    谢谢!

    2009年12月10日 8:51
  • hi,请参考此文章:
    http://coding.windstyle.cn/2007/04/23/programming-wf-12-compile-workflow-xaml-serialization/
    My blog: http://xiaoshatian.cnblogs.com
    2010年1月20日 11:03
    版主