0% found this document useful (0 votes)
37 views40 pages

Chapter 4: Forms: Objectives

Uploaded by

Romeo Dibakoane
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
37 views40 pages

Chapter 4: Forms: Objectives

Uploaded by

Romeo Dibakoane
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 40

Chapter 4: Forms

CHAPTER 4: FORMS
Objectives
The objectives are:

• Identify the main sections that make up a form.


• Add data sources to a form to define what data is displayed by the
form.
• Add controls to a form to display data.
• Modify form methods to the control how the form behaves when it
opens and closes.
• Make decisions about where to place the code.
• Make runtime modification of the fetch of data.

Introduction
This lesson provides a comprehensive foundation for using forms to interact with
the end-user.

The following topics will be discussed:

• Forms architecture
• Fetch of data
• Code placement in forms
• Advanced controls
• Special forms

4-1
Development III in Microsoft Dynamics® AX 2012

Scenario
Isaac, the systems developer, is required to create a new form that has multiple
data sources linked together, fields that are calculated from other fields, fields
that are not linked to a data source, and to initialize the fields on the form when
the form opens. He has also been asked to investigate other types of forms and
form controls.

Architecture
A form supports the interaction between the user and the database. It focuses on
the following actions.

• Displaying and receiving data


• Filtering data
• Sorting data
• Modifying data

The application and business logic are not integrated in forms but programmed
on the underlying tables and classes.

The following figure illustrates the structure of a form as displayed in the AOT.

FIGURE 4.1 THE SECTIONS OF A FORM

A form consists of five components in the AOT:

• Methods
• Data sources
• Parts
• Designs
• Permissions

All of these components have been described in previous Microsoft Dynamics


AX 2012 development courses. This course goes in to more detail about the three
main sections - Methods, Data sources and Design.

4-2
Chapter 4: Forms

Methods
System generated methods, also known as system methods, standard methods or
object methods, attached to the form are used to control the startup and shut
down of the form. These events are frequently overridden to make initialization
of the form. By default, the system methods are not displayed. To override a
system method, right-click on the Methods node, select Override Method and
then select the methods to override.

Other methods can be added and called from anywhere in the form. It is good
practice to add methods here rather than writing large chunks of code in the
objects deeper in the form design, as it makes locating code simpler.

Variables defined in the class declaration of the individual form can be accessed
from all methods in the form and can be used to hold the status of the form
controls.

The following illustration shows the CustTable form methods. The form system
methods task, run, init and close have been overridden. All other methods have
been added to the Methods node and are specific to this form.

FIGURE 4.2 CUSTTABLE FORM METHODS

Data Sources
Data source(s) define the interface between the form and the database. An entry
is added for each table. The properties of the individual data sources determine
the relationship between the data sources. Each data source also has system
methods that can be overridden to control the display of data or act on an event.

4-3
Development III in Microsoft Dynamics® AX 2012

The data source contains all fields in the table. Again, all fields have properties
and system methods that can be overridden. These methods control the following
functions.

• Field specific navigation (filter, lookup, jump to main table and


more)
• Validating the field
• Modifying the field

Use the list of fields as a source for drag-and-drop operation when you build the
design of the form. You cannot drag fields directly from the underlying table as
the form must know which data source the field is linked to.

Field groups display below the list of fields. They can also be used as the source
for drag-and-drop operation.

Notice that after accessing the form in the AOT the definition of the data source
is cached locally in the definition of the form. If changes are made when you
create a new field in the underlying table, you must restore the form to access the
new field in the form. Remember to save the form before clicking Restore from
the shortcut menu.

The following illustration shows the data source on the CustTable form.

FIGURE 4.3 DATASOURCES ON CUSTTABLE FORM

Design
The design of the form defines the interface between the form and the user and
controls the layout and presentation of the data. The design consists of
components called controls. Some controls are used to edit and display data,
while others are used to control the layout of the form.

4-4
Chapter 4: Forms

The following illustrates the normal design of a form:

Design
Tab
TabPage
Grid
Fields to be displayed on Grid
TabPage
Field Groups
Fields in Field Group

All controls on the design have properties and methods that can be overridden.

Under the Designs node, as well as the Design node, there is also a DesignsList
node. Design is the hierarchy of controls built from the DesignList using the
HierarchyParent and ElementPosition properties. DesignList is the flat list of all
controls that populate metadata store.

Handles to the Objects in a Form


When programming in a form you can reference the individual objects, for
example the data sources or controls of the form, using the kernel classes used to
build them, or by overriding the methods on the object itself.

All methods in the form are related to an object. The object can be accessed from
the methods associated with it, by using the handle this. Note that this reference
is relative to where you are programming.

When referencing an object from a method that is not associated with that object,
you need to use the object handle. The following table lists the objects and how
to access them:

Object Access from X++


FormRun Element
FormDataSource <name of data source>_DS
Active record in data <name of data source>
source
FormDataObject FormDataSource.Object(<fieldId>)
FormDesign FormRun.design()
Form……Control Name assigned to control, when property
AutoDeclaration is set to Yes.
or
element.control(Control::<name of control>)

4-5
Development III in Microsoft Dynamics® AX 2012

Object Access from X++


Query <name of data source>_Q
or
FormDataSource.Query()
QueryRun <name of data source>_QR
or
FormDataSource.QueryRun()

The method control() on the element object can be used if the control is included
in an auto field group. In this situation you cannot use the auto declaration
feature.

Data Sources
Adding a data source to a form allows the form to display the data from the table
specified on the data source. A table in a data source can be sorted and filtered by
the user, which is an important feature of Microsoft Dynamics® AX.

Forms can contain any number of data sources, and each data source can be
joined to another data source on the form using the defined relations between the
tables. Relations or Dynalinks can also be added in the form code.

A form data source produces a query that can be manipulated the same as any
other query in the system.

Joins
To display records from two tables on one form, you can limit the records in one
of the tables to the related records in the other table. You can do this by
specifying a join between the two tables.

The join is specified on the JoinSource property of the second or joined table.
Enter the data source name of the main data source here.

You can also specify the type of join or link. The types of link are described later
in the course.

4-6
Chapter 4: Forms

An example of a form that uses join is the form CustInvoiceJour. The


CustInvoiceTrans data source is joined to the CustInvoiceJour datasource, and
the InventDim data source is joined to the CustInvoiceTrans datasource. The
following figure shows the queries in the form and the properties of the
InventDim datasource.

FIGURE 4.4 CUSTINVOICEJOUR FORM DATASOURCE JOINS

The InventDim join to CustInvoiceTrans uses an InnerJoin because the data is


to be displayed in the same grid as the CustInvoiceTrans record.

Reference Data Sources


Reference data sources are data sources that are joined to the parent data source
through a surrogate key relation - the RecId relation.

4-7
Development III in Microsoft Dynamics® AX 2012

By adding the surrogate key field from the data source to the form design, the
Reference data source is automatically created, and the AutoIdentifcation field
group on the reference data source table is used instead of the surrogate key.

FIGURE 4.5 REFERENCE DATA SOURCE ON PURCHTABLE FORM

Modification from X++


Use the query object to modify the query of a form data source. The query object
can be retrieved using either <name of data source>_Q or
FormDataSource.Query()

To make a permanent modification of the query, this is typically implemented in


FormDataSource.Init() after the call to super().

To filter records in a form perform the following steps.

1. In the ClassDeclaration, declare the relevant QueryBuildRange or


QueryFilter objects.
2. In FormDataSource.Init, initialize the range object.
3. In FormDataSource.ExecuteQuery, assign the actual values to the
ranges before call of super().

Manipulate the sorting of data by adding sortfields or an index to the data source
of the query. As an alternative, specify an index in the properties of the data
source.

4-8
Chapter 4: Forms

Combine the sorting with some aggregated fields, which makes the data source
display aggregate information from the table instead of transactions. Perform the
following steps to show the sum of quantity of inventory transactions shown per
Item Id:

1. Group the data by item id using the addGroupByField on the


datasource.
2. Add Sum(Qty) as a SelectionField

Common Methods to Override


FormDataSource.Init

This method initializes the data source and is called from the super() of
FormRun.Init(). The method is only called once when the form opens.

The main task for this method is to initialize the query used for fetching data.

To modify or replace the query automatically created by the form, do this after
the super() call of this method.

FormDataSource.InitValue

This method is used to initialize a new record with default values. The super() of
this method calls the initValue() method on the underlying table.

If you have initialization that applies system-wide, put the code on the table.

FormDataSource.Active

This event is called when a new record becomes active in the data source. This
method is typically overridden to change properties which depend on the
contents of the current record: Commonly this method will:

• Modify permissions to the data source


• Modify permissions to the fields
• Enable/Disable buttons

FormDataSource.LinkActive

This method is the engine that joins data sources. This method is called on the
joined data source every time that the active record in the main data source is
changed. The method is also called when the form is opened as the system tries
to join the calling data source to the main data source of the called form.

4-9
Development III in Microsoft Dynamics® AX 2012

FormDataSource.ValidateWrite

This method validates an insert or update of a record.The super() of this method


calls the corresponding method on the underlying table.

If you need to distinguish between an insert and update, make a condition on the
RecId field, which only has a value if it is an update.

FormDataSource.Write

This method controls the insert and update of records. The super() of this method
calls the corresponding method on the underlying table.

If you have form-specific tasks to perform in relation to the commitment of the


record, add it here.

Example of Modifying a Data Source Query


The following code illustrates the necessary modifications on a form that
contains one data source related to the table InventTrans:

public void init()


{
QueryBuildDataSource dataSource;

super();

dataSource =
this.query().dataSourceTable(tableNum(InventTrans));
dataSource.addGroupByField(fieldNum(InventTrans,
ItemId));
dataSource.addSelectionField(fieldNum(InventTrans,
Qty), SelectionField::Sum);
}

4-10
Chapter 4: Forms

List of Datasource Properties


The following list describes each property available on a form data source. The
list can also be found in the Developer Help.

Property Description
Name The Name of the data source is used when referencing the
data source from code and also when setting the data source
for a control in the design.
Table Sets the table used in the data source
Index Use this property to specify the sorting of the data. It affects
the query that is created automatically.
When no index hints are specified, the database
management system locates an applicable access path. It is
based on the information in the supplied query.
The sort order for a form can be changed by a user by using
the query dialog.
CounterField Use this property to specify a real field in the table that is
used to save the sequence of the records. This option is used
to let the user control the sequence of data. This field is
usually called LineNum.
AllowCheck Specifies whether security checking occurs early, before the
form opens.
Yes – Before the form opens, check that the user has access
to the form. A message is displayed if the form cannot open.
Yes is the default, and is generally recommended.
No – After the form opens, check whether the user has
access to the form. If the user lacks access to the form, or to
the underlying data sources, the form does not display any
data.
AllowEdit, These properties are used to reduce the access to data. You
AllowCreate, can only reduce the rights of the current user in relation to
AllowDelete the general security system.
Note that the AllowEdit also affects edit methods. You can
also set this property individually on fields.
StartPosition This option specifies if the form sets the first or the last
record active, when the form is opened. Only change this
property when you have to as the user pays a performance
penalty by finding the last record.

4-11
Development III in Microsoft Dynamics® AX 2012

Property Description
AutoSearch, The properties specify whether the form:
AutoNotify, • Automatically creates a query (AutoQuery)
AutoQuery
• Performs the initial search (AutoSearch)
• Notifies the system when the active record is changed
(AutoNotify)
This last option is necessary if other data sources are linked
to this data source.
Cross Specifies whether the data source retrieves data from more
Company than one company database. To specify which companies to
AutoQuery search, the query.addCompanyRange(<company id>)
method should be called before the query is executed.
OnlyFetch This option can be used to include a field list that only
Active contains the fields displayed.
NOTE: Be careful with this option if the data could be
changed or used as parameter to method calls. Normally
this option is only used in lookup form and for tables that
contains large fields like containers.
JoinSource Use the LinkType to select whether the data source is
joined to another data source. The joining of data is a
mechanism which automatically limits the data in one data
source to the data displayed in another data source (the
controlling data source). This requires a relation between the
two tables.
An example is the SalesTable form that contains both Sales
orders and lines. When a new sales order is selected the data
source with the lines only shows the lines related to that
sales order.

4-12
Chapter 4: Forms

Property Description
LinkType The LinkType property determines how two data sources
are joined. The following list describes each option:
• Passive: The query on the joined data source is only
executed when the form is opened. A later change in the
controlling data source does not change the view.

• Delayed: The query on the joined data source is


executed every time that the controlling data source is
changed. The query execution is delayed to avoid the
fetch of data, if the controlling data source is changed
multiple times in a short time. This is the case when the
user is scrolling through data on a grid.

• Active: This option is similar to Delayed, except there is


no delay before the query is executed.

• InnerJoin: Selects records from the main table that have


matching records in the joined table and vice versa. If
the joined table does not have any records related to the
main table record, the main table record is not
displayed. Each match returns a result set of the main
table record and joined table record joined together as
one record. This is useful when wanting to display
records from both tables in a grid.

• OuterJoin: Selects records from the main table whether


they have matching records in the joined table. Each
match returns a result set of the main table record and
joined table record joined together as one record. If
there is no match, the fields from the joined table will be
empty.

• ExistsJoin: Selects a record from the main table only if


there is a matching record in the joined table. As soon as
a matching record is found, the main table record is
returned. The record in the joined table is never
retrieved.

• NotExistsJoin: Select records from the main table that


do not have a match in the joined table.
HINT: Use the form tutorial tutorial_Form_Join to see the
different results produced when you change the LinkType
property.

4-13
Development III in Microsoft Dynamics® AX 2012

Property Description
DelayActive This enables you to delay the execution of the data source
active method. If this property is set to Yes, the active
method is activated only after a delay of 20 milliseconds.
When a user scrolls through a data source, the active method
is not called on every record, but only on the final record
that the user selects
InsertAtEnd, These properties are used to specify whether the form
InsertIf automatically creates a new record in the following
Empty situations:
• If the user browses past the last record in the data source
(InsertAtEnd)
• If the forms do not find any data (InsertIfEmpty)
The new record is saved in the database only if the user
changes any of the fields manually. The automatic creation
of a new record in the two situations is similar to the event
related to CTRL+N.
Optional Specifies the create and delete behavior for records on an
RecordMode outer joined table.
This can be set to one of the following options:
• ImplicitCreate – When no record is saved in the
database, create an outer joined record and joined tables
as soon as the parent record becomes active. If the outer
joined record or its children are not changed, they will
be deleted when the parent record is no longer active.
• ExplicitCreate – When no record is saved in the
database, treat this record as disabled until the user
explicitly triggers creation with the Optional Record
checkbox. When the record exists, unchecking the
checkbox will delete the record.
• None – No special create or delete happens with an
outer joined record.
ValidTime Specifies the types of queries for date effectivity. (AsOfDate
StateAuto and DateRange)
Query
ValidTime Specifies the types of updates for date effectivity.
StateUpdate

4-14
Chapter 4: Forms

List of Datasource Field Properties


The following list describes each property available on each field on a form data
source. The list can also be found in the Developer Help.

Property Description
AllowEdit This property specifies whether the field can be changed. It
cannot remove a restriction imposed by the table field,
security settings, or the data source.
Enabled This property specifies whether the user can access the
control. If the field is disabled it is dimmed and the user
cannot give focus to the control.
Skip Skip removes the control from the sequence that is used by
pressing TAB in the form.
Visible This property can be used to remove a field from the user
interface. The same property exists on the database field
which should be used if the option applies across the entire
system.
AllowAdd This property specifies whether the field can be added to the
design by the user. There are three options:
• No: The user cannot add this field
• Restricted: The user can add this field and edit it if a
copy of the field already exists in the form and it can be
edited. For example, if a user wants to move a copy of a
field into a grid on the first tab page and the field already
exists on another tab page within the form. This is the
default value.
• Yes: This field can be added freely.
Mandatory This option determines whether it is required to fill in data in
this field. The same property exists on the database field
which should be used if the option applies across the entire
system.

4-15
Development III in Microsoft Dynamics® AX 2012

Lab 4.1: Create a form


Scenario

You have been asked to create a new form to show a list of customer invoices
that have been posted within the last month.

The list needs to have the following fields: Customer Account, Customer Name,
Customer Default Currency, Invoice Id, Invoice Date and Invoice Amount. You
should be able to filter and sort by any of the fields in the list.

The list must include a line for every invoice that has been posted, but not show
any customers that have not been invoiced this month.

Challenge Yourself!
Create a new form that has two data sources, CustTable and CustInvoiceJour.
CustInvoiceJour should be joined to CustTable. Ensure the join displays all
invoices but not customers that have not been invoiced. Add a filter that only
retrieves records posted after the first day of the current month.

You may have to post some invoices to get some that were during this month.

Step By Step

1. Create a new form.


2. Add a data source that uses CustTable.
3. Add a data source that uses CustInvoiceJour.
4. Set the JoinSource property on the CustInvoiceJour data source to
CustTable.
5. Set the LinkType property on the CustInvoiceJour data source to
InnerJoin.
6. Add a Grid control to the Design node.
7. Drag the fields AccountNum, Currency from the CustTable data
source to the Grid control.
8. Add a StringEdit control to the grid and set the data source property
to CustTable and the DataMethod property to Name.
9. Drag the fields InvoiceId, InvoiceDate and InvoiceAmount from
the CustInvoiceJour data source to the GridControl.
10. Add the following code to the system methods on the form and the
data source. Note that the first method is the ClassDeclaration.

4-16
Chapter 4: Forms

public class FormRun extends ObjectRun


{
QueryBuildRange QBRInvoiceDate;
}

// this is the init method on the CustInvoiceJour data


source

public void init()


{
super();

QBRInvoiceDate =
this.query().dataSourceTable(tableNum(CustInvoiceJour)).add
Range(fieldNum(CustInvoiceJour, InvoiceDate));

// this is the executeQuery method on the CustTable


dataSource.

public void executeQuery()


{
fromDate fromDate =
mkDate(1,mthofyr(systemDateGet()), year(systemDateGet())) ;

QBRInvoiceDate.value(sysQuery::range(fromDate,
systemDateGet()));

super();
}

4-17
Development III in Microsoft Dynamics® AX 2012

Form Controls
Form controls refers to all of the objects in a form design. Tabs, tab pages, field
groups, grids, fields and buttons are all examples of form controls. Controls are
arranged on the form using Intellimorph technology.

All data is displayed through field controls. As with fields on a table, each field is
a specific data type, and can also be an Extended Data Type. There are three
types of field controls: Bound, Unbound and Calculated.

Bound controls are associated with a field in an underlying table. Use bound
controls to display, enter, and update values from fields in the database.

Unbound controls do not have a data source, but can be a specific Extended Data
Types.

Calculated controls use a method as the data source. An example of a calculated


control is the sum of two fields on a form.

IntelliMorph
IntelliMorph is a technology that simplifies the modification of forms. For
example, IntelliMorph lets users hide and show fields. Individual users can safely
and swiftly rearrange fields to best suit their work preferences without modifying
the form through the AOT (Application Object Tree). IntelliMorph also makes it
possible to quickly redesign forms. Field labels can be modified without
disturbing field data or underlying business logic.

When the form is displayed the width of the labels are adjusted to the actual
language. Fields that are not active because of configuration or security are
removed. The formatting of date, time and numbers is performed according to the
settings in the operating system.

The design of the form should be made to support IntelliMorph. This includes the
following guidelines for the properties on the controls:

• Limit the change of properties to a minimum. A property on a


control shadows a later system-wide modification at the dictionary
level.
• Do not put controls at absolute coordinates. This prevents the form
from rearranging the fields if they are added or removed.
• Use the values column width and column height for the properties
width and height to support manual resizing of the form.
• Use database field groups. This enables a later modification to the
forms at the dictionary level.

4-18
Chapter 4: Forms

Display Methods
A display method is used to display a calculation or data from another table. The
method modifier Display is added to the beginning of the method definition line
to allow the returned value to be displayed on a form (or report).

Display methods can be created either on a table or on a form data source. If it is


created on the form data source, then it takes the table as a parameter. If possible
a display method should be created on the table itself, but there are situations
where it has to be on the form data source, for example, if it uses an unbound
control on the form.

The following example is from the InventJournalTable form, and displays the
user ID of the user that is locking a journal.

//BP Deviation documented


display JournalBlockInUseUserId inUseUserId(JournalTableMap
_journalTable)
{
return
journalFormTable.datasourceMethodInUseUserId(_journalTable)
;
}

Edit Methods
Edit methods are similar to display methods in that they can return calculated
values or data from another table. They can also be edited. An edit method takes
two more parameters than a display method. The first parameter is Boolean and
is True if the user has edited the field. The last parameter is the value that has
been entered in the case that a user has edited the field. If the edit method is on a
form data source, the second parameter is the table.

The following example is from the form CustTransOpen which is used to settle
transactions against each other. This method is used to mark which transactions
are to be settled.

// BP Deviation documented
public edit NoYes editMarkTrans(boolean _set, CustTransOpen
_custTransOpen, NoYes _markTrans)
{
NoYes returnMarkTrans;
;

if (_set)
{
manager.updateTransMarked(_custTransOpen,
_markTrans);

element.updateDesignDynamic();

this.refresh();
}

4-19
Development III in Microsoft Dynamics® AX 2012

returnMarkTrans =
manager.getTransMarked(_custTransOpen);

return returnMarkTrans;
}

Unbound Controls
Unbound fields are fields of a specific type, but not attached directly to a table.
These fields inherit the properties of the data type including any relations to a
table. An unbound control can be used for filtering record to be displayed or to
display images or static text.

The following illustration shows the properties of an unbound control in which


an item ID can be entered. The lookup of the item table is still available through
the relations on the Extended Data Type.

FIGURE 4.6 AN UNBOUND CONTROL

4-20
Chapter 4: Forms

Common Methods to Override


FormDataObject.Modified

Use this method when the user changes the contents of the field. This event can
be used to make calculations or other operations which depend on the field.

For system-wide functionality during a manual change of a database field,


override the modifiedField method on the table.

FormDataObject.Validate

Use this method to validate the contents of the field. This event can be used to
supplement or remove the ordinary validation.

For system-wide functionality during the validation of a database field,


implement this by overriding the validateField method on the table.

4-21
Development III in Microsoft Dynamics® AX 2012

Lab 4.2 - Use Unbound Controls


Scenario

You have been asked to modify the form created in Lab 4.1 so that the user can
enter a date in a field on the form. The form will then display all invoices posted
after that date.

Challenge Yourself!
Add a new date control field to the form, and filter the records based on this date.

Step by Step

1. Add a new DateEdit control to the design of the form created in Lab
4.1. Rename the control to FromDate.
2. Open the properties of the FromDate control.
3. Set the ExtendedDataType property to FromDate.
4. Set AutoDeclaration to Yes.
5. Close the properties form.
6. Expand the FromDate node.
7. Right-click on the methods node and select Override Method >
Modified.
8. Modify the code as shown below.
9. Edit the ExecuteQuery() method on the CustTable data source.
10. Modify the code as follows.

public boolean modified()


{
boolean ret;

ret = super();

CustTable_ds.executeQuery();

return ret;
}

public void executeQuery()


{

QBRInvoiceDate.value(sysQuery::range(fromDate.dateValue(),
systemDateGet()));

super();
}

4-22
Chapter 4: Forms

Form Methods
Form methods control how the form opens, runs and closes. These methods can
be overridden as with other form system methods.

Common Methods to Override


FormRun.Init

This method initializes the form and its objects. This is the first event you can
override in connection with the startup of the form.

Never remove the super() call from this method, as it removes the initialization of
all the objects.

To make some manual initializations, formRun.init is typically used. This could


include the following tasks:

• Verification of the contents of the args-object received


• Initialization of supporting classes
• Dynamically changes to the design

If your manipulation needs access to the objects of the form, wait until the
super() call has executed.

FormRun.Run

The run method is called immediately after the init method. The super() call
makes the form window appear on the screen and performs a database search for
the data to be displayed in the form.

Typical reasons for overriding the formRun.run() method include, activating or


de-activating some fields, setting default values for controls or modifying the
query.

You must call super() if you override formRun.run() method, and you should
place your code before the super() call.

FormRun.Close

This method shuts down the form. If you have cleanup in connection with
finishing the execution of the form, place it here.

One function available for implementation is when saving some options for
future use as in \Forms\ForecastPurch\Methods\close.

4-23
Development III in Microsoft Dynamics® AX 2012

FormRun.ClosedOK

The formRun.closedOK() method is called when a Command Button with the


Type set to OK is clicked. The call to super() will close the form.

The formRun.ClosedOK() method is used when code is to be executed when


the user accepts the data that they have entered in the form is correct, and wants
to exit, as with many standard windows forms.

4-24
Chapter 4: Forms

Lab 4.3 - Initialize a Form


Scenario

You have been asked to default the date field added in the Lab 4.2 to the first day
of the month.

Challenge Yourself!
When the form opens, the date field should be set to the first day of the current
month. Ensure that the records are then filtered to only show invoices posted
after this date.

Step by Step

1. Right-click on the methods node of the form you created in the Lab
4.1, select Override Method > Run.
2. Add the code to this method as shown below.
3. Save the method and run the form.

public void run()


{
FromDate.dateValue(systemDateGet() -
dayofmth(systemDateGet()) + 1);
super();
}

4-25
Development III in Microsoft Dynamics® AX 2012

Placement of Code
The form offers many opportunities to place code on events. Try to minimize the
X++ code in forms for the following reasons:

• Forms do not support inheritance. You cannot share logic


implemented in a form with other application objects.
• The X++ code implemented in forms is always executed on the
client. This means that you cannot tune an application by specifying
where to execute the code.

To program system-wide logic, which is closely related to a record, put the logic
in object methods on the table. The table which inherits from the kernel class
xRecord has many events you can override and supplement with logic.

If designing logic which is more related to the function of the form, than the
individual records in the data source, consider making a class which supports the
form. If the form can work with different variations of functions or data, this
approach supports using polymorphism.

If putting the X++ code in the form, avoid programming on the design and put
your logic on the data source. Many events on the design are dependent on
exactly how the user navigates the form. Code on the form controls does not take
the possibility of the user modifying the contents of the form into account.

Additional Controls
The following introduces additional controls that can be used on forms.

Segmented Entry Control


Segmented entry controls are used to enter the main account and dimension
combinations that make up a segmented entry. To add a segmented entry control
to a form, drag the field that holds a foreign key to the
DimensionAttributeValueCombination table to the design of the form. This
creates a control of type Segment Entry. Next, override the following methods on
the form, data source and new form control.

<Form Methods>

public class FormRun extends ObjectRun


{
LedgerDimensionDefaultAccountController
ledgerDimensionDefaultAccountController;
}
public void init()
{
super();
ledgerDimensionDefaultAccountController =
LedgerDimensionDefaultAccountController::construct(myTable_

4-26
Chapter 4: Forms

ds,
fieldstr(MyTable, LedgerDimension));
}

<Form Control methods>

public void jumpRef()


{
ledgerDimensionDefaultAccountController.jumpRef();
}

public void
loadAutoCompleteData(LoadAutoCompleteDataEventArgs _e)
{
super(_e);

ledgerDimensionDefaultAccountController.loadAutoCompleteDat
a(_e);
}

public void
segmentValueChanged(SegmentValueChangedEventArgs _e)
{
super(_e);

ledgerDimensionDefaultAccountController.segmentValueChanged
(_e);
}

public void loadSegments()


{
super();
// (Optional parm*() specification should go here, see
the Control options section.)

ledgerDimensionDefaultAccountController.parmControl(this);
ledgerDimensionDefaultAccountController.loadSegments();
}

public boolean validate()


{
boolean isValid;
isValid = super();
isValid =
ledgerDimensionDefaultAccountController.validate() &&
isValid;
return isValid;
}

<Form datasource methods>

4-27
Development III in Microsoft Dynamics® AX 2012

public Common resolveReference(FormReferenceControl


_formReferenceControl)
{
return
ledgerDimensionDefaultAccountController.resolveReference();
}

ListView
The listview control is used to present the user with a list of options. Select one
or more of them. One example of using listview can be found in the selection of
payment file formats in the vendor module as shown in the following figure.

FIGURE 4.7 FILE FORMATS FORM

The forms tutorial_Form_ListControl and


tutorial_Form_ListControl_CheckBox illustrate many of the functions related
to the listview control and how they are programmed in X++.

NOTE: Examine the tutorials in Microsoft Dynamics AX. There are several
application objects in the AOT which are created to illustrate how to design and
implement special functions. All these application objects are prefixed with
'tutorial'.

4-28
Chapter 4: Forms

Table
The table control looks like a spreadsheet. The grid is predefined with fields as
columns and records as row. In the table you control which type of data (control)
and which data (value) is presented in each cell.

The table control has related controls as a grid. Decide which of these controls
should be used in each cell of the table. Use the following two options for
specifying which control to use for each cell:

