How to create a custom composite activity
Designer:
<sap:ActivityDesigner x:Class="CompositeActivity.CompositeDesigner" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation" xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"> <StackPanel> <TextBlock>This is the Expanded View</TextBlock> <sap:WorkflowItemsPresenter HintText="Drop Activities Here" Items="{Binding Path=ModelItem.Activities}"> <sap:WorkflowItemsPresenter.SpacerTemplate> <DataTemplate> <Ellipse Width="10" Height="10" Fill="Black"/> </DataTemplate> </sap:WorkflowItemsPresenter.SpacerTemplate> <sap:WorkflowItemsPresenter.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </sap:WorkflowItemsPresenter.ItemsPanel> </sap:WorkflowItemsPresenter> </StackPanel> </sap:ActivityDesigner>
Code:
[Designer(typeof(CompositeDesigner))] public class MyCompsiteActivity : NativeActivity { // Define an activity input argument of type string public InArgument<string> Text { get; set; } private Variable<string> EmployeeID = new Variable<string>() { Name = "EmployeeID" }; public Variable<int> Index = new Variable<int>(); public Collection<Activity> Activities { get; set; } public Collection<Variable> Variables { get; set; } public MyCompsiteActivity() { Activities = new Collection<Activity>(); Variables = new Collection<Variable>(); } protected override void CacheMetadata(NativeActivityMetadata metadata) { base.CacheMetadata(metadata); metadata.SetChildrenCollection(Activities); foreach (Variable variable in this.Variables) { //declare a public variable metadata.AddVariable(variable); } //declare a implementation variable metadata.AddImplementationVariable(this.Index); metadata.AddVariable(this.EmployeeID); } protected override void Execute(NativeActivityContext context) { // Obtain the runtime value of the Text input argument string text = context.GetValue(this.Text); //this.EmployeeID.Set(context, 12); //Activity '1.1: MyCompsiteActivity' cannot access this variable because it is declared at the scope of activity '1.1: MyCompsiteActivity'. An activity can only access its own implementation variables. context.DataContext.GetProperties()["EmployeeID"].SetValue(context.DataContext,"123"); this.Index.Set(context, 0); ScheduleActivities(context); } void ScheduleActivities(NativeActivityContext context) { int currentIndex = this.Index.Get(context); if (currentIndex < this.Activities.Count) { context.ScheduleActivity(this.Activities[currentIndex], onActivityCompleted); this.Index.Set(context, currentIndex+1); } } void onActivityCompleted(NativeActivityContext context, ActivityInstance instance) { ScheduleActivities(context); } }
Note:
There must be a Public get method to make the designer can be edited
The "public variable" can't access directly because an activity can only access its own implementation variables. Hence, we using:
context.DataContext.GetProperties()["EmployeeID"].SetValue(context.DataContext,"123");
Workflow Foundation 4.0 Activity Data Model (III)
http://blogs.msdn.com/b/flow/archive/2010/04/27/workflow-foundation-4-0-activity-data-model-iii.aspx