Visual resizing

Hi!

I am re-hosting the workflow designer. Is there any way to enable visual resizing of the activites in the workflow?

Thanks!

[146 byte] By [FassaBortolo] at [2007-12-23]
# 1

hi guy.

there is three step you must follow.

1.

the Container Activity Designer of the activity you want to resize must inherited from FreeformActivityDesigner and override the bool CanResizeContainedDesigner property to return true .

2. you must override bool EnableVisualResizing property of the activities you will visualresizing.

3. protected override Size OnLayoutSize(ActivityDesignerLayoutEventArgs e)
{
return base.Size;
}

Matt.

MattLin at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 2

Thanks, but it did'nt work....

I have this activity who uses the BPDesigner:

[Designer(typeof(BPDesigner), typeof(IDesigner))]

[Designer(typeof(BPDesigner), typeof(IRootDesigner))]

public partial class WorkProcessStep : SequenceActivity

{

...

Now, the BPDesigner inhertits from FreeformActivityDesigner:

public class BPDesigner : FreeformActivityDesigner

{

...

protected override Size OnLayoutSize(ActivityDesignerLayoutEventArgs e)

{

return base.Size;

}

protected override bool CanResizeContainedDesigner(ActivityDesigner containedDesigner)

{

return true;

}

protected override bool EnableVisualResizing

{

get

{

return true;

}

}

}

Is this correct implemented? It didn't work. Any suggestion?

And, another question. Why should i inherit from the FreeformActivityDesigner class instead of the ActivityDesigner class.

Thanks!

FassaBortolo at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 3

hi.

the BPDesigner dose not need to be inherited from the FreeformActivityDesigner .

but the Designer of the container activity that contains WorkProcessStep Activity must Inherited from FreeformActivityDesigner.

because ,it the child activity be resize ,the parent activity's designer layout will be change. the FreeformActivityDesigner provider this funtion.

MattLin at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 4

Great!!

It's working, but now i can't see the sequential workflow from top to bottom (the arrows between the activities). I can move the activities free around the surface. Is this the freeformdesigner?

How can I implement the arrows etc from the sequential workflow into the freeformdesigner?

thanks a lot!

FassaBortolo at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 5

hi.

yes. in the FreeformDesigner. the child Activities can be move anywhere inside the FreeformDesigner bounds.

but if you will resize the activity , this function wounld be needed.

now ,you can use dragdrop mouse action to connect activities each other.

capture a source activity's connection point and drag to a target activity's connection point.

do this , a connector will be create by RootDesigner (at this time ,it is the FreeformDesigner) . you can override the FreeformActivityDesigner's CreateConnector virtual method to provide your custom connector if you wanted. but ,you do not need to do it. it default CreateConnector implemation work charmingly.

the finally step is very important .

you can override the child Activity's Designer (BPDesigner etc) OnConnected method to listen this connected event.

OnConnected has two parameters , source and target ,both are ConnectionPoint type.

then add a Activity type property named like "NextActivity" to WorkProcessStep.

for example

protected override void OnConnected(ConnectionPoint source, ConnectionPoint target)
{
base.OnConnected(source, target);
if (this == source.AssociatedDesigner)
{
Action _action = (Action)this.Activity;
_action.NextActivity = target.AssociatedDesigner.Activity;
//_action.NextActivityName = target.AssociatedDesigner.Activity.QualifiedName;
}
}

by the way ,maybe you also need two custom activities ,"StartWorkStep" end "EndWorkStep" .like UML Activity Diagram

Matt.

MattLin at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 6

Hi, thank you for the help! It's great!

I have implemented the nextActivity property and the onConnected event.

But, the workflow won't run in the correct order. If i drag activity1 and activity2 to the surface, and connect them with an arrow (activity1 = target and activity2 = source), activity1 still executes before activity2.

Any suggestions?

FassaBortolo at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 7

hi guy,

if you do above .

the workflow does not run in the order as same as the SequenceWorkflow does.

there is a little more thing you must finish.

you would override the Execute method of every CompositeActivity that can contains the WorkProcessStep.

and , there will be only one entry activity maybe named "WorkProcessStepStartActity" and some end Activity like "WorkProcessStepEnd". and ,do below step.

1. the Composite Activity must implemation IActivityEventListener<ActivityExecutionStatusChangedEventArgs> interface to listen the Statuschange Event of Child Activity help to Schedule Activity Execution.

2. override the CompositeActivity Execute method.

like sample code below

public class MyWorkFlow : CompositeActivity , IActivityEventListener<ActivityExecutionStatusChangedEventArgs>

{

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
Activity _StartExecute = this.StartChildActivity;


StartExecute .RegisterForStatusChange(Activity.ClosedEvent,this);

executionContext.ExecuteActivity( StartExecute ); // async invoke here

return ActivityExecutionStatus.Executing;
}

 public void IActivityEventListener<ActivityExecutionStatusChangedEventArgs>.OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)

{

 ActivityExecutionContext context1 = sender as ActivityExecutionContext;
 if(e.Activity is EndActivity)
{
 this.OnSequenceComplete(context1);

context1.CloseActivity();
}
else
{

 Activity _Activity = ((WorkProcessStep)e.Activity).NextActivity;
_Activity.RegisterForStatusChange(Activity.ClosedEvent,this);

context1.ExecuteActivity( _Activity); // async invoke here
}
}

}

