Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / XAML

Introduction to XAML in Windows Workflow Foundation

4.82/5 (16 votes)
17 Apr 20079 min read 1   803  
Third article in a Windows Workflow Foundation tutorial

Introduction

This is the third article in introductory series of articles on 'Windows Workflow Foundation'. In the first article we took at quick tour of Windows Workflow Foundation and also developed a rudimentary flight booking system which was based on 'sequential workflow'. Later on, we explored 'state-machine workflow' in the second article and developed a purchase ordering system. Now we will focus on XAML and learn how we can use it to design workflows in Windows Workflow Foundation.

Hello XAML!

Extensible Application Markup Language or XAML (pronounced zammel) is a new declarative language that is used in Windows Framework and Windows Presentation Foundation. Introduced with .NET Framework 3.0, XAML is harbinger of declarative (in contrast with imperative using coding) programming model. In Workflow Foundation, workflows can be created using code as well as XAML. Even fully XAML-based solutions are possible with no code at all! This not only gives flexibility of no-compilation-needed to applications, it also opens up a window of possibility for entirely non-technical persons (like business analysts) to design workflows. (Though Workflow Foundation is targeted for programmers, experiments are underway around the globe for making it feasible for business analysts to model processes in it).

XAML and Workflow Foundation

One can design workflow in three possible ways using Workflow Foundation; purely code based, partially code/XAML based, and totally XAML based. Partially code/XAML based workflows are combination of code and XAML. For instance, a typical scenario would be: a panoramic view of application is taken and workflow is defined using XAML, and later on, technical nitty-gritty is added by developer(s) for each workflow activity in code. These solutions need compilation. Purely XAML based solutions have workflow as well as all conditions/rules specified in XAML and can be hosted without compilation, though 'XAML Activation' would be needed to make them work.

What we are going to cover in this article

We will develop the world's simplest sequential workflow using XAML, add few rules 'declaratively' i.e. in XAML and then insert some code of displaying in console. We will learn a declarative programming model, play with XAML and see how integration of XAML and code can work!

Let's start the show

To all alpha blue geeks, I salute their patience for bearing all my theoretical musings till now, and invite them into venturing some real exciting practical work. Click on 'Microsoft Visual Studio 2005' in your Start menu, select 'Create New Project' and select 'Sequential Workflow Console Application'.

Screenshot - image001.jpg

By default, Workflow Project includes code based workflow file, now since we would rather want to play with XAML, we will delete the file. Right-click project in 'Solutions Explorer', select 'Add New Item' and select 'Sequential Workflow with Code Separation' file. 'Code Separation' is an indicator that we are doing 'something exciting' (read: XAML) separate than crude code here.

Screenshot - image002.jpg

That done, click on 'Add' and you would see standard empty workflow designer window. Hang here for a moment and let's explore what files are included in our pet project. In the 'Solution Explorer' window, there is MyWorkflow.xoml, this is the file that contains our XAML for workflow. Since workflow is empty right now, if you open-up the file, it would only have header node. [You can view XAML by right-clicking the file and selecting 'view in browser' or alternatively, go into the project folder, selecting MyWorkflow.xoml file and opening in your favorite XML editor.]. Here is how MyWorkflow.xoml should be look like currently.

XML
<SequentialWorkflowActivity x:Class="FirstXAMLWFApplication.MyWorkflow 1"   
    Name="MyWorkflow 1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

</SequentialWorkflowActivity>

Let's do a quick look at it with a magnifying glass. The root element is the 'Sequential Workflow Activity'; as it should be, since we are developing a sequential workflow application.

The other option is StateMachineWorkflowActivity. The element has two important attributes; Class and Name, where 'Class' specifies fully classified name of our workflow class, 'Name' is simply our workflow's 'name' property value.

To quench our thirst for doing-something-exciting, let's add a While activity in our workflow. A While activity is part of Microsoft's provided 'Base Activity Library' which contains numerous activities that are used in a variety of workflows, irrespective of which business domain they belong to. A few activities in the library are: Code, IfElse, Delay, WebServiceInput, Replicator etc.

The While activity is one of the simplest and mostly used. Almost every workflow has task(s) that are needed to run in iteration; hence While activity, where unless a particular condition is fulfilled, the loop continues to run a specific activity.

We can always add the While activity by doing a drag-drop in the Workflow designer window, but let's play with the cool and crude XAML first.

Open up MyWorkFlow.xoml and add the following code (shown in bold).

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

Save the file and switch back to VS.NET IDE and open up workflow. It will look like:

Screenshot - image003.jpg

Cool right!? But can you see that red exclamation sign? It is denoting the fact that we haven't specified any condition for the loop to terminate. Let's go into the code and add a protected variable in the workflow class. Code excerpt:

C#
namespace FirstXAMLWFApplication
{
     public partial class MyWorkflow : SequentialWorkflowActivity
     {
         public Int32 counter;
     }
}

Go back to the designer window and select 'Declarative Rule Condition' in the 'Condition' property of the While activity, then click on 'Ellipse' of 'Condition Name'. The following dialog should display.

Screenshot - image004.jpg

Click on 'Add' to go to the 'Rule Condition Editor' and add the following condition.

Screenshot - image005.jpg

We have added a simple condition here which will make the While loop continue until counter reaches 10, where it will terminate. This is probably a good time to go back to our XAML file and see how this declarative condition got added in it.

XML
<SequentialWorkflowActivity x:Class="FirstXAMLWFApplication.MyWorkflow" 
    x:Name="MyWorkflow"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
    <WhileActivity x:Name="whileActivity1">
        <WhileActivity.Condition>
            <RuleConditionReference ConditionName="Condition1" />
        </WhileActivity.Condition>
    </WhileActivity>
</SequentialWorkflowActivity>

"Well, I can see the condition property is set as Condition1 which was the name of our recently added condition, but where is the actual condition statement?" Good question! There is a separate file in a project named as MyWorkflow.rules, all rules are kept in this file. For brevity's sake, I am not adding an excerpt from the file (though you can always download it along with the attached code at the top of the article to have a detailed look into it). For now, let it suffice that our declarative rule statement is present in the .rules file, while the condition name goes into XAML. This again shows us the power of using XAML for designing workflows, as I can add a million rules in my project and relate it with some particular activity by adding a single line in XAML! And can even later edit/replace it by simply changing the name of the condition and that's it!

That's good enough for making the while activity execute, now let's add an activity within this one. You can think of it as the loop's body. Here we will add an IfElse activity and then a Code activity for each IfElse branch within the While activity. This time we will use power of VS IDE and simply drag-drop activities within workflow designer. The final shape of workflow after the addition of these new activities would be like:

Screenshot - image006.jpg

As we can see, the IfElse activity has two branches. One is executed when the If condition is true and the other when the else condition is true. We will assign proper conditions to each of branch, but for now let's have a look at our XAML file to see how this change in workflow got translated in it.

XML
<SequentialWorkflowActivity x:Class="FirstXAMLWFApplication.MyWorkflow" 
    x:Name="MyWorkflow" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
    <WhileActivity x:Name="whileActivity1">
        <WhileActivity.Condition>
            <RuleConditionReference ConditionName="Condition1"/>
        </WhileActivity.Condition>
     <IfElseActivity x:Name="ifElseActivity1">
            <IfElseBranchActivity x:Name="ifElseBranchActivity1">
                <CodeActivity x:Name="codeActivity1"
                    ExecuteCode="codeActivity1_ExecuteCode" />
            </IfElseBranchActivity>
            <IfElseBranchActivity x:Name="ifElseBranchActivity2">
                <CodeActivity x:Name="codeActivity2"
                    ExecuteCode="codeActivity2_ExecuteCode" />
            </IfElseBranchActivity>
        </IfElseActivity>
    </WhileActivity>
</SequentialWorkflowActivity>

