Delphi 3. Библиотека программиста

       

Модели, виды и фреймы


Джон Шемитц

В этой главе развивается творческий подход к функциональности программ, который позволяет внедрять одну форму внутрь другой. Новые интерфейсы Delphi3 заметно упрощают эту задачу.

В число достоинств Delphi входит и упрощение многих аспектов работы с Windows API. В результате объемистый и неуклюжий код сокращается до простого оператора присваивания, а невообразимо сложное становится совсем тривиальным. Вероятно, самым знакомым примером для вас окажется свойство Canvas; кроме того, заслуживает внимания и свойство Parent. Задавая значение свойства Parent, вы сообщаете Windows о том, что элемент становится дочерним окном нового родителя Parent. Отныне он будет появляться на экране одновременно со своим окном-родителем. (Кстати, именно так работают диалоговые окна со вкладками: каждая страница фактически представляет собой панель. Все компоненты, находящиеся на ней, являются дочерними по отношению к вкладке. Когда вкладка переходит на передний план (поверх других вкладок), вместе с ней появляются и все ее компоненты.) Задание свойства Parent во время выполнения программы позволяет добиться разнообразных специальных эффектов — от динамического создания элементов типа вкладок до включения одной формы в пустую область другой.

Когда могут пригодиться внедренные формы? Рассмотрим четыре возможных сценария:

  1. Вы занимаетесь созданием программ-мастеров (wizards), руководящих действиями пользователя при создании объектов. Кроме того, вы хотите предоставить пользователям список свойств объекта в виде диалогового окна со вкладками, чтобы позволить изменять любое свойство объекта, не проходя заново все этапы работы с мастером. Единственное отличие между мастером и списком свойств заключается в том, что мастер разрешает пользователю перейти только от текущей страницы к следующей (и лишь при условии ввода правильных данных), а вкладки списка свойств можно перебирать в произвольном порядке. Следовательно, вкладка списка свойств на рис. 10.1 содержит точно такой же набор данных объекта, как и страница мастера на рис. 10.2. Если страницы мастера будут обслуживаться тем же кодом, что и вкладки списка свойств, поведение этих объектов всегда будет согласованным.

    Рис. 10.1. Мастер, использующий код для просмотра данных совместно
    со списком свойств на рис. 10.2

    Рис. 10.2. Список свойств, использующий код для просмотра
    данных совместно с мастером на рис. 10.1

  2. Ваши объекты могут отображаться в нескольких различных контекстах. Например, один и тот же человек может быть и подчиненным, и начальником. Если для просмотра информации о начальнике будет использо ваться тот же код, что и для информации о подчиненном, программа ста- нет более компактной, и в ней исчезнет вероятность рассогласования.
  3. Вы участвуете в разработке большого и сложного диалогового окна со вкладками. Из-за сложности окна над ним трудится целая команда программистов, каждый из которых отвечает за одну или несколько вкладок. Вместо того чтобы объединять изменения в одном общем модуле, вы наверняка предпочтете хранить каждую вкладку в отдельном модуле. При этом участники команды не будут «наступать на пятки» друг другу, а программа станет более логичной и понятной.
  4. Вы работаете с некой иерархией объектов, и вам нужна форма, с помощью которой пользователи могли бы просматривать и/или изменять любые объекты, входящие в иерархию. Некоторые действия применимы ко всем участникам иерархии, другие возможны только для некоторого подмножества объектов. Логичнее всего было бы создать единую форму с элементами, отвечающими за выполнение общих действий. Во время выполнения на форму можно добавлять специализированные элементы, относящиеся к определенному типу объектов, и изменять их при смене выбранного объекта.

Первые два варианта имеют много общего. У нас имеются объекты и стандартные способы для их просмотра и изменения — модели (models) и виды (views). Все, что вам теперь нужно — это фрейм. Фрейм (frame) может содержать любой вид. При отображении фрейма отображается и находящийся в нем вид. Один и тот же вид можно поместить в несколько фреймов. Виды, в свою очередь могут исполнять функции фрейма для видов внедренных или подчиненных объектов.

Фреймы прекрасно подходят и для третьего сценария. Если на каждой вкладке окна будет находиться отдельный фрейм, у вас получится обобщенное диалоговое окно со вкладками, которое может содержать любые виды по вашему усмотрению. Из громоздкого набора ничем не связанных (по крайней мере потенциально) фрагментов модуль формы превращается в простой контейнер с кодом для заполнения каждого фрейма и, возможно, кодом OnChanging, в котором активный фрейм спрашивает у своего вида, можно ли переключиться на другую вкладку. Большое диалоговое окно со вкладками можно разделить на несколько модулей, чтобы каждый участник команды мог самостоятельно следить за обновлением своего кода. Вы забудете о таких неприятностях, как потеря обновлений или повторное появление уже исправленных ошибок из-за неаккуратного объединения версий.

Аналогично форма для редактирования объектов иерархии из четвертого сценария может содержать несколько элементов для операций, применимых ко всем членам иерархии, и фрейм для размещения вида, специфического для конкретного объекта (можно сделать так, чтобы объект сам сообщал форме, какой вид следует использовать). Чтобы перейти от одного типа объекта к другому, достаточно поместить во фрейм другой вид.



Содержание раздела