31 Mar 2009

Rich Allen running for charity this weekend

Fellow Southampton coordinator Rich Allen is running a HUGE distance (10K, ow!) this weekend to raise money for the British Heart Foundation.

So if you want to sponsor Rich, go along here and chuck some money at him.

Best of luck Rich! We want photos :)

WF 4.0 – Part 3. Custom Composite Activities

The following is based on the PDC CTP of WF 4.0 and as such might change or be missing in futures releases.

In Parts 1 and 2 we looked at the different types of Workflow and their respective designers available in the CTP of WF 4.0. In the next couple of parts we will look at how we go about creating our own custom Activities.

As previously mentioned, there has been a shift in the way we create and implement our Workflows. We no longer need to write C# to create a workflow, instead we use XAML. This is also true for Activities, as there are 2 kinds of Activities we can create in WF 4.0 which are Composite and Workflow Elements.

The Composite Activity is built up from other Activities and uses one of the Workflow types as it’s basis. This is a change in the way we think about Workflows, in 3.x we saw Workflows as containers that could only contain Activities, now Workflows can contain Workflows which contain Workflows etc. This new approach will allow us to capture and declare far more complex Processes and State Machines than in 3.x.

Composite Activities

So lets start by creating a Composite Activity. In this example we’re going to create a new Activity that is going to be used in the theoretical process of a User Group member arriving at a meeting and signing in. The Activity will basically be in charge of asking them there name, some sort of password and saying hello to them.

So first off we create a new Blank Activity and its designer is displayed. At this point we can either add in a single existing Activity or a Workflow.

Because my Activity is essentially making decisions, I am going to add a FlowChart Workflow to be the basis of my new Activity, this will allow me to add multiple Activities that will execute in a specific order.

Now the steps needed to perform our activity are as follows:

  1. Greet the User
  2. Ask for their confirmation code (given to them when they registered)
  3. Depending on whether the code is valid
    1. Welcome the user
    2. Give them another attempt to register

Now this Workflow is actually going to loop forever until a valid code is input, but in real life we’d give the user some sort of option to give up.

I’m going to be using our old friends the WriteConsole and ReadConsole Activities for this, as well as a new custom activity that checks the Users input against a confirmation code. The process is exactly the same as creating a Workflow, I drag the Activities on I want to use and connect them together. This leaves me with an Activity that looks like this:

Here are Variables and Arguments:

So what does the XAML look like for this?


   1: <p:Activity x:Class="DemoChart.GreetingActivity" xmlns:c="clr-namespace:CustomActivities;assembly=CustomActivities" xmlns:p="http://schemas.microsoft.com/netfx/2009/xaml/workflowmodel" xmlns:p1="http://schemas.microsoft.com/netfx/2008/xaml/schema" xmlns:p2="http://schemas.microsoft.com/xps/2005/06" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:swd="clr-namespace:System.WorkflowModel.Debugger;assembly=System.WorkflowModel" xmlns:swdv="clr-namespace:System.WorkflowModel.Design.View;assembly=System.WorkflowModel.Design" xmlns:swdx="clr-namespace:System.WorkflowModel.Design.Xaml;assembly=System.WorkflowModel.Design" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x2="http://schemas.microsoft.com/netfx/2008/xaml">
   2:   <p1:SchemaType.Members>
   3:     <p1:SchemaProperty Name="AttendeeName" Type="p:InArgument(p1:String)" />
   4:   </p1:SchemaType.Members>
   5:   <p:Flowchart DisplayName="Flowchart" swd:XamlDebuggerXmlReader.FileName="C:\Users\Administrator\Documents\Visual Studio 10\Projects\1_Designer_Demo\DemoChart\GreetingActivity.xaml">
   6:     <p:Flowchart.Variables>
   7:       <p:Variable x:TypeArguments="p1:Int32" Name="_attendeeCode" />
   8:       <p:Variable x:TypeArguments="p1:Boolean" Default="[False]" Name="_codeValid" />
   9:     </p:Flowchart.Variables>
  10:     <p:FlowStep>
  11:       <p:FlowStep.Action>
  12:         <c:WriteLine DisplayName="GreetAttendee" Text="[String.Concat(&quot;Welcome &quot;, AttendeeName)]">
  13:           <swdv:WorkflowViewStateService.ViewState>
  14:             <scg:Dictionary x:TypeArguments="p1:String, p1:Object">
  15:               <p2:Point x:Key="ShapeLocation">160,82.02</p2:Point>
  16:               <p2:Size x:Key="ShapeSize">160,35.96</p2:Size>
  17:             </scg:Dictionary>
  18:           </swdv:WorkflowViewStateService.ViewState>
  19:         </c:WriteLine>
  20:       </p:FlowStep.Action>
  21:       <swdv:WorkflowViewStateService.ViewState>
  22:         <scg:Dictionary x:TypeArguments="p1:String, p1:Object">
  23:           <p2:PointCollection x:Key="PolylineLocation">240,117.98 240,142.02</p2:PointCollection>
  24:         </scg:Dictionary>
  25:       </swdv:WorkflowViewStateService.ViewState>
  26:       <p:FlowStep x:Name="__ Reference ID 0">
  27:         <p:FlowStep.Action>
  28:           <c:WriteLine DisplayName="RequestMeetingCode" Text="[&quot;Please enter your metting confirmation code&quot;]">
  29:             <swdv:WorkflowViewStateService.ViewState>
  30:               <scg:Dictionary x:TypeArguments="p1:String, p1:Object">
  31:                 <p2:Point x:Key="ShapeLocation">160,142.02</p2:Point>
  32:                 <p2:Size x:Key="ShapeSize">160,35.96</p2:Size>
  33:               </scg:Dictionary>
  34:             </swdv:WorkflowViewStateService.ViewState>
  35:           </c:WriteLine>
  36:         </p:FlowStep.Action>
  37:         <swdv:WorkflowViewStateService.ViewState>
  38:           <scg:Dictionary x:TypeArguments="p1:String, p1:Object">
  39:             <p2:PointCollection x:Key="PolylineLocation">240,177.98 240,222.02</p2:PointCollection>
  40:           </scg:Dictionary>
  41:         </swdv:WorkflowViewStateService.ViewState>
  42:         <p:FlowStep x:Name="__ Reference ID 1">
  43:           <p:FlowStep.Action>
  44:             <c:ReadLine DisplayName="GetAttendeeCode" outArgument="[_attendeeCode]">
  45:               <swdv:WorkflowViewStateService.ViewState>
  46:                 <scg:Dictionary x:TypeArguments="p1:String, p1:Object">
  47:                   <p2:Point x:Key="ShapeLocation">160,222.02</p2:Point>
  48:                   <p2:Size x:Key="ShapeSize">160,35.96</p2:Size>
  49:                 </scg:Dictionary>
  50:               </swdv:WorkflowViewStateService.ViewState>
  51:             </c:ReadLine>
  52:           </p:FlowStep.Action>
  53:           <swdv:WorkflowViewStateService.ViewState>
  54:             <scg:Dictionary x:TypeArguments="p1:String, p1:Object">
  55:               <p2:PointCollection x:Key="PolylineLocation">240,257.98 240,282.02</p2:PointCollection>
  56:             </scg:Dictionary>
  57:           </swdv:WorkflowViewStateService.ViewState>
  58:           <p:FlowStep x:Name="__ Reference ID 2">
  59:             <p:FlowStep.Action>
  60:               <c:CodeCheck CodeToCheck="[_attendeeCode]" IsValid="[_codeValid]">
  61:                 <swdv:WorkflowViewStateService.ViewState>
  62:                   <scg:Dictionary x:TypeArguments="p1:String, p1:Object">
  63:                     <p2:Point x:Key="ShapeLocation">160,282.02</p2:Point>
  64:                     <p2:Size x:Key="ShapeSize">160,35.96</p2:Size>
  65:                   </scg:Dictionary>
  66:                 </swdv:WorkflowViewStateService.ViewState>
  67:               </c:CodeCheck>
  68:             </p:FlowStep.Action>
  69:             <swdv:WorkflowViewStateService.ViewState>
  70:               <scg:Dictionary x:TypeArguments="p1:String, p1:Object">
  71:                 <p2:PointCollection x:Key="PolylineLocation">240,317.98 240,350</p2:PointCollection>
  72:               </scg:Dictionary>
  73:             </swdv:WorkflowViewStateService.ViewState>
  74:             <p:FlowDecision False="{x2:Reference Name=&quot;__ Reference ID 0&quot;}" x:Name="__ Reference ID 3" Condition="[_codeValid]">
  75:               <p:FlowDecision.True>
  76:                 <p:FlowStep x:Name="__ Reference ID 4">
  77:                   <p:FlowStep.Action>
  78:                     <c:WriteLine DisplayName="Thanks" Text="[&quot;Thanks for coming!&quot;]">
  79:                       <swdv:WorkflowViewStateService.ViewState>
  80:                         <scg:Dictionary x:TypeArguments="p1:String, p1:Object">
  81:                           <p2:Point x:Key="ShapeLocation">20,462.02</p2:Point>
  82:                           <p2:Size x:Key="ShapeSize">160,35.96</p2:Size>
  83:                         </scg:Dictionary>
  84:                       </swdv:WorkflowViewStateService.ViewState>
  85:                     </c:WriteLine>
  86:                   </p:FlowStep.Action>
  87:                 </p:FlowStep>
  88:               </p:FlowDecision.True>
  89:               <swdv:WorkflowViewStateService.ViewState>
  90:                 <scg:Dictionary x:TypeArguments="p1:String, p1:Object">
  91:                   <p2:Point x:Key="ShapeLocation">210,350</p2:Point>
  92:                   <p2:Size x:Key="ShapeSize">60,60</p2:Size>
  93:                   <p2:PointCollection x:Key="TruePolylineLocation">210,380 100,380 100,462.02</p2:PointCollection>
  94:                   <p2:PointCollection x:Key="FalsePolylineLocation">270,380 398.5,380 398.5,160 320,160</p2:PointCollection>
  95:                 </scg:Dictionary>
  96:               </swdv:WorkflowViewStateService.ViewState>
  97:             </p:FlowDecision>
  98:           </p:FlowStep>
  99:         </p:FlowStep>
 100:       </p:FlowStep>
 101:     </p:FlowStep>
 102:     <x2:Reference Name="__ Reference ID 1" />
 103:     <x2:Reference Name="__ Reference ID 0" />
 104:     <x2:Reference Name="__ Reference ID 2" />
 105:     <x2:Reference Name="__ Reference ID 3" />
 106:     <x2:Reference Name="__ Reference ID 4" />
 107:   </p:Flowchart>
 108: </p:Activity>


