Click to Rate and Give Feedback
MSDN
MSDN Library
.NET Development
.NET Framework 3.5
This page is specific to
Microsoft Visual Studio 2008/.NET Framework 3.5

Other versions are also available for the following:
Using Workflow Markup

Windows Workflow Foundation gives designers and developers a declarative way to create workflows by using eXtensible Application Markup Language (XAML) to create markup source files. These markup files can be compiled into a workflow type, loaded directly into the workflow runtime engine at run time, or they can be compiled into a workflow type with code-beside files implemented in either C# or Visual Basic. This means that the workflow markup files can be compiled or not, depending on business reasons and whether additional implementation logic is required. The use of workflow markup with code-beside logic files is similar to how ASP.NET separates presentation files from logic files.

For an example of how to load a workflow markup file directly into the workflow run-time engine, see the Running Workflows section of the Creating a Workflow Host Application topic or Using Custom Activities with Workflow Markup.

Basic structure

The basic structure of the workflow markup contains the root node, which denotes the type of workflow, followed by the child activities in that workflow as nested sub elements. Because workflow markup is based on a subset of XAML elements and attributes, the structure of workflow markup files looks similar to that of an XAML file. For example, each element in the workflow is represented as nodes of either composite activities or the workflow itself. The relationship between nodes is preserved just like it is when you create workflows through a programming language such as C# or Visual Basic.

Elements and Attributes

As stated previously, each element in a workflow markup file corresponds to a workflow component. The names for those elements are the same names for the activity types that are used when you create workflows programmatically. For example, the IfElseActivity activity is represented by the <IfElseActivity> element. This is also true for custom activities.

Activity members are declared as shown in the following example. In this example, a DelayActivity activity is configured with a Name of delayActivity1, a TimeoutDuration of fifteen seconds, and the InitializeTimeoutDuration event is set to a method in the code-beside named SetTimeoutDuration.

<DelayActivity
    x:Name="delayActivity1"
    TimeoutDuration="00:00:15" 
    InitializeTimeoutDuration="SetTimeoutDuration" />

XAML also provides the ability to insert procedural code within a workflow markup file using the x:Code directive element. The code must be placed in a CDATA section so that the compiler can compile the code instead of treating it like declarative XAML markup. The following example shows how that element is used with a CDATA section.

<CodeActivity x:Name="codeActivity1" ExecuteCode="methodName1">
  <x:Code><![CDATA[
      void methodName1(object sender, EventArgs e) 
      {
      }
  ]]></x:Code>
</CodeActivity>
ms735921.note(en-us,VS.90).gifNote:
The x:Code directive element can only be used in workflow markup files that are compiled.

The following table describes the common attributes of workflow markup.

Attribute Description

x:Array

An array of types.

x:Class

Name of the workflow class including the namespace. The class with this name is created when the workflow is compiled.

x:Name

Name of an activity. Corresponds to the Activity.Name property.

x:Type

A type reference.

x:Null

A null value.

xmlns:x

The namespace for the XAML schema.

xmlns

The namespace for the workflow XAML schema.

ms735921.note(en-us,VS.90).gifNote:
If you use a non-compiled, XAML-only workflow markup file to create a workflow, x:Class attribute should not be present in the XAML file. This attribute is valid only when the workflow is being compiled.

ms735921.note(en-us,VS.90).gifNote:
If the Root Namespace for a Visual Basic application is changed after a workflow markup file is created, the x:Class attribute of that workflow must also be updated.

Example

The following is an example of a workflow markup file for a compiled workflow and the code-beside file that contains implementation logic for the various event handlers in the workflow.

<SequentialWorkflowActivity
    x:Class="XamlCodeExamples.SampleWorkflow"
    x:Name="SampleWorkflow"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
    <CodeActivity x:Name="GenerateRandomNumber"
        ExecuteCode="GenerateRandomNumber_ExecuteCode" />
    <IfElseActivity x:Name="ifElseActivity1">
        <IfElseBranchActivity x:Name="ifElseBranchActivity1">
            <IfElseBranchActivity.Condition>
                <CodeCondition Condition="SampleCodeCondition" />
            </IfElseBranchActivity.Condition>
           <CodeActivity x:Name="EvenNumber" ExecuteCode="EvenNumber_ExecuteCode" />
        </IfElseBranchActivity>
        <IfElseBranchActivity x:Name="ifElseBranchActivity2">
            <CodeActivity x:Name="OddNumber" ExecuteCode="OddNumber_ExecuteCode" />
        </IfElseBranchActivity>
    </IfElseActivity>
</SequentialWorkflowActivity>
Visual Basic
Public Class SampleWorkflow
    Inherits SequentialWorkflowActivity


    Private randomValue As Integer
    Public Property RandomInt() As Integer
        Get
            Return randomValue
        End Get
        Set(ByVal value As Integer)
            randomValue = value
        End Set
    End Property

    Private Sub GenerateRandomNumber_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs)
        RandomInt = New Random().Next(1, 101)
    End Sub

    Private Sub SampleCodeCondition(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.ConditionalEventArgs)
        e.Result = RandomInt Mod 2 = 0
    End Sub

    Private Sub EvenNumber_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Console.WriteLine("{0} is even.", RandomInt)
    End Sub

    Private Sub OddNumber_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Console.WriteLine("{0} is odd.", RandomInt)
    End Sub
End Class
C#
public partial class SampleWorkflow : SequentialWorkflowActivity
{
    public int RandomInt { get; set; }

    private void GenerateRandomNumber_ExecuteCode(object sender, EventArgs e)
    {
        RandomInt = new Random().Next(1, 101);
    }

    private void SampleCodeCondition(object sender, ConditionalEventArgs e)
    {
        e.Result = RandomInt % 2 == 0;
    }
    
    private void EvenNumber_ExecuteCode(object sender, EventArgs e)
    {
        Console.WriteLine("{0} is even.", RandomInt);
    }

    private void OddNumber_ExecuteCode(object sender, EventArgs e)
    {
        Console.WriteLine("{0} is odd.", RandomInt);
    }
}

If you use a non-compiled, XAML-only workflow markup file to create a workflow, you must use the ActivityBind markup extension to set all dependency properties of type event handler or they are not called during runtime. One way to accomplish this is to define a custom type that serves as the root workflow element and bind to methods in this custom type. In the following example, the custom workflow type WorkflowBase has a method that matches the signature of a dependency event handler.

Visual Basic
Public Class BaseWorkflow
    Inherits SequentialWorkflowActivity

    Public Sub ExecuteCodeEventHandler(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Console.WriteLine("Base Workflow event handler")
    End Sub

End Class
C#
public partial class BaseWorkflow : SequentialWorkflowActivity
{
    public BaseWorkflow()
    {
        InitializeComponent();
    }

    public void ExecuteCodeEventHandler(object sender, EventArgs e)
    {
        Console.WriteLine("Base Workflow event handler");
    }
}

The following workflow markup is an example of a workflow of type BaseWorkflow from the previous example that has one CodeActivity activity that has its ExecuteCode dependency event bound to the ExecuteCodeEventHandler method that is defined in BaseWorkflow.

<?xml version="1.0" encoding="utf-16"?>
<ns0:BaseWorkflow x:Name="BaseWorkflow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow" 
    xmlns:x="http://sch//emas.microsoft.com/winfx/2006/xaml" 
    xmlns:ns0="clr-namespace:XamlCodeExamples;Assembly=XamlCodeExamples, 
    Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <CodeActivity
            x:Name="codeActivity1"
            ExecuteCode="{ActivityBind BaseWorkflow,Path=ExecuteCodeEventHandler}"
        />
</ns0:BaseWorkflow>
ms735921.note(en-us,VS.90).gifNote:
The previous example shows how to use a CodeActivity in a markup-only workflow but you can use this technique for any activity that has dependency events.

See Also



Copyright © 2007 by Microsoft Corporation. All rights reserved.
Tags What's this?: Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
Processing
© 2008 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Page view tracker