none
How do I get the root activity from WorkflowDesigner?

    Question

  • I am using the WorkflowDesigner to load and edit XAML workflows, as per this post. I now need to get the root activity from the designer and pass it into a WorkflowApplication so that I can execute the workflow (the reason that I cannot reload the workflow from XAML is because I am having to implement custom visual workflow tracking (see this post) and need make sure that the same activity instances are loaded into the WorkflowDesigner and the WorkflowApplication). I was originally getting the root activity using:

    designer.Context.Services.GetService<ModelService>().Root.Properties["Implementation"].ComputedValue
    

    This was working fine until I tried loading a XAML workflow that had InArguments defined at the top level e.g.:

    <Activity x:Class="..."...>
      <x:Members>
        <x:Property Name="Msg1" Type="InArgument(x:String)" />
        <x:Property Name="Msg2" Type="InArgument(x:String)" />
      </x:Members>
      <Sequence>
        <WriteLine Text="Msg1" />
        <WriteLine Text="Msg2" />
      </Sequence>
    </Activity>
    

    In this case the above code returned me the Sequence, rather than the root Activity that contained the Sequence + the InArguments. As a result, when I try to run this via a WorkflowApplication I get the error:

    'VisualBasicValue<String>': Compiler error(s) encountered processing expression "Msg2".
    'Msg2' is not declared. It may be inaccessible due to its protection level.

    'VisualBasicValue<String>': Compiler error(s) encountered processing expression "Msg1".
    'Msg1' is not declared. It may be inaccessible due to its protection level.

    Does anyone know how to fix this?

    Thanks

    Akash

    Monday, May 16, 2011 3:25 PM

Answers

  • 3) Use SourceLocationProvider.CollectMapping for both the runtime and design-time root activities and join on SourceLocation to create the map - this works for activities that have source locations, but fails for activities such as FlowDecisions, which do not appear in the dictionary created by SourceLocationProvider.CollectMapping.

    [4)] The only way I have found to work around this is to assume that the runtime activity id = "1." + design-time activity id, which is true for any workflow I've created so far, but I'm nervous about relying on such behaviour.

    Am I missing something?


    Re 3):
    I think this is the same as in WF4 Visual Studio debugger (i.e. by design for VS10 release) - you can't debug FlowDecision or FlowSwitch. The reason is that they are not actually activities. When those conditions are being evaluated, the current activity is the Flowchart itself.

    Re [4)]:
    I think that it is probably worth trying a strategy based on this - it is safe to assume the suffixes are consistent, and the prefixes depend on exactly how your activity is being 'wrapped' by other activities, i.e. if you added an extra sequence outside the workflow before invoking it, the prefix would change, but in a way you can detect and compensate for.

    Tim
    Saturday, May 21, 2011 8:16 PM
    Moderator

All replies

  • At design time the Arguments of the workflow that you loaded are not actually on an activity, they are on an ActivityBuilder.

    You can't run an ActivityBuilder directly, instead you need to convert it to (programmatically) into an actual Activity. A typical approach is to serialize your workflow definition using WorkflowDesigner save, then reload it using ActivityXamlServices.Load().
    Tim
    Monday, May 16, 2011 7:11 PM
    Moderator
  • Ok, so if I serialize/deserialize to XAML then I have two copies of each activity - a runtime instance and a design-time instance. Then, for visual tracking and audit purposes I need to create a mapping between the runtime instance and the modelitem that wraps the design-time instance. How do I do that? The following approacbes all fail:

     

    1) Map by name - the activity names do not have to be unique within a workflow.

    2) Map by id - the ids of the runtime and design-time instances do not match e.g. the root Flowchart/Sequence typically had id="1" in design-time and id="1.1" in runtime.

    3) Use SourceLocationProvider.CollectMapping for both the runtime and design-time root activities and join on SourceLocation to create the map - this works for activities that have source locations, but fails for activities such as FlowDecisions, which do not appear in the dictionary created by SourceLocationProvider.CollectMapping.

     

    The only way I have found to work around this is to assume that the runtime activity id = "1." + design-time activity id, which is true for any workflow I've created so far, but I'm nervous about relying on such behaviour.

    Am I missing something?


    • Edited by drakc Friday, May 20, 2011 12:06 PM typo
    Wednesday, May 18, 2011 10:06 PM
  • 3) Use SourceLocationProvider.CollectMapping for both the runtime and design-time root activities and join on SourceLocation to create the map - this works for activities that have source locations, but fails for activities such as FlowDecisions, which do not appear in the dictionary created by SourceLocationProvider.CollectMapping.

    [4)] The only way I have found to work around this is to assume that the runtime activity id = "1." + design-time activity id, which is true for any workflow I've created so far, but I'm nervous about relying on such behaviour.

    Am I missing something?


    Re 3):
    I think this is the same as in WF4 Visual Studio debugger (i.e. by design for VS10 release) - you can't debug FlowDecision or FlowSwitch. The reason is that they are not actually activities. When those conditions are being evaluated, the current activity is the Flowchart itself.

    Re [4)]:
    I think that it is probably worth trying a strategy based on this - it is safe to assume the suffixes are consistent, and the prefixes depend on exactly how your activity is being 'wrapped' by other activities, i.e. if you added an extra sequence outside the workflow before invoking it, the prefix would change, but in a way you can detect and compensate for.

    Tim
    Saturday, May 21, 2011 8:16 PM
    Moderator