Axapta AX2009-检查表单是否为调用方

Axapta AX2009-检查表单是否为调用方,axapta,microsoft-dynamics,dynamics-ax-2009,Axapta,Microsoft Dynamics,Dynamics Ax 2009,如果表单被用作当前打开的另一个表单的调用者,是否有方法签入表单中的代码?据我所知,开箱即用的方法无法进行检查。如果您有一小部分特定表单(例如一个调用方表单和2或3个被调用表单),那么通过管理调用方表单中被调用表单的列表应该非常容易 如果您想要一个适用于所有表单的通用解决方案,那么事情就会变得有趣。您可能希望查看SysSetupForm[Run]和SysForm[Run]类,并尝试使用类似的表单管理逻辑来扩展这些类。可能需要将被调用表单管理的数据存储在全局缓存中 也就是说,我建议你重新考虑你的表单

如果表单被用作当前打开的另一个表单的调用者,是否有方法签入表单中的代码?

据我所知,开箱即用的方法无法进行检查。如果您有一小部分特定表单(例如一个调用方表单和2或3个被调用表单),那么通过管理调用方表单中被调用表单的列表应该非常容易

如果您想要一个适用于所有表单的通用解决方案,那么事情就会变得有趣。您可能希望查看
SysSetupForm[Run]
SysForm[Run]
类,并尝试使用类似的表单管理逻辑来扩展这些类。可能需要将被调用表单管理的数据存储在全局缓存中

也就是说,我建议你重新考虑你的表单设计。通常这样的需求是由于糟糕的设计造成的。

是的,有

对于AX 2009,您的代码应该如下所示:

Object caller = element.args().caller();

if (SysDictClass::isEqualOrSuperclass(classIdGet(caller), classNum(FormRun)))
{
    // ...
}
对于AX 2012,类似于此:

Object caller = element.args().caller();

if (caller is FormRun)
{
   // ...
}
但是请注意,只有通过菜单项调用表单时,才会在此时设置caller()。如果直接调用方法,则必须在Args对象中手动设置caller()

如果您想在调用者窗体上调用方法,我在过去的博客中已经提到了这一点:


这只是一个想法,我还没有尝试过,但我不明白为什么它不起作用。我没有优化代码,所以把这个想法作为一个灵感

首先,在从主窗体调用的每个窗体中修改
init
方法,如下所示:

public void init()
{
    super();

    blahblah::addHandleToCache(element.hWnd());
}
这是blahblah::addHandleToCache的代码:

public static client void addHandleToCache(int _handle)
{
    #define.CACHE_OWNER('MyCallerForm')
    container con;
    int hWnd;
    int i;

    //get a container with open window handles from the cache
    if (infolog.globalCache().isSet(#CACHE_OWNER, curUserId()))
    {
        con = infolog.globalCache().get(#CACHE_OWNER, curUserId());
    }

    //remove handles of closed windows from the container
    for (i = conLen(con); i >= 1; i--)
    {
        hWnd = conPeek(con, i);

        if (!WinApi::isWindow(hWnd))
        {
            conDel(con, i, 1);
        }
    }

    //add the current window handle to the container
    con += _handle;

    //save the container in the cache
    infolog.globalCache().set(#CACHE_OWNER, curUserId(), con);
}
现在,如果要检查主窗体是否用作其他打开窗体的调用者,可以使用以下检查:

public boolean hasOpenChildForms()
{
    #define.CACHE_OWNER('MyCallerForm')
    container con;
    int hWnd;
    boolean ret;

    //get a container with open window handles from the cache
    if (infolog.globalCache().isSet(#CACHE_OWNER, curUserId()))
    {
        con = infolog.globalCache().get(#CACHE_OWNER, curUserId());
    }

    for (i = conLen(con); i >= 1; i--)
    {
        hWnd = conPeek(con, i);

        if (WinApi::isWindow(hWnd))
        {
            //the form is open
            ret = true
        }
        else
        {
            //remove handles of closed windows from the container
            conDel(con, i, 1);
        }
    }

    return ret;
}

也许我没有正确理解这个问题,但我想@user3660338想知道一个表单是否调用了任何表单。您的代码将帮助他检查表单是否已被表单调用。