As you can see that’s a fairly comprehensive bit of XAML, which is understandable as there is no code behind anywhere in this Workflow. We can now use this Activity on a Workflow, and this is what it will look like.And if we look at the Properties for the placed Activity, we can see our AttendeeName argument that we added to allow us to greet individuals by name.

As this is an InArgument, it allows for expression binding. Had we used just a plain String property on there, we would not be able to use the expression functionality.

In the next part, we will look at creating our own custom Activities in code (items called Workflow Elements) and how to skin them.

30 Mar 2009

WebDD registration goes live!

It’s been a while coming, but the second WebDD is coming to the Microsoft Campus in Thames Valley Park on the 18th April.

This is a free one day Web orientated event and they’ve confirmed a whole host of excellent speakers, you can see the schedule here.

To register go here.

25 Mar 2009

1st meeting of the UK South Scrum User Group

Southampton NxtGenUG member and Agile speaker Plamen Balkanski has set the date for the first meeting of his new UK South Scrum User Group.  The meeting will be on the 27th April at the Inn of the Furlong pub in Ringwood.  You can get details of how to get to the pub and register here.

This is a very exciting User Group dedicated to all things Agile and Scrum! So something not to be missed!

See you there!

17 Mar 2009

Fest 09 registration opens!

This years Fest has now opened for registration.  Places are limited to paid up members only at the present time, but may open up to everyone else at a later date.

So if you’re a paid up member head over to registration now and grab your spot as places are rapidly disappearing!

This year we’re be at the Microsoft Research in Cambridge, and have some of the research guys from Microsoft giving talks!  It promises to be an excellent day :)

11 Mar 2009

Live Messenger and Windows 7

I installed Live Writer today so i didn’t need to be online to blog, especially now that I’m writing the WF 4.0 stuff and could well be commuting again soon.

As part of the Live Writer you get a whole host of tools you can also I install, most of which I passed on except for the Office tools and Messenger. I’m glad I did!

The new messenger has disappeared from the system tray and now lives full time in the Task Bar. Here’s the new icon:

and when I become busy, the little green circle goes red.

As you’d expect with apps designed for Windows 7 it has a new menu that you can open from the Task Bar. This is basically all the options you had on the menu from the System Tray.

The final change I really liked, is a change in how the conversations are organised. It's now grouped by the speaker, so if you're doing all the talking, your bits are all grouped together.

I know it’s a lot of little changes, but somehow it improved the whole experience :) It’s also nice to see apps beginning to move away from living in the System Tray, as I think far too many apps end up living in the System Tray.

5 Mar 2009

WF 4.0 - Part 2. The Flowchart Workflow & Designer

Replaced with an updated post here.

WF 4.0 - Part 1. The Sequential Designer

This has now been superceeded by This Post

3 Mar 2009

DDD South West registration opens!

The Registration for DDD South West has now opened! Go register there immediatley!

DDD South West is a free one day technical event on Saturday 23rd May 2009 at Queens College, Taunton with lots of top speakers doing sessions on damn interesting stuff.

2 Mar 2009

Back from roaming around Italy

I've just a very pleasant 2 week roaming around Italy with my wife :) The whole point of going was to do a course in Lampwork Bead making in Florence run by Tim and Lily at Beaded Lilly Glass Works. They were absolutley top hosts and I'd thoroughly recommend anyone interested in learning lampwork beads to go out to them :) This is all part of a grand plan for my wife to start up her own Lampwork Bead emporium, the website should be up at the end of the month on www.BatfishBeads.com.

This is us making beads

In other random unrelated news Xbox Live arcade went and released two of my favourite games while I was away. The first will need no introduction as everyone know it as the best shmup ever, that's right R-Type Dimensions. These are two games I've been trying to track down for years for my Arcade Machine but they always seem to come up when things are tight, so this release should sate my appitite for the time being :)

The other game was a complete outsider. Way back in my college days a craze swept my course for a game called Scorched Earth. It took place on a randomly generated landscape with tanks randomly placed on it which each player controlled. The idea was to kill everyone else on the map and be the survivor. You got cash for each kill and could bigger and better weapons, from dirt mobs which covered your opponents and they had to dig out, to Nuke which obliterated half the map. It was good fun and passed the lunchtimes quickly :) Anywho, XBox Live have just released what looks like a remake of it and it's called Death Tank. I've tried the trial and it's cracking, the number of weapons was more limited but that could be just the trial... Anywho, go check it out, it's an excellent party game :D

Workflow, in the next couple of days I'm going to start posting a series of articles on WF 4.0. I'll start off with the creating a new custom activity and work my way up from there. So keep posted for more information. These articles will be based on the PDC build, so I'll update them when the Beta becomes available :)