by the way , that just be demo .maybe some more control will be added .

i hope these would give you some idea.

Matt.

MattLin at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 8

Ok. thank you (again).

I am maybe stupied, but i get som error messages:

Error 1 'ActivityLibrary.WorkflowSurface' does not contain a definition for 'StartChildActivity' c:\Windows Workflow Foundation\WorkProcessEditor\ActivityLibrary\WorkflowSurface.cs 22 42

Error 2 The type or namespace name 'EndActivity' could not be found (are you missing a using directive or an assembly reference?) c:\Windows Workflow Foundation\WorkProcessEditor\ActivityLibrary\WorkflowSurface.cs 31 31

Error 3 'ActivityLibrary.WorkflowSurface' does not contain a definition for 'OnSequenceComplete' c:\Windows Workflow Foundation\WorkProcessEditor\ActivityLibrary\WorkflowSurface.cs 33 22

I have not implemented startChildActivity and endActivity. I am not sure what you meant by this, and how to implement this? I have listed my code below.

Thanks a lot (again)!

[Designer(typeof(WorkProcessDesigner), typeof(IDesigner))]

[Designer(typeof(WorkProcessDesigner), typeof(IRootDesigner))]

public partial class WorkProcessStep : SequenceActivity

{

public static DependencyProperty NextActivityNameProperty = System.Workflow.ComponentModel.DependencyProperty.Register("NextActivityName", typeof(String), typeof(WorkProcessStep));

public static DependencyProperty NextActivityProperty = System.Workflow.ComponentModel.DependencyProperty.Register("NextActivity", typeof(WorkProcessStep), typeof(WorkProcessStep));

[Description("NextActivityName")]

[Browsable(true)]

[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

public String NextActivityName

{

get { return ((String)(base.GetValue(WorkProcessStep.NextActivityNameProperty))); }

set { base.SetValue(WorkProcessStep.NextActivityNameProperty, value); }

}

[Description("NextActivity")]

[Browsable(true)]

[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

public WorkProcessStep NextActivity

{

get { return ((WorkProcessStep)(base.GetValue(WorkProcessStep.NextActivityProperty))); }

set { base.SetValue(WorkProcessStep.NextActivityProperty, value); }

}

}

public class WorkProcessDesigner : ActivityDesigner

{

WorkProcessStep parentActivity;

protected override void Initialize(Activity activity)

{

base.Initialize(activity);

parentActivity = (WorkProcessStep)activity;

}

protected override void OnConnected(ConnectionPoint source, ConnectionPoint target)

{

base.OnConnected(source, target);

if (this == source.AssociatedDesigner)

{

parentActivity.NextActivityName = target.AssociatedDesigner.Activity.QualifiedName;

parentActivity.NextActivity = (WorkProcessStep)target.AssociatedDesigner.Activity;

}

}

}

[Designer(typeof(WorkflowSurfaceDesigner), typeof(IDesigner))]

[Designer(typeof(WorkflowSurfaceDesigner), typeof(IRootDesigner))]

public partial class WorkflowSurface : System.Workflow.ComponentModel.CompositeActivity, IActivityEventListener<ActivityExecutionStatusChangedEventArgs>

{

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

{

Activity StartExecute = this.StartChildActivity;

StartExecute.RegisterForStatusChange(Activity.ClosedEvent, this);

executionContext.ExecuteActivity(StartExecute); // async invoke here

return ActivityExecutionStatus.Executing;

}

void IActivityEventListener<ActivityExecutionStatusChangedEventArgs>.OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)

{

ActivityExecutionContext context1 = sender as ActivityExecutionContext;

if (e.Activity is EndActivity)

{

this.OnSequenceComplete(context1);

context1.CloseActivity();

}

else

{

Activity _Activity = ((WorkProcessStep)e.Activity).NextActivity;

_Activity.RegisterForStatusChange(Activity.ClosedEvent, this);

context1.ExecuteActivity(_Activity); // async invoke here

}

}

}

FassaBortolo at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 9

Hi guy.

because the WorkflowSurface has a task to Schedule child activity execution , it is not same to SequenceActivity that start by Activities[0]. as the WorkflowSurface allow child activity to be drag-drop anywhere,so it is important that the WorkflowSurface contains a special Activity that point it a workstep starter. and the workstep ender is also very necessary.

so , you maybe need to implement StartChildActivity and EndActivity

the 'OnSequenceComplete' method is a new method you need to add to WorkflowSurface class,

maybe, more suitable name can be "OnWorkflowSurfaceComplete",it 's not necessary..:) ( i am sorry for this puzzle)

protected void virtual OnWorkflowSurfaceComplete(ActivityExecutionContext executionContext)

{

/// can be override .

}

Matt./

MattLin at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 10

But, what should i implement in the OnWorkflowSurfaceComplete method?

FassaBortolo at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 11

hi.

see http://wf.netfx3.com/files/folders/activity_behavior/entry840.aspx

the sample maybe give you some ideat how to let workflow run in the correct order.

Matt

MattLin at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 12

Thanks, I have been using that example, and I think I have found a solution that work.

FassaBortolo at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...

Software Development for Windows Vista

Site Classified