Simple and structured? You bet it is! Bold statements shows our new IfElse and Code activities. Now we add simple conditions in each branch of the IfElse activity. For keeping it simple, we will simply check if the counter is even or odd, and on the basis of this condition check, send each control to each branch. We will add these two rules and assign them to each branch using the same mechanism (from the Properties window -> Select Condition -> Rule Condition Editor) as we did for While activity. Our condition for each branch will be:

C#
this.counter
% 2 == 0  // for even
this.counter
% 2 != 0  // for odd

Finally, our 'Select Condition' looks like:

Screenshot - image007.jpg

Hey! Didn't I say we will write some code? Yes I did, and it is time to do so. Select 'CodeActivity1', click on 'Generate Handlers' in the 'Properties' window and delve into its handler code. Add the following code in it. We have simply displayed on the console announcing this is an even number and incremented our counter variable.

C#
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
    Console.WriteLine("Hello! " + Convert.ToString(counter) + 
        " is an even number!");
    counter++;
}
Similarly, add following code for 'CodeActivity2'.
C#
private void codeActivity2_ExecuteCode(object sender, EventArgs e)
{
    Console.WriteLine("Hello! " + Convert.ToString(counter) + 
        " is an odd number!");
    counter++;
}

Yey! That's it. We have our complete workflow. Let's go through what we did.

  1. We added a while activity using XAML.
  2. We added a condition in the while activity 'declaratively'. The condition simply checks whether the counter field is less than 10
  3. We then drag-dropped IfElse and CodeActivity within While activity.
  4. Proper conditions were added in each branch of the IfElse activity to check whether its an even / odd number
  5. Code was added in the Code activity handler for display at console and incrementing the counter field.

Workflow runtime needs a host to run workflows. Our host will be a simple console application. Our project contains Progam.cs, here our workflow runtime will actually get started. A workflow instance is created, executed and then runtime gets closed. There is not much science here; pretty simple code generated by VS IDE for us:

C#
static void Main(string[] args)
{
    using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
    {
        AutoResetEvent waitHandle = new AutoResetEvent(false);
        workflowRuntime.WorkflowCompleted += delegate(object sender,              
            WorkflowCompletedEventArgs e) {waitHandle.Set();};
        workflowRuntime.WorkflowTerminated += delegate(object sender,
            WorkflowTerminatedEventArgs e)
        {
            Console.WriteLine(e.Exception.Message);
            waitHandle.Set();
        };

        WorkflowInstance instance = workflowRuntime.CreateWorkflow(
            typeof(FirstXAMLWFApplication.MyWorkflow));
        instance.Start();

        waitHandle.WaitOne();
        Console.ReadKey();
    }
}

A new runtime object is created. Two event handlers are provided for 'Completed' and 'Terminated' statuses for Workflow. Then 'Create Workflow' is called to get an instance of our workflow and 'Start' is called to launch it. The runtime engine will execute our workflow asynchronously, therefore, we need to block our thread on the AutoResetEvent object and wait for workflow to complete (otherwise even before we could see what's written on our console window, it will close and the program will exit!). Now, using AutoResetEvent means the thread will be blocked until it is 'set' in complete event handler.

That is it, buddies. Click on 'Run' and watch the show. Well our output will not have much for our aesthetic senses, but it should give us good idea about what XAML is. Why and how to use it with Workflow Foundation.

Our output window looks like:

Screenshot - image008.jpg

What more we can do with XAML in Workflow Foundation?

A lot! We can even design fully XAML-based workflows and we won't even need to compile them. That is, one can just design a workflow using XAML (any tool other than Visual Studio can also be used, after all it's all about creating/altering an XML-like document) and deploy it to run. 'XAML Activation' is used in place of compilation to launch the workflow. This was beyond scope of this article and we opted or a mid-way approach, of using both XAML and code (declarative and imperative programming model) as this is how workflows are vastly designed and implemented.

Where to find more

My favorite books/links remain same as was specified in my previous articles.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here