There's more...

The form is based on the FormRun class. We can see this by opening (double-click) classDeclaration for the CustGroup form:

public class ConWHSVehicleParameters extends FormRun 
This differs from AX 2012, where the declaration was public class FormRun extends ObjectRun, which was probably a little more honest, as the form is not a type; this is why it can have the same name as a table.

This is actually a definition file that FormRun instantiates with in order to build and execute the form.

Once the system has built the form design using SysSetupFormRun, it will perform the initialization tasks and run the form. The key methods in this are Init and Run. These can be overridden on the form in order to perform additional initialization tasks.

One of FormRunInit method's key tasks is to construct the form's data sources; these aren't table references but FormDataSource objects constructed from the tables listed under the Data Sources node.

In the case of the ConWHSVehicleParameters form, the system creates the following objects from the ConWHSVehicleParameters data source for us:

  • ConWHSVehicleParameters as type ConWHSVehicleParameters(table)
  • ConWHSVehicleParameters_DS as type FormDataSource
  • ConWHSVehicleParameters_Q as type Query
  • ConWHSVehicleParameters_QR as type QueryRun

We aren't normally concerned with the Query and QueryRun objects as we can access them through the FormDataSource object anyway.

The data sources are declared as global variables to the form and provide a layer of functionality between the form and the table. This allows us to control the interaction between the bound form controls and the table.

Let's override the init method on the data source, and then override the modifiedField event on a field; the code editor will present the change as follows:

[Form] 
public class ConWHSVehicleParameters extends FormRun
{
public void init()
{
ConWHSVehicleParameters::Find();
super();
}

[DataSource]
class ConWHSVehicleParameters
{
public void init()
{
super();
}
[DataField]
class DefaultVehicleGroupId
{
public void modified()
{
super();
}
}
}
}

It adds the data source as a class within the form's class declaration, and then adds the field as a class within the data source class. This is the only place in Operations where this occurs. If the data source class were a class, it would have to extend FormDataSource. The Form, DataSource, and DataField attributes are a clue as to what's going on here. As all executable code compiles to CLR types, the compiler uses these attributes in order to create the actual types. The structure is written as such for our convenience as a presentation of code.

Let's take the modifiedField method. This is an event that occurs after the validateField event returns true. The call to super() calls the table's modifiedField method. We may wonder why the call to super() has no parameter. This happens behind the scenes, and it is useful that this is handled for us.

This pattern is followed for the following methods:

DataSource method

Calls table method

validateWrite

validateWrite

write

write (in turn, insert or update)

initValue

initValue

validateDelete

validateDelete

delete

delete

DataField.validateField

validateField(FieldId)

DataField.modifiedField

modifedField(FieldId)

The table's initValue, validateField, modifiedField, validateWrite, and validateDelete methods are only called from form events; the write method does not call validateWrite.

From this, we have a choice as to where we place our code, and this decision is very important. The rule to follow here is to make changes as high as possible: table, data source, and form control.

It is critically important that code on a form must only be written to control the user interface and should not contain validation or business logic.

We can go further with this and write form interaction classes that allow user interface control logic to be shared across forms; for instance, controlling which buttons are available to a list page and the associated detail form.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.70.79