• Override the method editControl() and return a handle to the


control. This method has the actual row and column as parameters.
The kernel calls this method when the information is needed.
• Call the method cell() of the table control. Specify the actual row and
column as parameters. This returns a FormTableCell object. On this
object call the method editControl with a handle to the control as a
parameter. Use this to specify all the controls in a loop construction.

The specification of data in the table is performed in a similar manner.

• Override the method data() and return the actual value of the cell.
The method is similar to the editControl().
• Obtain the formTableCell object and call the method data().

The labels of the row and columns are specified by overriding the methods
rowLabel and colLabel of the table control.

An example of a table control is the form SysDateLookup which is used to


select a value in a date field.

The forms tutorial_Form_Table illustrates many of the functions related to the


table control and how they are programmed in X++.

4-29
Development III in Microsoft Dynamics® AX 2012

Tree
The tree control is used to show hierarchical organized data as a bill of material,
projects, directory structure on a hard disc, and more.

An example from the standard application is the project table. Click Edit on the
All Projects list page.

FIGURE 4.8 TREE VIEW

The forms tutorial_Form_TreeControl illustrates many of the functions related to


the table control and shows how they are programmed in X++.

When working with tree structures with significant amount of nodes, only build
the visible part of the tree and extend the depth of the tree as the nodes are
expanded.

4-30
Chapter 4: Forms

Window
The window control can be used to display images. An example of this is the
form displaying the company logo.

FIGURE 4.9 COMPANY LOGO

To display an image in a grid, you need to add a window control to the grid and
set the method to be a method that returns the resource Id of the image.

Use the class ImageList to build a list of images that the window can display and
then set that ImageList on the control.

Most resource Ids are listed in the macros ResAppl and Resource. You can add a
new image through the Resource node in the AOT.

For an example to show an image in a grid, examine the code in the Init form
method and the errorExists method in the LedgerJournalTrans datasource in the
LedgerJouranlTransDaily form. Also look at the form
Tutorial_Form_Windowingrid.

Managed Host
Microsoft Dynamics AX supports the display of .net managed controls. Actions
taken by the user on those controls are also handled. The following procedure
shows how to add a windows calendar control to a form and handle an event that
arises from a user action.

1. In the AOT, right-click on the Forms node and select New Form.
2. Rename the new form to DateDifferenceCalculator.
3. Right-click on the Design node and select New Control >
ManagedHost. The Managed control selector form appears.
4. In the list find the System.Windows.Forms record.
5. In the Controls list, select MonthCalendar. Click OK.
6. Rename the new ManagedHost control to CalendarControl.
7. Right-click CalendarControl and select Events. The Events form is
displayed.
8. Highlight DateSelected and click Add.
9. Click Close.

4-31
Development III in Microsoft Dynamics® AX 2012

10. Open the Init method of the form. Note that code has been added to
initiate the control and also the DateSelected event handler.
11. Open the CalendarControl_DateSelected method. Add the
following code.

utcDateTime dt;

date selectedDate;

dt = e.get_Start();

