TActionManager

miss.mate
Дата: 07.06.2011 11:36:59
Добрый день!
У меня на одной форме находится TActionManager и TActionMainMenuBar , на этой форме все настроила , все работает как надо. А необходимо на другой форме сделать меню повторябщее тоже самое что на форме где находится TActionManager, возможно ли это сделать имея TActionManager только на одной форме? или нужно для каждой формы свой TActionManager ?
Gust2002
Дата: 07.06.2011 12:09:43
miss.mate,

TActionManager не наследуется. Можно написать обработчик, которые создает его программно и вызывать на нужных формах.
miss.mate
Дата: 07.06.2011 12:47:04
Gust2002
miss.mate,

TActionManager не наследуется. Можно написать обработчик, которые создает его программно и вызывать на нужных формах.


Значит будет правильно если я буду на каждой нужной форме писать создавать новый TActionManager ?
Gust2002
Дата: 07.06.2011 13:19:53
miss.mate
Gust2002
miss.mate,

TActionManager не наследуется. Можно написать обработчик, которые создает его программно и вызывать на нужных формах.


Значит будет правильно если я буду на каждой нужной форме писать создавать новый TActionManager ?


Правильно будет, если весь код создания меню будет вынесен в отдельную процедуру.
miss.mate
Дата: 07.06.2011 13:30:37
Спасибо
roschinspb
Дата: 08.06.2011 00:36:36
miss.mate, мне кажется, что вы не совсем правильно поняли концепцию суть цзэнбудизма :)
TActionMainMenuBar по определнию должен быть только в одной форме (в главной). И TActionManager тоже один.
Если у Вас много форм, то я бы предложил сделать следующим образом.
На главной форме кладете TActionManager и создаёте для него все возможные действия с членораздельными именами, и картинками. ImageList лучше положить в отдельный TDataModule, чтобы другие формы могли к нему обращаться. Настраиваете меню и инструментальные панели по своему усмотрению. Теперь обработчики onExecute и onUpdate: Вы заранее не знаете сколько будет у Вас форм, и тем более не знаете какие будут открыты у пользователя. Но можете предположить, что на любой форме будет ActionList с теми действиями, которые форма может обрабатывать. Обработчик действия (на главной форме) может искать на активной форме одноименное действие и выполнять Update и Execute. После Update копировать свойство Enabled. Если не найдено действие то False.
Пользователь в Runtime может настраивать меню и инструментальные панели, но не обязательно все формы открыты, некоторые еще только в планах... поэтому в TActionManager заранее создаём все действия, а обработчики находим динамически.
Некоторые действия, такие как TDataSetFirst, автоматически привязываются к тому Dbкомпоненту, в котором фокус ввода.

Вот както так.
Мыльников Дмитрий
Дата: 08.06.2011 09:41:34
Зачем такие сложности с процедурами, динамический поиск, создание "руками" и т.п.? Да и про наследование, насколько я понял, речь не шла.

Всё намного проще. Прописываете в секции implementation раздел uses и в нём указываете модуль той формы, на которой размещён ваш TActionManager. После этого можете выбирать его везде в инспекторе свойств, как если бы он был размещён на этой форме. Только имя его будет указано через имя формы с точкой.
Тоже самое справедливо практически для всех невизуальных компонентов, включая ImageList, DataSet, DataSource и т.д.

Чтобы добавить элемент в TActionMainMenuBar из TActionManager с другой формы нужно открыть окно настройки параметров TActionManager на первой форме, потом не закрывая этого окна переключится на вторую форму, а потом как обычно тащить мышкой элемент на TActionMainMenuBar.

Только нужно учесть, что всё это будет нормально работать только в том случае, если в момент создания второй формы первая форма будет уже создана, причём именно через стандартную переменную, которую генерит Delphi в модуле формы. Иначе всё упадёт с ошибкой доступа.

В остальном же всё прекрасно работает.

Единственное, о чём нужно помнить, что при вызове соответствующего события из второй формы оно на самом деле будет отрабатываться в контексте первой формы. А о том, что оно вызывалось из второй формы можно узнать через анализ переменной sender в событии. Либо вы должны придумать какой-то внешний механизм, который будет вам позволять узнать откуда же на самом деле было вызвано событие, чтобы реагировать соответствующим образом. Опять же, прописать в одной форме один обработчик, а в другой - другой, у вас при этом способе не получится.
Gust2002
Дата: 08.06.2011 10:02:21
Мыльников Дмитрий,

Есть одно золотое правило проектирования: модули должны быть независимыми друг от друга.
roschinspb
Дата: 08.06.2011 22:57:55
В сухом остатке имеем:
Мыльников Дмитрий
Всё намного проще:
Только нужно учесть...
Единственное, о чём нужно помнить...
Либо вы должны придумать какой-то...
у вас при этом способе не получится...
короче в приложении из двух форм, всё проще, а когда форм больше, трудности начинают увеличиваться не линейно. Обращаю внимание на основные тезисы:
1. главная форма ни чего не знает о дочерних, т.к. их создано разными людьми очень много и еще больше только планируется.
2. подчиненные формы ни чего не должны знать о главной, т.к. иначе невозможно их будет перетащить из одного проекта в другой, кроме того малейшее изменение в главной форме потребует переделок во многих подчиненных.
3. перекрестные ссылки, когда главный модуль ссылается на подчиненный, а подчиненный на главны вещь хоть и допустимая в языке, но крайне кривая с точки зрения архитектуры приложения (см. п. 2 и 10780607)
4. правилом хорошего тона, является возможность пользователя, настраивать инструментальные панели и меню во время работы программы. Так вот не факт, что во время загрузки/настройки у вас будут созданы все подчиненные формы, и по этому доступа ко всем возможным действиям не будет.
5. в мелкие приложения, в которых можно не заморачиваться с проектированием, вообще не вижу смысла запихивать TActionManager и TActionMainMenuBar. Накидал батонов, и покатит.