Delphi, фреймы против форм. Что за многодокументный интерфейс?
Вчера я начал обсуждение "MDI против интерфейса с вкладками". Я спросил, стоит ли мне продолжать разработку моего приложения на основе MDI или я должен встраивать дочерние формы в таблицы вкладок. Кто-то указал, что я должен использовать вместо этого TFrames... Мой вопрос: почему?
Каковы преимущества использования TFrames при встраивании формы поверх TFrame? Пока что я не знаю, переключение потребует от меня только переписать некоторые части кода...
(В любом случае, я не собираюсь использовать встраивание во время разработки!)
заранее спасибо
7 ответов
Отвечая на комментарий, укажите причину использования фреймов:
Я бы посчитал, что фреймы являются строительными блоками графического интерфейса с сочетанием времени разработки существующих компонентов с более продвинутыми компонентами. До Delphi 5 можно было бы использовать TCustomPanel
потомок с дочерними элементами управления и зарегистрировал его как новый компонент, готовый для размещения на форме. Рамки позволяют то же самое с меньшими хлопотами.
Они позволяют вам сосредоточиться на разработке именно той функциональности, которая вам нужна, и не более того. Если все сделано правильно, вы можете встраивать их в контрольные листы вкладок, в модальные или немодальные диалоги, в дочерние фреймы MDI и в стандартные фреймы. Вы даже можете добавить несколько из них в одну форму - что-то, что, вероятно, не будет делать со встроенными формами. Дело в том, что для максимального повторного использования часто необходим многоуровневый подход, и фреймы помогают в этом.
Рамка подходит для встраивания с ходу. Форма должна быть адаптирована так, чтобы не отображать строку заголовка и границу, обычно можно переопределить CreateParams()
и настроить стиль окна соответственно. В инспекторе намного больше свойств формы, которые просто не имеют смысла для встроенной формы. ИМХО, нужно использовать самую основную и общую сущность, которой достаточно. Форма просто намного больше, чем контрольный контейнер для встраивания.
OTOH Я не знаю ни одного недостатка встраивания фрейма, который бы не имел встраивание формы.
Редактировать:
Там есть комментарий относительно таких событий, как OnCreate
или же OnShow
что кадры не имеют. На самом деле, я бы подумал, что еще одно преимущество фреймов, так как обработчики событий не имеют параметров, поэтому многие вещи обязательно жестко запрограммированы в формах.
Рассмотрим случай индивидуальных настроек: в OnCreate
там не так много доступной информации, так что каждый неизменно заканчивает тем, что использует константу или имя формы для раздела файла INI, что делает очень трудным или даже невозможным повторное использование формы или создание нескольких ее экземпляров. С фреймами с другой стороны метод LoadSettings
это очевидный способ сделать это, и он может нести необходимые параметры. Таким образом, управление возвращается туда, где оно принадлежит, контейнеру встроенной рамки / формы. Возможность повторного использования возможна только в том случае, если поведение можно регулировать извне.
Для содержащихся объектов, которые не являются компонентами и должны управляться на протяжении жизни, существуют, например, AfterConstruction
а также BeforeDestruction
,
Возможно, вы найдете ответы в этой теме: gui-design-множественные формы-против-симулированные-mdi-tabs-vs-pagecontrol
Рама использует самую быструю нагрузку и без задержек при создании рамы.
Но у рамки должен быть родитель, чтобы встроить это. Недостаток - нет события onCreate или onShow. но вы можете позвонить с сообщением для события onShow триггера, как этот:
положить на частную часть кадра:
procedure CMShowingChanged(var M: TMessage); message CM_SHOWINGCHANGED;
а затем создайте код следующим образом:
procedure TFrame1.CMShowingChanged(var M: TMessage);
begin
inherited;
if Showing then
begin
// .... put your code for onShowing is triggered
end
else
begin
// .... put your code for onHiding is triggered
end;
end;
Надежда может помочь вам рассмотреть встроенную рамку для графического интерфейса.
Вы можете рассмотреть в сочетании с PageControl для управления открытием вашего кадра.
Манц
Для динамически вставленных форм / фреймов я лично предпочитаю использовать встроенные формы поверх фреймов. Несколько версий назад, когда один из них редактировал фрейм, для которого было установлено значение alClient, размер фрейма изменялся между правками, а любые элементы управления, которые были выровнены конкретно справа от фрейма, меняли положение. При использовании встроенных форм этого не произошло, поэтому я переключился. Я считаю, что эта проблема теперь исправлена в более поздних версиях Delphi.
Я полностью согласен с замечаниями, которые Мгхи высказал ранее относительно невозможности передачи информации во встроенную форму посредством уведомлений. Чтобы решить эту проблему, я обычно реализую серию интерфейсов в каждой встроенной форме для связи. Это действительно упрощает код и допускает более общие реализации, где у вас есть один "контейнер", который будет иметь дело со многими различными типами встроенных форм / фреймов. Несколько примеров этого доступны в моем блоге как часть созданной мной структуры мастера.
У меня было такое же решение несколько лет назад для одного из наших приложений, мы хотели, чтобы оно выглядело как встроенные формы, сначала я использовал Frames и написал класс для управления им.
Позже я обнаружил компонент TLMDDisplayForm от LMDTools, который сделал задачу встраивания форм в него очень простой задачей, он сократил используемый код и у нас появилось больше возможностей.
одной из основных целей, которую мы изменили с фреймов на формы, было отсутствие некоторых событий TForm, таких как: OnCreate, OnShow, OnActive, которые мы используем для некоторых задач в наших приложениях, помимо отсутствия некоторых свойств, таких как: ActiveControl и других вещей, которые я не помню,
Если вы хотите использовать Forms, я предлагаю вам использовать LMDTools, которые облегчат вам задачу, кроме базовой версии бесплатной:-)
Я думаю, что оба должны быть использованы. Например, у меня есть "стандартный" фрейм с компонентами dbnavigator, dbgrid и datasource, который очень удобен для обычного просмотра данных. Вместо того, чтобы вставлять такие компоненты каждый раз, я вставляю фрейм, который также имеет возможность экспортировать свои данные (с JVCL:D) в несколько форматов... но я знаю, что я хочу отображать во время разработки, поэтому я предлагаю очень простое правило: если оно известно во время разработки, используйте фреймы, в противном случае используйте встроенные формы.
Однако имейте в виду, что формы не были предназначены для встраивания. Использовать их вот так, это неестественно (как утверждает вампир, когда она похоронила свою 80-летнюю дочь и выглядела как 30:D). Встроенная форма мало знает о том, кому она принадлежит, и может (логически) предположить, что она не встроена.
В дополнение к этому, фрейм является компонентом, и поэтому, когда он внедрен (принадлежит) в форму, форма знает об этом, а фрейм знает о форме (может использовать ее методы и свойства. Встраиваемый также может это делать, но требует дополнительного кодирования)
Возможно, Embarcadero может помочь нам, создав TEmbeddableForm или интерфейс для таких целей.
С уважением, Альваро Кастиелло
Фреймы хороши, когда вы хотите повторить "подформу" несколько раз в форме. Я бы не стал использовать их для взаимодействия с вкладками, поскольку встроенная форма - лучшее решение для использования интерфейса MDI/Tabbed.