20.08.2008, 12:52 | #1 |
Гость
|
Выбираем Enum, меняется Lookup, как правильней закодить?
Задача выглядит так:
Исходные: На форме есть группа из 2х контролов для сортировки таблицы. Первый контрол - выбор значения Enum (TypeFilter), второй контрол - выбор значения EDT (GroupFilter), EDT:ItemGroupId. Нужно: отображать не всю кучу записей из EDT, а в соответствии с критерием Enum-а. Вопрос: как это лучше закодить? Почему возник вопрос - недавно на этом форуме очень нелестно отзывались о программировании на формах, его нужно избегать? Сводить к минимуму? Есть какие-то правила хорошего тона? У меня 2 варианта: или перекрывать Lookup на контроле, который EDT (GroupFilter), или сделать несколько наследников EDT с нужными фильтрами и подсовывать их в GroupFilter.extendedDataType(). Можно ещё создать кучу контролов, каждый со своим EDT и отображать их в зависимости от выбранного Enum... Какой способ правильней? |
|
20.08.2008, 13:01 | #2 |
Axapta
|
Цитата:
Цитата:
Code on form methods
Only place code on a form when you cannot possibly place it on a class or on a table method. This means that you will not generally find X++ code here! If you have to place code on a form, you should strive to place it on the data source. Only when you are absolutely certain that there is no other solution should you place code directly on controls. Code on a form must be for the purpose of manipulating the form, including the form’s query. Цитата:
Сообщение от Shakr
У меня 2 варианта: или перекрывать Lookup на контроле, который EDT (GroupFilter), или сделать несколько наследников EDT с нужными фильтрами и подсовывать их в GroupFilter.extendedDataType(). Можно ещё создать кучу контролов, каждый со своим EDT и отображать их в зависимости от выбранного Enum...
Какой способ правильней? Поясню. Делать разные ЕДТ и подсовывать их в рантайме - плохо. Вы совсем не любой алгоритм фильтрации сможете сделать через ЕДТ. Стоит ему стать сколько-нибудь сложным и упс, придется код писать. Да и в рантайме менять свойства объектов - тоже не лучший способ, в общем случае. Надо стараться такого избегать. Делать много контролов и управлять видимостью? К чему такие сложности? Плюс еще и придется при изменении квери датасорса анализировать, значение какого из фильтров брать. Зачем? А не на контроле - чтобы лукап срабатывал и в том случае, если это поле будет еще где-то на форме. На контролах вообще почти никогда не стоит ничего программировать.См. выше. Последний раз редактировалось oip; 20.08.2008 в 15:36. Причина: Еще раз исправил и добавил. |
|
20.08.2008, 13:11 | #3 |
Участник
|
я так понял, что эти поля с источником данных не связаны. Соответственно на источнике данных перекрыть не получится.
Перекрываем на контроле, и в нем вызываем метод на уровне формы, в котором пишем что-то типа: X++: void callLookupOnControl(FormStringControl _callingControl) switch (BaseEnumField.selection()) { case BaseEnumFieldEnum::One: ItemGroup::lookupCtrlBaseEnumOne(_callingControl); break; ..... } |
|
20.08.2008, 13:13 | #4 |
Гость
|
Цитата:
Code on a form must be for the purpose of manipulating the form, including the form’s query.
Цитата:
Третий: перекрыть лукап на датасорсе.
Кстати, лукап на датасорсе и до меня перекрыли. Но лукап на датасорсе меняли, чтобы человек не смог выбрать значение поля, отличающееся от критерия фильтрации. А контролы нужны для фильтрации самого датасорса. Или я не понял, что вы имели в виду. |
|
20.08.2008, 13:15 | #5 |
Участник
|
На контроле, на котором вы пытаетесь изменить лукап, установлены свойтва DataSource and DataField?
|
|
20.08.2008, 13:17 | #6 |
Гость
|
нет. только EDT
|
|
20.08.2008, 13:20 | #7 |
Axapta
|
Ок, да, тогда в данном случае перекрываем лукап контрола.
|
|
20.08.2008, 13:23 | #8 |
Axapta
|
Цитата:
X++: ItemGroup::lookupCtrlBaseEnum(_callingControl, BaseEnumField.selection()); |
|
20.08.2008, 13:25 | #9 |
Гость
|
А callLookupOnControl в 3.0 есть?
извините, не прочитал пояснения Oip, читаю Последний раз редактировалось Shakr; 20.08.2008 в 13:30. |
|
20.08.2008, 13:26 | #10 |
Участник
|
Зависит от ситуации. Так получается, что всегда нужно будет передавать значение BaseEnumField. Я предпочитаю иметь методы с четким предназначением, с меньшим кол-вом параметров.
При подходе с одним методом, зато, будет меньше кода на форме. |
|
20.08.2008, 13:29 | #11 |
Axapta
|
А у тебя получается, что при смене алгоритма фильтрации придется кучу методов переписывать и менять, а не один. Ну и что, что всегда надо передавать? У нас вроде алгоритм фильтрации как раз и зависит от этого значения (см. условие задачи), конечно его надо передавать, а как еще? Или я тебя не понял? Если уж хочешь разделить на узкоспециализированные методы (зависит от ситуации, согласен), то не вопрос. Вызываешь общий табличный метод, в него передаешь параметр, а уже в этом общем методе разруливаешь, какой из методов вызывать дальше. Но параметр все равно надо передавать скорее всего.
Последний раз редактировалось oip; 20.08.2008 в 13:41. Причина: Добавил немного текста... |
|
20.08.2008, 13:44 | #12 |
Участник
|
Да, я подразумевал, что методы в дальнейшем будут использоваться из других мест, где может понадобиться только специализированный метод, не зависящий от какого-либо энума. И передавать его значение специально уже теряет смысл.
Дело вкуса, думаю |
|
20.08.2008, 13:48 | #13 |
Axapta
|
Тогда делаешь один общий метод и несколько специализированных. Когда нужно (как в данном случае) используешь общий сначала, когда не нужно (плохо себе представляю подобную ситуацию, но допускаю) - сразу специальный. Но в твоем варианте в любой форме, где нужна будет точно такая же фильтрация, придется писать этот самый свитч, а при смене алгоритма искать все подобные формы и править. Лишний и ненужный код на форме. Нехорошо-с.
Upd. Например, если у нас есть энум CustVend, то делаем lookupCustVend, где в зависимости от параметра вызываем или lookupCust или lookupVend. Но рулим этим не на форме, а в табличном методе. Не совсем согласен, что дело вкуса. Не уверен, что твой такой код прошел бы мой Code Review. |
|
20.08.2008, 13:59 | #14 |
Участник
|
|
|
|
За это сообщение автора поблагодарили: (1). |
20.08.2008, 15:19 | #15 |
Гость
|
Цитата:
Поясню. Делать разные ЕДТ плохо, т.к. в общем случае их будет 2^(n-1), где n - количество элементов в энуме
В моём случае, в енуме 3 элемента, 1 исходный ЕДТ: ItemGroupId, из которого я делаю 3 (условно назвал): ItemGroupId_1 ItemGroupId_2 ItemGroupId_3 Но это не 2^(3-1) = 4.. для 4 элементов енума: +4 едт (всего 5), но не 2^(4-1) = 8 Последний раз редактировалось Shakr; 20.08.2008 в 15:22. |
|
20.08.2008, 15:26 | #16 |
Axapta
|
Да, я исправил уже. Я сначала не о том подумал. Но все равно в общем случае лукап на контроле перекрывать надо.
|
|
|
За это сообщение автора поблагодарили: (1). |
20.08.2008, 16:26 | #17 |
Moderator
|
Господа, а можно в двух словах о самой физической задачке? А то дискуссия оживленная, но понимаю, что чего-то не понимаю... Что за контролы с Enum и EDT? Откуда для них выбираются значения? Из Dictionary? Спасибо.
|
|
20.08.2008, 16:28 | #18 |
Axapta
|
Эм... Значения для энума выбираются из АОТа. Значения для контрола с ЕДТ - вероятно из связанной с этим ЕДТ таблицей.
|
|
20.08.2008, 17:01 | #19 |
Moderator
|
Хм, сорри, что туплю, но все равно не прожёвываю...
Ну вот выбрал я, допустим, Enum = RAssetTransType - чем список для EDT должен заполниться? EDTами, у которых EnumType = RAssetTransType? Или под Enum в задачке имеется в виду список самих значений для конкретного Enum, т.е. для RAssetTransType это "Амортизация", "Списание", "Ввод в эксплуатацию" и т.п. Но что тогда дополнительно при этом выбирается в контроле "EDT"? |
|
20.08.2008, 17:05 | #20 |
Участник
|
Думаю, здесь больше
ItemType ItemId Item все товары (Finished goods) BOM все запчасти,товары произведенные Service все сервисы это предположение |
|