Wednesday, April 25, 2007

Dynamics AX Tutorials - Tutorial 2 - Classes\Box

Here is a small project demonstrating capabilities of the class BOX in Dynamics AX.
Specifically, the following is covered in this tutorial:

  1. A short description of the system class BOX
  2. Creating a form from a class (using classFactory), launching different form methods, waiting for the form to be closed by the user and returning the selection
  3. Differences in implementation between DAX 3.0 and DAX 4.0

You can download the project from the following link:

  • download (for Dynamics AX 3.0 - only user layer)
  • download (for Dynamics AX 4.0 - only user layer)

Classes\Box is a simple class used throughout the DAX application. It provides an interface for showing a standard dialog with a number of selection options and a short message. This is very useful, especially during development, because it provides a fast way to show some kind of text information to the user.

The class contains a number of methods that can be extended with new ones (as shown below). All the methods are static and have the keyword client in the declaration, which forces the code in them to be executed on the client side.

The most commonly used methods of this class are:

  • box::info("message"); (for debugging purposes),
  • box::warning("message"); (for showing a warning message that the user won't miss)
  • box::yesNo("Message", dialogButton::Yes"). (for allowing the user to select the course of action for the underlying business logic)

All the methods mentioned above are simply creating an object of class DialogBox, which is system and doesn't allow to see its implementation. This class is therefore not covered in this tutorial.

----------------------

The rest of the methods is rarely found in the application code, and is suited for specific situations where you need to provide the user with the option of choosing from more options. (for example, when imporing a project, you see a dialog created by the method box::yesAllNoAllCancel();

The implementation of these methods is very much alike: (example mentioned above)

client static DialogButton yesAllNoAllCancel(str _text, //message
DialogButton _defaultButton, //default dialog button
str _title = "@SYS11132") //dialogTitle
{
Form form;
Args args;
Object formRun;
;
args = new Args();
args.name(formStr(SysBoxForm)); //form SysBoxForm is used to show the message
formRun = classFactory.formRunClass(args); //creating a FormRun object
formRun.init(); //calling init of the form
formRun.setTitle(_title); //setting title of the form (caption)
formRun.setText(_text); //setting message
formRun.setType(DialogBoxType::YESTOALLNOTOALLBOX); //setting the type of the form
formRun.setDefaultButton(_defaultButton); //setting the default button
formRun.run(); //calling run of the form
formRun.wait(); //waiting for user action
return formRun.dialogButton(); //returing the user selection
}

The example creates 2 objects that are needed to run a form from code:
Args args - not discusses here (used to specify the name of the form that is being created)
Object formRun - that is the actual object of the form being created.

You might have noticed that it is of type Object and not FormRun. (using the base type)
This is done on purpose, as there is no compile-time validationg of methods actually existing on the form. If the method doesn't exist, you will receive a runtime error, which is not really appropriate in a live environment. So in your code you should chech that the methods being called do actullay exist. (Global method formHasMethod can be used for this purpose)

After the form is initialized and all the setMethods() are called, the Run() method is called. This method executes the form and shows it on the screen.
After the Run Method we see a call to formRun.wait(); This method notifies the RunTime that the code execution should stop here and wait until the form is closed. (if this method is used on a form to call a child form, the parent form cannot be closed before the child form)
[Note: The alternative method here is the detach method (behavior of MenuItem calls)]

After the user closes the form, the dialogButton method on the form is called to return the selected value. [Note: Notice, that the methods on the form are still accessible, even though the form is already closed by the user. This happens because the formRun object is not yet destroyed]

-----------------
I added another method to the box class - yesNoWaitForm. It opens a form that looks kinda cooler than the standard forms, because it has the option of autoclosing after a set period of time. Well, everyone can find his own uses for this form. The form name is Dev_SysBoxForm and it is an almost complete duplicate of the system SysBoxForm form. The only big difference is that this form is set modal, and that the text of the default button is appended with the remaining amount of time before the form is autoclosed. [Note: SetTimeOut method is used, which is not covered in this tutorial]

There were differences in implementation (compared to the sytem form SysBoxForm). The main are listed below:
  • DAX 4.0 already has a modal window option (wait(TRUE)); So custom methos are removed from the form
  • DAX 4.0 has the minimize and maximize system buttons visible on the dialog form, and they had to be turned of on the form design.
  • In DAX 4.0 The return value of method formRunObj.dialogButton() was not automatically converted to the correct type. So an extra variable way added to the method to convert the result to a specific type of DialogButton. [Note: I think that this is a bug]
  • The font size of the html (message) was increased by 1, because the default font size seems too small to read.

The project also includes a job that contains a couple of examples of using the new method. Enjoy!