A blog offering various X++ code snippets and tips for Microsoft Dynamics AX

Saturday, July 26, 2008

Creating a Form at Run Time

Welcome to another AX development lesson.

In this lesson I shall discuss how we can create a form at run time and add it to the AOT.

Here, we have to use various AX classes which are found under the System Documentation node in the AOT.

The class FormBuild is the base canvas on which we start building our form and on which our form level method have to be added. Therefore, we assign a new Form object (which resembles our form node in the AOT) and assign it to the FormBuild's form.

However, just like in standard AOT form design, we cannot add controls directly to the FormBuild but we need a FormBuildDesign class on which we will continue adding the rest of the controls.

We also need to add DataSources (if required) to the form object. Remember the form object is representing one form's route node in the AOT and your code has to rsemble the tree structure in the AOT i.e.

Form -> Methods
-> DataSources
-> Design -> Controls

The following job should make things clearer:


static void createFormAtRunTime(Args _args)
{
  TreeNode formlist;
  Form formNode;
  FormBuild formBuild = new FormBuild('MyRunTimeForm');
  FormBuildDesign formDesign;
  FormBuildTabControl formTab;
  FormBuildTabPageControl formTabPage;
  FormBuildDataSource formDatasource;
  FormBuildGridControl formGrid;
  XPPCompiler compiler;
  str dataSourceName;
  int dataSourceId;
  str sourceCode, methodName;
  ;
  methodName = 'runTimeMethod';
  sourceCode = @'
        void runTimeMethod()
        {
          ;
          info("hello");
        }';
  compiler = new XppCompiler();

  if (sourceCode && compiler.compile(sourceCode))
  {
    // Assign to formBuild's base 'canvas' to a form object
    // This resembles the top node of a form in th AOT
    // To this form object (form node) we add designs and datasources
    formNode = formBuild.form();
    formNode.AOTfirstChild();

    // Add ClassDeclaration
    formBuild.addMethod('classDeclaration', 'class FormRun extends ObjectRun     \n{}\n');

    // Add our previously built method
    formBuild.addMethod(methodName, sourceCode);

    // Add a new form Design
    formDesign = formNode.design();
    formDesign.columns(1);
    formDesign.leftMode(0);
    formDesign.topMode(0);

    // Add a new tab - header
    formTab = formDesign.addControl(FormControlType::Tab, 'Header');
    formTab.columns(1);
    formTab.autoDeclaration(true);
    formTab.widthMode(1); //column Width

    // Add a new tab page - overview
    formTabPage = formTab.addControl(FormControlType::TabPage, 'Overview');
    formTabPage.caption('Overview');
    formTabPage.widthMode(1); //column Width
    formTabPage.heightMode(1); //column Height

    formlist = infolog.findNode('Forms');
    formlist.AOTadd('MyRunTimeForm');

    // Add a DataSource - SalesTable
    formDatasource = formNode.addDataSource(tablestr(SalesTable));
    dataSourceName = formDatasource.name();
    dataSourceId = formDatasource.id();

    // Add a Grid
    formGrid = formTabPage.addControl(FormControlType::Grid,tablestr     (SalesTable)+'Grid');
    formGrid.heightMode(FormHeight::ColumnHeight);
    formGrid.widthMode(FormWidth::ColumnWidth);

    // Add fields to the Grid
    formGrid.addDataField(dataSourceId, fieldNum(SalesTable, SalesId));
    formGrid.addDataField(dataSourceId, fieldNum(SalesTable, CustAccount));

    // Commit changes - same like pressing Save button in the AOT
    formNode.save();
    formNode = formList.AOTfindChild('MyRunTimeForm');
    formNode.AOTrestore();
  }
}


If we did not have AX's Morphx/AOT features we would have to write all that code just to create a simple form like the one generated if you run the above code and open the form it generates and adds to the AOT.

That's all for this lesson!

See you next time!

If you any questions or comments e-mail me on: mirko@mirkobonello.com

No comments: