Коллега придумал оригинальный и вполне надежный способ гарантированно перехватывать события на полях диалога - даже когда заранее неизвестно, сколько полей будет в этом диалоге выведено (ну, в разумных пределах, конечно). Суть-то проблемы в чем?
- Методы-перехватчики идентифицируются формой в соответствии с названиями контролов на форме;
- Названия полям диалога даются в зависимости от числовых идентификаторов, присваиваемых объектам DialogField при добавлении полей в диалог, а также от индекса отображаемого DialogField'ом поля в поле-массиве (обычно этот индекс равен 1) - см. метод \Classes\DialogField\fieldname;
- В диалог в зависимости от настроек может быть добавлено произвольное количество дополнительных полей - это происходит при вызове super() в перекрытом методе \Classes\RunBase\dialog, в результате управлять нумерацией объектов DialogField внутри диалога при добавлении их методами addField()/addFieldValue() становится затруднительно.
Так вот, чтобы принудительно задавать эти самые номера объектам DialogField, коллега нашел такой способ:
X++:
class DEV_FormMethodOverloadSample
extends RunBase
{
// ссылка на диалог понадобится для методов-обработчиков
// событий на полях диалога, которые мы собираемся повесить
Dialog dialog;
DialogField df1;
DialogField df2;
// задаем идентификаторы для DialogField, заведомо бОльшие
// того количества полей, которое может быть добавлено в диалог
#define.DlgFldNum1 (10240)
#define.DlgFldNum2 (10241)
// ...
}
protected Object dialog(DialogRunbase _dialog = null, boolean _forceOnClient = false)
{
;
dialog = super( _dialog, _forceOnClient );
// вот в чем фишка! создаем DialogField сами и "привязываем" к диалогу
df1 = new DialogField( dialog, typeid(AmountCur), #DlgFldNum1 );
df1.init( dialog );
// значение df1 можно установить здесь же или в putToDialog()
df2 = new DialogField( dialog, typeid(JournalId), #DlgFldNum2 );
df2.init( dialog );
// ...
return dialog;
}
public void dialogPostRun(DialogRunbase _dialog)
{
super( _dialog );
// вешаем свои обработчики на некоторые события контролов диалоговой формы
// NB! наш класс должен иметь свойство RunOn == Client или Called from
// и canSwapBetweenCS() должен возвращать true, иначе этот код будет
// вызван на сервере, и никакого _dialog.formRun() мы не увидим
_dialog.formRun().controlMethodOverload( true );
_dialog.formRun().controlMethodOverloadObject( this );
}
protected boolean fld10240_1_modified() // df1
{
FormRealControl formControl;
boolean ret;
;
formControl = dialog.formRun().controlCallingMethod();
ret = formControl.modified(); // вызываем super()
if (ret)
{
// дальше выполняем нужные действия
}
return ret;
}
protected void fld10241_1_lookup() // df2
{
FormStringControl formControl;
;
formControl = dialog.formRun().controlCallingMethod();
// дальше выполняем нужные действия
}