Показать сообщение отдельно
Старый 09.02.2012, 19:27   #11  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Доработка метода Dialog.customFieldName_RU()
Цитата:
Сообщение от ziva Посмотреть сообщение
Добавляем в classDeclaration следующую конструкцию:
X++:
#define.dialogCustAccount('dialogCustAccount')
Здесь мы вынуждены иметь hardcoded название будущего контрола на форме.
2. В метод dialog() добавляем вызов ещё пары методов:
X++:
// здесь насильно устанавливаем название создаваемого контрола в форме диалога
dialog.customFieldName_RU(#dialogCustAccount);
// ...
3. Теперь создаём метод dialogCustAccount_modified(), который позволяет отлавливать события контрола с названием 'dialogCustAccount'.
Поскольку мне лично не нравятся hardcoded-названия, зависимости которых от названий других сущностей нельзя проверить компилятором, решил немного подрихтовать метод "насильной установки названия контрола", чтобы он мог принимать название метода-перехватчика событий на контроле и по нему "понимал", как надо назвать контрол. За счет этого можно избавиться от лишних макросов и получить дополнительные проверки на этапах компиляции и выполнения.
X++:
/// <summary>
///     позволяет задать название следующего добавляемого в диалог контрола
/// </summary>
/// <param name="_customFieldName">
///     желаемое название контрола ИЛИ название метода объекта, перекрывающего один из методов контрола
/// </param>
/// <param name="_isOverloadedFormCtrlMethodName">
///     если true, то из _customFieldName будет выделено желаемое название контрола, иначе название получится таким, как заказали
/// </param>
/// <remarks>
///     Если _isOverloadedFormCtrlMethodName == true, то из названия контрола вырезается название предположительно перекрытого на нем метода,
///     при этом перебираются все возможные методы контрола, не являющиеся свойствами и не объявленные как final (такие перекрыть нельзя).
///     Т.о. можно передавать сюда название метода объекта, а не просто строку, что обеспечит контроль на этапе компиляции: имена контрола и метода уже не "разъедутся"
/// </remarks>
/// <exception cref="Exception::Error">
///     выбрасывается, если _isOverloadedFormCtrlMethodName == true, но из переданного названия метода не удалось выделить желаемое название контрола
/// </exception>
public final void customFieldName_RU(str _customFieldName, boolean _isOverloadedFormCtrlMethodName = false)
{
    #macrolib.AOT

    DictMethod      dictMethod;
    DictClass       dictClass;
    TreeNodePath    methodPath;
    TreeNode        methodNode;
    str             methodSign;
    str             pattern;
    Counter         n;
    ;
    if (_isOverloadedFormCtrlMethodName && _customFieldName)
    {
        // перебираем все методы класса контрола, которые можно перекрыть, и пытаемся "догадаться", какому методу соответствует название в _customFieldName
        // TODO возможно, следует перебирать методы нескольких объектов, а не только FormStringControl
        dictClass = new DictClass(classnum(FormStringControl));
        for (n = 1; n <= dictClass.objectMethodCnt(); n++)
        {
            dictMethod = new DictMethod(UtilElementType::Class, dictClass.id(), dictClass.objectMethod(n));
            if (    dictMethod
                && !dictMethod.isAbstract()
                && !dictMethod.isStatic()
                && !dictMethod.propertyMethod()
               )
            {
                // дополнительная проверка, что метод - не final, иначе ведь его нельзя перекрыть...
                methodPath = strfmt(#SystemClassesPath + @'\%1\%2', dictClass.name(), dictMethod.name());
                methodNode = TreeNode::findNode(methodPath);
                if (methodNode)
                {
                    methodSign = methodNode.AOTtoolTip();
                    methodNode.treeNodeRelease();
                    methodNode = null;
                    if (!(  match(@'<final ', methodSign)
                        ||  match(@' final ', methodSign)
                       ))
                    {
                        pattern = strfmt(@'<[0-9a-z_]+_%1>', dictMethod.name());
                        if (match(pattern, _customFieldName))
                        {
                            // BINGO!
                            // выделяем из названия метода, перекрывающего метод контрола, желаемое название контрола
                            customFieldName = substr(_customFieldName, 1, strlen(_customFieldName) - strlen(dictMethod.name()) - 1);
                            break;
                        }
                    }
                }
            }
        }
        if (customFieldName == '')
        {
            throw error(strfmt(@"Не удалось определить, какой метод контрола перекрывает метод с названием '%1'", _customFieldName));
        }
    }
    else
        customFieldName = _customFieldName;
}
/*
void customFieldName_RU(str _customFieldName)
{
    ;
    customFieldName = _customFieldName;
}
*/
Пример использования:
X++:
dialog.customFieldName_RU(methodstr(MyClassName, dialogCustAccount_modified), true);
За это сообщение автора поблагодарили: Logger (3), Eldar9x (7), Kiot (1).