Цитата:
Сообщение от
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);