Friday, May 11, 2007 - Posts

Load WF State Transitions For The WF Host

When working with state machine workflows there is a need to notify the WF Host, of possible transitions or events that can be rendered, based on the current state of the workflow. This way the host can react to the workflow’s state rather than having to embed separate responsive logic within the host application. This can easily be accomplished by using the StateMachineWorkflowInstance object.

Consider a windows state machine workflow host that controls the flow of the workflow by firing events from different buttons on the form. Each button has an ID of an activity's ID represented within workflow. So now that each button represents the states of the workflow, let’s take a closer look and analyze the code below.

In the following method, UpdatePossibleStateTransitions, the System.Workflow.Activities.StateMachineWorkflowInstance is instantiated by passing in the running WorkflowRuntime and the running WorkflowInstanceId for the workflow instance that I am interested in retrieving possible transitions. The read-only generic collection, System.Collections.ObjectModel.ReadOnlyCollection is the object type that is set with current Workflow State’s possible state transitions, from the StateMachineInstance.PossibleStateTransitions object.

private void UpdatePossibleStateTransitions()
     Button cmd;
     StateMachineWorkflowInstance StateMachineInstance =
          new StateMachineWorkflowInstance(_wfRuntime, _wfInstance.InstanceId);
     System.Collections.ObjectModel.ReadOnlyCollectionstring> PossibleStates
          = StateMachineInstance.PossibleStateTransitions;
     foreach (Control cntrl in this.Controls)
          if (cntrl is Button)
              cmd = (Button)cntrl;
                    cmd.Enabled = false;
              foreach (string PossibleState in PossibleStates)
                  if (PossibleState == cmd.Name.Substring(3, cmd.Name.Length-3))
                      cmd.Enabled = true;

Now that the possible state transitions are loaded based on the current state of the workflow, the code loops through the controls on the form and finds only the controls that are Type Button. First all the buttons on the form are disabled except the one that actually stops the workflow runtime, and then the possible state activities are looped through matching buttons that have the same name as the iterated activity name, and then enabling those buttons that can be transition to as next possible transition(s).

There are two critical opportunities for getting possible state transitions. When a workflow instance is loaded from a persisted state and while the workflow instance is running. The above code can be called after a workflow instance is loaded, however if the workflow is never persisted, events need to be fired from the workflow to make the host aware that the state has changed.