12.08.2010, 08:17 | #1 |
Иван Захаров
|
Расширенные возможности отслеживания событий на диалогах классов-наследников RunBase
В AX2009 RU5 появилась возможность простого расширения возможностей отслеживания событий на диалогах классов-наследников RunBase.
Поясню как это использовать (на примере InventBaileeCreateCalc_RU): 1. Добавляем в classDeclaration следующую конструкцию: X++: CustAccount custAccount;
DialogField dialogCustAccount;
#define.dialogCustAccount('dialogCustAccount') 2. В метод dialog() добавляем вызов ещё пары методов: X++: ... dialog.customFieldName_RU(#dialogCustAccount); // здесь насильно устанавливаем название создаваемого контрола в форме диалога dialogCustAccount = dialog.addFieldValue(typeid(CustAccount), custAccount); ... dialog.allowControlMethodOverload_RU(true); // а теперь разрешаем инстансу настоящего класса отлавливать события контролов 3. Теперь создаём метод dialogCustAccount_modified(), который позволяет отлавливать события контрола с названием 'dialogCustAccount' (если бы мы не изменяли название контрола, то метод бы назвался Fld1_modified, или Fld3_2 - взависимости от того где и как вы вызываете dialog.addField или dialog.addFieldValue) Примечание: Поля-массивы (Dimension) будут иметь наименование с суффиксом содержащим номер элемента массива. Пример: dialogDimension_1, dialogDimension_2, ... Очень важное примечание: поскольку в этом методе вы имеете дело с серверной версией класса Dialog, то для корректной работы нужно не забывать обновлять значения полей "обрамляющим" вызовом методов updateServer() и updateClient()) X++: protected boolean dialogCustAccount_modified() { boolean ret = dialog.curFormControl_RU().modified(); ; dialog.dialogOnClient_RU().updateServer(); dialogContractCode.value(''); dialogContractAccount.value(''); this.dialogActivateFields(); dialog.updateClient(dialog.dialogOnClient_RU()); return ret; } Таким же точно образом можно отслеживать методы lookup(), validate(), selectionChange() и др... P.S. Собственно изначально делал это в AX3, а теперь удалось получить это в рамках RU5. Пользуйтесь на здоровье! |
|
|
За это сообщение автора поблагодарили: db (3), sukhanchik (5), gefr (1), konopello (2), MikeR (1), gl00mie (3), alex55 (1), jeky (1), imir (1). |
12.08.2010, 09:23 | #2 |
Ищущий знания...
|
в аксапте 3.0 отлавливание событий на диалоге сильно глючило, т.е. если на диалоге есть query, то при нажатии кнопки выбор, а потом закрытии её, поля запроса удваивались, если пользователь нажимал раза три кнопку выбор, то форма не умещалась на экран
Вопрос в Ax2009 RU5 это исправили??
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
12.08.2010, 09:32 | #3 |
MCT
|
Можно наверное добавить еще и пересчет других полей диалога в зависимости от измененеия в поле. Но честно когда увидел сильно кастомизированный dialog, то переделал все на вызов формочки. Уж больно гиморно поддерживать
__________________
Axapta book for developer |
|
12.08.2010, 10:56 | #4 |
Участник
|
dialog.customFieldName_RU(#dialogCustAccount);
dialogCustAccount = dialog.addFieldValue(typeid(CustAccount), custAccount); dialogItemId = dialog.addFieldValue(typeid(ItemId), ItemId); вопрос - какое имя контрола после выполнения третьей строки кода? ps нет под рукой ax2009 RU5 |
|
12.08.2010, 11:34 | #5 |
Участник
|
Цитата:
|
|
30.08.2011, 19:32 | #6 |
:o)
|
доброго !
подскажите, пожалуйста, как правильно вызвать lookup в данном контексте
__________________
"Только на Бога не может быть обиды - если смерть пошлет, значит, жизни пришел предел, на то рождался,- а за все остальное на Земле есть и должен быть спрос!." Чингиз Торекулович Айтматов. Последний раз редактировалось jeky; 30.08.2011 в 20:06. |
|
30.08.2011, 20:20 | #7 |
:o)
|
Спасибо всем и Wamr-у
Покопалась в классе InventBaileeCreateCalc_RU - всё получилось!!
__________________
"Только на Бога не может быть обиды - если смерть пошлет, значит, жизни пришел предел, на то рождался,- а за все остальное на Земле есть и должен быть спрос!." Чингиз Торекулович Айтматов. |
|
|
За это сообщение автора поблагодарили: gefr (1). |
02.09.2011, 11:50 | #8 |
Участник
|
В DAX 2012 можно делать вот так:
X++: protected void updateDesign() { formStringCtrl = form.control(#StringCtrlId); formStringCtrl.registerOverrideMethod( methodStr(FormStringControl, JumpRef), methodStr(MyFormHandlerClass, custTableJumpRef), this); } public void custTableJumpRef(FormStringControl _control) { Args args = new Args(); args.record(formDS.cursor()); new MenuFunction(menuitemdisplaystr(CustTable), MenuItemType::Display).run(args); }
__________________
The 50-50-90 rule: Any time you have a 50-50 chance of getting something right, there’s a 90% probability you’ll get it wrong. |
|
|
За это сообщение автора поблагодарили: alex55 (1). |
12.09.2011, 11:42 | #9 |
Участник
|
Мне нужно:
1. Выполнять различный лукап в зависимости от значения друго поля. Срослось. 2. Разрешать выбор нескольких значений. Посмотел, как делается на SysQueryForm, сделал, не работает. Заменяет другое значение при повторном выборе: X++: protected void dialogAccountRelation_lookup() { SysLookup sysLookup; Query query=new Query(); QueryBuildDataSource queryBuildDataSource; FormControl _formcontrol=dialog.curFormControl_RU(); TmpSysQuery TmpSysQuery; boolean rn=false; ; oldvalue=_formcontrol.valueStr(); dialog.dialogOnClient_RU().updateServer(); if(this.priceModule(dialogRelation.value())==ModuleInventCustVend::Vend){ switch(dialogAccountCode.value()){ case TableGroupAll::All:break; case TableGroupAll::GroupId: queryBuildDataSource=query.addDataSource(tablenum(VendGroup)); TmpSysQuery.initValue(); TmpSysQuery.Table_Id=tablenum(VendGroup); TmpSysQuery.Field_Id=fieldnum(VendGroup,VendGroup); TmpSysQuery.insert(); rn=true; break; case TableGroupAll::Table: queryBuildDataSource=query.addDataSource(tablenum(VendTable)); TmpSysQuery.initValue(); TmpSysQuery.Table_Id=tablenum(VendTable); TmpSysQuery.Field_Id=fieldnum(VendTable,AccountNum); TmpSysQuery.insert(); rn=true; break; } if(rn){ syslookup::lookupRange(_formcontrol,TmpSysQuery,query); dialog.updateClient(dialog.dialogOnClient_RU()); } } else info("Поддерживается только для модуля поставщиков"); X++: protected void dialogAccountRelation_modified(){ ; dialog.dialogOnClient_RU().updateServer(); if(OldValue) dialogAccountRelation.value(OldValue+dialogAccountRelation.value()); dialog.updateClient(dialog.dialogOnClient_RU()); } Не подскажете, где косяк? |
|
12.09.2011, 12:58 | #10 |
Участник
|
Все, разобрался сам. В Лукапе не нужен был super(), чего-то и в modified тоже его подзабыл поставить
|
|
09.02.2012, 19:27 | #11 |
Участник
|
Доработка метода Dialog.customFieldName_RU()
Цитата:
Сообщение от ziva
Добавляем в classDeclaration следующую конструкцию:
X++: #define.dialogCustAccount('dialogCustAccount') 2. В метод dialog() добавляем вызов ещё пары методов: X++: // здесь насильно устанавливаем название создаваемого контрола в форме диалога dialog.customFieldName_RU(#dialogCustAccount); // ... 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). |
Теги |
ax2009, dialog, законченный пример, полезное |
|
|