selectedDate = DateTimeUtil::date(dt);

info(strFmt("Number of days until %1 is %2", selectedDate,


selectedDate - systemDateGet()));

12. Save your changes to the form.


13. Open the form and click on different dates to see the number of days
from now until that date.

ActiveX
The ActiveX control is used to host an ActiveX component. ActiveX is a
component of another program which is installed individually and can be
integrated in other applications such as Microsoft Dynamics AX or Web pages.
There are many ActiveX programs available.

4-32
Chapter 4: Forms

When you create the control, a list of ActiveX controls installed on the actual
computer displays.

FIGURE 4.10 ACTIVEX BROWSER

Select from the list or click 'Enter class ID' to identify the ActiveX with unique
class ID.

An ActiveX control has auto declaration set to Yes as default, as you have to
address the control to access the specific methods of the ActiveX. When you
write X++ the specific methods are included in the list of methods.

4-33
Development III in Microsoft Dynamics® AX 2012

ActiveX Methods
Open the ActiveX explorer from the context menu of the control. The explorer
lists all events and methods that are defined on the ActiveX.

FIGURE 4.11 ACTIVEX EXPLORER METHODS

The parameters to the methods and a help text is displayed in the window of the
explorer.

ActiveX Events
Add an event to the AOT by double-clicking the event. Afterward, you can edit
and delete the event directly from the methods-node of the control.

See the documentation of the individual ActiveX for a description of the


component.

4-34
Chapter 4: Forms

Lab 4.4 - Add a window control


Scenario

You have been asked to add a visual alert to the invoice list form if an invoice
has not yet been paid. The grid should contain a field that has a Warning icon if
the invoice has not yet been fully settled.

Challenge Yourself!
Add a window control to the grid of the form created in Labs 4.1, 4.2, and 4.3. If
the invoice has been fully paid then the window should be blank otherwise the
window should show a Red Error icon.

Step by Step

1. Expand the designs node of the form created in Labs 4.1, 4.2, and
4.3.
2. Right-click on the Grid control, select New Control > Window.
3. In the properties of the new Window Control, rename it to
WindowOpen, set the DataSource to CustInvoiceJour, and set
AutoDeclaration to Yes.
4. Modify the ClassDeclaration as shown below.
5. Modify the run method as shown below.
6. Create a new method in the CustInvoiceJour data source and add
the code as shown below.
7. In the properties on the WindowOpen control, set the dataMethod
property to invoiceIsOpen.
8. Save and run the form.

public class FormRun extends ObjectRun


{
QueryBuildRange QBRInvoiceDate;
imageListAppl imageListAppl;
}

public void run()


{
#resAppl

imageListAppl = new ImagelistAppl(


Imagelist::smallIconWidth(), Imagelist::smallIconHeight());
imageListAppl.add(#ImageError);
windowOpen.imageList(ImageListAppl.imageList());

FromDate.dateValue(systemDateGet() -
dayofmth(systemDateGet()) + 1);

4-35
Development III in Microsoft Dynamics® AX 2012

super();
}

//BP Deviation Documented


display ImageRes invoiceIsOpen(CustInvoiceJour
_CustInvoiceJour)
{
ImageRes res = -1;
#resAppl;

if (!_CustInvoiceJour.custTrans().Closed)
res = imageListAppl.image(#ImageError);

return res;
}

4-36
Chapter 4: Forms

Summary
This lesson discusses how to join data sources on a form, add controls that can
display the data from the data source as well as data from other tables and
calculations. It also discusses the methods and properties available when creating
a form and the additional options for control types and form types.

4-37
Development III in Microsoft Dynamics® AX 2012

Test Your Knowledge


Test your knowledge with the following questions.

1. Which kernel class documents the individual field in a data source and how
do you get a handle to it?

2. Which methods do you override to make changes to the structure of the


query which fetches data to the data source?

3. What are the characteristics of a table control?

4-38
Chapter 4: Forms

Quick Interaction: Lessons Learned


Take a moment and write down three key points you have learned from this
chapter

1.

2.

3.

4-39
Development III in Microsoft Dynamics® AX 2012

Solutions
Test Your Knowledge
1. Which kernel class documents the individual field in a data source and how
do you get a handle to it?

MODEL ANSWER:

The kernel class FormDataObject documents fields on a data source. You


can get a handle by using FormDataSource.Object(<fielded>)

2. Which methods do you override to make changes to the structure of the


query which fetches data to the data source?

MODEL ANSWER:

You override FormDataSource.executeQuery and FormDataSource.init().

3. What are the characteristics of a table control?

MODEL ANSWER:

The developer can select which data type the rows and columns in the table
should have and the number of columns and rows.

4-40

You might also like