Adding controls at runtime can be a powerful feature of Microsoft Dynamics AX client development. As a developer you may choose to display a control based on business logic and one way to do this can be with X++. I had a recent case where attempting this caused the Financial dimension fields to not work. I thought I would share some of the learning that took place in resolving the issue.
When adding a control to a form at runtime using X++, you have an option of using the controlMethodOverload method. This method allows the developer to provide additional code to overload the methods on the form. However when this is added to a form with Financial dimension fields, your control may work but the Financial dimension fields become unavailable. You cannot click or do anything with them. Using controlMethodOverload is not documented from Microsoft very much but there are numerous articles externally on trying to use it. In some of the examples I have seen it works well.
X++ Example of adding a Button Control at Runtime
I will add a button named DynamicButtonControl to the BankAccountTable form to illustrate the behavior as this form has Financial dimension fields. A new method called addButtonAtRuntime and DynamicButtonControl_Clicked will be created like below:
private void addButtonAtRuntime()
{
FormButtonControl formButtonControl;
formButtonControl = this.design().addControl(FormControlType::Button, "DynamicButtonControl");
formButtonControl.text("Dynamic FormButtonControl button");
this.controlMethodOverload(true);
}
void DynamicButtonControl_Clicked(FormButtonControl _formButtonControl)
{
;
info ("Dynamic button clicked!");
}
Then add the below to the existing init method of the BankAccountTable form:
element.addButtonAtRuntime();
Now you can test the BankAccountTable form and the button should show up in the bottom of the form. You can click this new button and the Infolog window will open. However the Financial dimension fields will not work when clicked on.
The resolution is to use the registerOverrideMethod method to override the specific control we added. This method is available on Form controls. You may not find much detailed documentation from Microsoft on it, but it can be used like this:
formButtonControl.registerOverrideMethod(methodStr(FormButtonControl, clicked),'DynamicButtonControl_Clicked',this);
In the above we know the name of the button control we added was DynamicButtonControl. To override the button clicked event we use the above syntax with the registerOverrideMethod method. Now all the form controls like the Financial dimension fields and the custom button control added at runtime will work correctly. When you add Form controls at runtime, you will probably want to use the registerOverrideMethod method over the controlMethodOverload method.