Dimension Controls in a Dialog for AX7


I’ve received a few questions regarding a post on the AX R&D Yammer group about how to add default dimension controls to a dialog in the new Dynamics AX.  Dialogs are unique in that they often do not have a data source, however there are valid cases to still support the selection of dimensions for batch jobs or other periodic processes.

As I’ve blogged about previously for AX 2012, there used to be a class called DimensionDefaultingControllerNoDS for exactly this purpose.  However this class has been deprecated, so we need to go down a new path!  To put it simply, we just need to create our own custom control type, let’s call it “Dimension Entry No Datasource” control.

Firstly, create an extension package so that you are not tempted to overlayer code. Be sure to include the Dimensions model in your package.  Visit the Dynamics ‘AX7’ menu and create a new model:

Name it however you wish:

And select extension package:

Include any other packages you want to reference.  Think of this as an assembly (DLL) referencing other assemblies. 

Extensions is the new bag, baby!

Create a new class in your model, and extend the DimensionEntryControl class:

  1. [FormControlAttribute('Group', '', classStr(DimensionEntryControlBuildNoDS))]
  2. class DimensionEntryControlNoDS extends DimensionEntryControl
  3. {
  4. public DimensionDefault getDimensionRefRecId()
  5. {
  6. return this.parmDimensionValueSetId();
  7. }
  8.  
  9. }
  10.  

You’ll notice in the metadata I’ve also drafted a separate extension class for DimensionEntryControlBuildNoDS as well. 

In the class example above, you’ll see we have overridden the getDimensionRefRecId() method which is declared as Protected in the parent class.  By setting it to public, we can use it as required in our dialog form.

Build your package from the AX7 menu. 

Now it’s time to make use of your training in SysOperation Framework from AX 2012! Create a new controller class which extends SysOperationServiceController, in this example I’ve called it MyController.  Override the templateForm() method and specify a new form:

  1. class MyController extends SysOperationServiceController
  2. {
  3.  
  4. /// <summary>
  5. /// Swenka internal use only.
  6. /// </summary>
  7. /// <returns>
  8. /// A <c>formName</c> value.
  9. /// </returns>
  10. protected FormName templateForm()
  11. {
  12. return formStr(MyTemplateForm);
  13. }
  14.  
  15. public static void main(Args _args)
  16. {
  17. MyController c = new MyController();
  18. c.initializeFromArgs(_args);
  19. c.startOperation();
  20. }
  21.  
  22. }
  23.  
  24.  
  25.  

The new form I’m using above called MyTemplateForm is just a duplicate of the SysOperationTemplateForm.  Expand the design to the DialogStartGrp group which is the main group for any SysOperation dialog.

Add your new custom dimension control here by right-click and new control:

Typically a dimension entry control can infer the type of dimension entry we are requiring based on the Extended Data Type (EDT) of the table field that is associated to the control.  This will either be a Default Dimension such as on master data, or a Ledger Dimension such as on General Journal lines. 

In our case however, we have no datasource on the form. So we must specify explicitly the default dimension controller class in the control properties.  Also set the auto declare to True.

From here it is a quick couple lines of code in the init() of the form to tell the control to display values upon loading:

  1. public void init()
  2. {
  3. super();
  4. DimensionEntryControlNoDS.parmDisplayValues(true);
  5.  
  6. }
  7.  
  8.  

And upon closing the dialog we want to capture that default dimension recId and save it to our data contract for use in our service:

  1. // <summary>
  2. /// Command control message called when the form's OK button is clicked.
  3. /// </summary>
  4. public void closeOk()
  5. {
  6. if (this.controller().checkCloseDialog())
  7. {
  8. super();
  9. var someRecId = DimensionEntryControlNoDS.getDimensionRefRecId();
  10. //now we need to save this in the data contract
  11. //via calling...
  12.  
  13. DataContract c = this.controller().getDataContractObject('_myContractParameterName');
  14. c.parmDim(someRecId);
  15. //now we can close the form, and execute the job
  16.  
  17. if(this.controller().skipRunOperation())
  18. {
  19. this.controller().skipRunOperation(false);
  20. }
  21. else
  22. {
  23. this.controller().dialogClosedWithOk(this.dialog());
  24. }
  25. }
  26. }
  27.  
  28.  

Using a simple action menu item to invoke the service, we can see the dialog displays our default dimensions for the current legal entity: