Here is the document from the Dynamics AX workflow team on how to enable workflow controls in EP. You can also take a look at PurchReqTableInfo or TrvExpTrans controls in out of the box EP which are workflow enabled. Thanks Josh Honeyman for sending this info to me.

1.1.        WorkflowActionBar control

The WorkflowActionBar control surfaces a message bar and an actions menu button to the user. This provides context of the workflow action that needs to be taken along with surfacing the button to take the action. 

 

Since this control requires the data to be loaded in order to render, it is sub-classed from the ASP.NET DataBoundControl.   The rendering of data bound controls occurs after the associated data source control has executed its data set.   This allows us to look up workflow specific information for the current workflow-enabled record and then dynamically add the necessary controls to the WorkflowActionBar.  The PerformDataBinding method is overridden and provides this logic to build up our controls when the data is ready.

 

 

A set of events are exposed as the primary interaction with the control.

 

Adding control in markup

Just like any other web control, this WorkflowActionBar control can be added via markup or the designer.  Since this is a DataBoundControl, the DataSourceID and DataMember properties MUST be set.  The DataMember property must be set to the table that is workflow enabled.

 

 

<dynamics:AxDataSource ID=" IssuesDatasource " DataSetName="Issues" runat="server">

</dynamics:AxDataSource>

 

<dynamics:WorkflowActionBar ID="WorkflowActionBar" runat="server" DataSourceID="IssuesDatasource" DataMember="IssuesTable_Current"/>

 

 

 

EvaluatingCanSubmitToWorkflow event

This event will fire when the control is attempting to determine if the current record is in a state to be submitted to workflow.  The control does not have any knowledge of the state of the document, thus the application developer MUST subscribe to this event.

 

 

void Page_Init(object sender, EventArgs e)

{

    //Subscribe to the EvaluatingCanSubmitToWorkflow event

this.WorkflowActionBar.EvaluatingCanSubmitToWorkflow += new   EventHandler<EvaluatingCanSubmitToWorkflowEventArgs>(WorkflowActionBar_EvaluatingCanSubmitToWorkflow);

}

 

 

void WorkflowActionBar_EvaluatingCanSubmitToWorkflow(object sender, EvaluatingCanSubmitToWorkflowEventArgs e)

{

    // Evaluate state of document and set value to true or false

    e.CanSubmitToWorkflow = true;

}

 

 

 

WorkflowConfigurationLoading event

This event will fire when the control is attempting to infer and load a configuration for the current submit-able record.   If a valid configuration record is set onto the event args, the control will use that instead of doing the inference based on activation conditions, record type, etc.

 

 

void Page_Init(object sender, EventArgs e)

{

    //Subscribe to the WorkflowConfigurationLoading event

this.WorkflowActionBar.WorkflowConfigurationLoading += new EventHandler<WorkflowConfigurationLoadingEventArgs>(WorkflowActionBar_WorkflowConfigurationLoading);

}

 

 

void WorkflowActionBar_WorkflowConfigurationLoading(object sender, WorkflowConfigurationLoadingEventArgs e)

{

    ISession session = this.AxSession;

 

//Use a proxy class to retrieve your desired workflow configuration    e.WorkflowConfiguration =    YourProxy.loadWorkflowConfiguration(session.AxaptaAdapter);

}

 

 

 

WorkflowConfigurationActive event

This event will fire after the control has retrieved a configuration for the submit-able record.   If the consumer of the control provided the configuration via subscribing to the WorkflowConfigurationLoading event, this is not an interesting event.  However, if the control inferred the configuration by mapping the record type to an enabled configuration and/or evaluated activation conditions, this event may be interesting to the consumer.   The event args will provide the active configuration record to the subscriber.

 

 

void Page_Init(object sender, EventArgs e)

{

    //Subscribe to the WorkflowConfigurationActive event

this.WorkflowActionBar.WorkflowConfigurationActive += new EventHandler<WorkflowConfigurationActiveEventArgs>(WorkflowActionBar_WorkflowConfigurationActive);

}

 

void WorkflowActionBar_WorkflowConfigurationActive(object sender, WorkflowConfigurationActiveEventArgs e)

{

    // Do something interesting with the configuration

    IAxaptaRecordAdapter workflowConfiguration = e.WorkflowConfiguration;  

}

 

 

 

WorkflowWorkItemActive event

This event will fire after the control has retrieved a pending work item for the current user and current record.  Also, when we add support for multiple work items being displayed in this control (i.e. multiple workflows acting on the same record), this event will get fired when the context is switched between the work items on the current record.   The consumer can retrieve the active work item via subscribing to this event.

 

 

 

void Page_Init(object sender, EventArgs e)

{

    //Subscribe to the WorkflowWorkItemActive event

this.WorkflowActionBar.WorkflowWorkItemActive += new EventHandler<WorkflowWorkItemActiveEventArgs>(WorkflowActionBar_WorkflowWorkItemActive);

}

 

void WorkflowActionBar_WorkflowWorkItemActive(object sender, WorkflowWorkItemActiveEventArgs e)

{

    // Do something interesting with the workflow work item.

    IAxaptaRecordAdapter workflowWorkItem = e.WorkflowWorkItem;

}

 

 

 

1.2.        EPWorkflowWorkItemActionManager

This X++ class contains a generic menu item class implementation to associate to work item specific web menu items (Outcomes, Delegate, and Resubmit).   Instead of every application developer building their own menu item classes to manage calling the necessary work item APIs, this class provides a default implementation that can be used.

 

main

 

public static void main(Args _args)

 

This is the method invoked when a web menu item is selected in the workflow action bar or from the unified work list.   This contains the generic implementation of handling a work item action selected.

 

1.3.        EPWorkflowControlContext

This X++ class will expose the current context of the workflow controls, as in the controls are referencing a workflow comment, a user (for delegate and request change), an active workflow configuration or an active work item.   This context information must flow to the menu item classes when a workflow menu item is selected from EP.   From the Args passed into the menu item class, you will be able to retrieve the EPWorkflowControlContext from Args.caller and then invoke the following APIs to retrieve the desired workflow information.

 

getActiveWorkflowConfiguration

 

public WorkflowConfigurationTable getActiveWorkflowConfiguration()

 

This method will retrieve the current active workflow configuration for the current record.  This provides an X++ programming model for getting at the information retrieved by the workflow controls.

 

getActiveWorkflowWorkItem

 

public WorkflowWorkItemTable getActiveWorkflowWorkItem()

 

This method will retrieve the current active workflow work item for the current record.  This provides an X++ programming model for getting at the information retrieved by the workflow controls.

 

getWorkflowComment

 

public WorkflowComment getWorkflowComment()

 

This method will retrieve the comment entered for the current workflow action.  This provides an X++ programming model for getting at the information retrieved by the workflow controls.

 

getWorkflowReassignedUser

 

public userId getWorkflowReassignedUser()

 

This method will retrieve the user selected within the workflow comments dialog (if the action was delegate or request change).  This value will be empty for all other workflow actions.  This provides an X++ programming model for getting at the information retrieved by the workflow controls.

 

Sample menu item class implementation (processing approve action for a work item)

public static void main(Args _args)

{

    WorkflowComment             comment;

    WorkflowWorkItemTable    workItem;

    EPWorkflowControlContext context =_args.caller();

    ;

   

    // retrieve active work item from workflow control context

    workItem = context.getActiveWorkflowWorkItem();

 

    if (workItem != null)

    {

        comment = context.getWorkflowComment();

 

        // take the action on the work item

        WorkflowWorkItem::takeAction(workItem.Id, 'Approve', comment);

    }

}