AX2009在init上循环遍历表单中的所有控件

时间:2014-05-21 15:11:15

标签: dynamic axapta dynamics-ax-2009

在初始化表单时,如何循环遍历表单中的所有控件?

我在init和run方法中尝试了以下方法,但它不起作用:

for( i = 1 ; i <= element.form().design().controlCount() ; i++ )
{
    control = element.form().design().controlNum(i);

    switch ( control.handle() )
    {
        case classnum(FormBuildButtonControl):
            element.initButton(control);
        break;
        case classnum(FormBuildStaticTextControl):
            element.initStaticText(control);
        break;
    }
}

有没有办法做到这一点?

3 个答案:

答案 0 :(得分:4)

您所使用的代码,但它只遍历设计的顶层。您需要构建一个递归函数来遍历整个控件集,并将它放在init方法之前 super():

void init()
{
    int     i;
    void    processControls(FormBuildControl fbc)
    {
        int     j;
        ;

        if (fbc.isContainer())
        {
            for (j = 1; j < fbc.controlCount(); j++)
            {
                //Process container, if you need to
                processControls(fbc.controlNum(j)); 
            }
        }
        else
        {
            //Control is not a container, process it here.                
        }
    }
    ;

    for (i = 1; i <= element.form().design().controlCount(); i++)
    {
        processControls(element.form().design().controlNum(i);
    }

    super();
}

super()调用将自动初始化表单上的所有控件。初始化后,您将无法使用FormBuildControl类型对象来配置字段,因为它们已经被用于表单上。如果你需要在初始化后修改字段,你应该直接引用该字段(虽然我不知道你如何获得字段名称并通过X ++引用它。)

不是有条件地初始化控件,而是调用super()并简单地隐藏字段,或者使用安全性来隐藏您不希望某些人访问的信息。

修改 由于您正在处理预先初始化设计的FormBuildControl,因此在初始processControls调用之后应该进行super()调用。我已经改变了我的例子以反映这一点。

答案 1 :(得分:3)

每个控件都可以有子控件和父控件。你只是超越了第一级。下面是一个示例作业,演示如何在表单控件上使用递归。

static void recurseOverAllFormControls(Args _args)
{
    Form form = new Form(formstr(SalesTable));

    void recurse(Object _parent, int _depth = 1)
    {
        int     i;
        str     name;
        str     caption;
        str     dashes;
        ;

        // Used for making it pretty
        //-->
        i = _depth;
        while (i)
        {
            dashes += '-';
            i--;
        }
        //<--

        // Used for example of how to use data
        //-->
        if (SysTest::hasMethod(_parent, identifierStr(caption)))
            caption = _parent.caption();

        if (SysTest::hasMethod(_parent, identifierStr(name)))
            name = _parent.name();

        info(strfmt("%1%2[%3](%4)", _depth, dashes, name, caption));
        //<--

        // Escape condition!
        if (_parent.controlCount() == 0)
            return;

        // Recursive statement
        for (i=1; i<=_parent.controlCount(); i++)
            recurse(_parent.controlNum(i), _depth+1);
    }
    ;

    recurse(form.design());
}

编辑:有人打我的答案。希望有人会欣赏我的演示工作。

答案 2 :(得分:0)

我已经用x ++(以及d365)编写了一个简单的代码,但它可能对某人有所帮助。在此代码中,所有表单控件都将保存在名为FormControlsTable的表中。

    public void init()
    {
        super();
        FormControlsTable   _formControlTable;
        int                             i;
        FormBuildControl                _control;

        select count(RecId) from _formControlTable;

        if(_formControlTable.RecId == 0)
        {
            for( i = 1 ; i<= element.form().design().controlCount(); i++)
            {
                 _control = element.form().design().controlNum(i);
                 ttsbegin;
                 _formControlTable.ControlId        =   _control.id();
                 _formControlTable.ControlName      =   _control.name();
                 _formControlTable.insert();
                 ttscommit;
                this.TraverseFormControl(_control);
            }
        }
    }

    private void TraverseFormControl(FormBuildControl _control)
    {
        int i;
        FormControlsTable               _formControlTable;
        FormBuildControl                _childControl;

        for( i = 1 ; i<= _control.controlCount(); i++)
        {
            _childControl   =   _control.controlNum(i);
            if(_childControl != null)
            {
                ttsbegin;
                _formControlTable.ControlId     =   _childControl.id();
                _formControlTable.ControlName   =   _childControl.name();
                _formControlTable.insert();
                ttscommit;
                this.TraverseFormControl(_childControl);
            }
        }
    }