Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»
Форма и элементы управления
Как населить форму элементами управления? Чаще всего, это делается вручную в режиме проектирования. Доступные элементы управления, отображаемые на специальной панели (Toolbox), перетаскиваются на форму. Этот процесс поддерживается особым инструментарием — дизайнером форм (Designer Form). Как только на этапе проектирования вы сажаете на форму элемент управления, немедленно в тексте класса появляются соответствующие строки кода (в лекции 2 об этом подробно рассказано). Конечно, все можно делать и программно — появление соответствующих строк кода приводит к появлению элементов управления на форме. Нужно понимать, что форма — это видимый образ класса Form, а элементы управления, размещенные на форме — это видимые образы клиентских объектов соответствующих классов, наследников класса Control. Так что форма с ее элементами управления есть прямое отражение программного кода.
Каждый вид элементов управления описывается собственным классом. Библиотека FCL содержит большое число классов, задающих различные элементы управления. Одним из типов проектов, доступных на С#, является проект, создающий элемент управления, так что ничто не мешает создавать собственные элементы управления и размещать их на формах наряду со встроенными элементами. Многие фирмы специализируются на создании элементов управления — это один из видов повторно используемых компонентов.
В каких отношениях находятся класс Form, класс Control, классы элементов управления? На рис. 24.1 показана иерархия отношений, связывающих эти классы.
Рис. 24.1. Иерархия классов элементов управления
Естественно, все эти классы являются потомками прародителя — класса Object. Заметьте, класс Control в иерархии классов занимает довольно высокое положение, хотя и у него есть два важных родительских класса — класс Component, определяющий возможность элементам управления быть компонентами, и класс MarshaiByRefObject, задающий возможность передачи элементов управления по сети. Класс Control задает важные свойства, методы и события, наследуемые всеми его потомками. Все классы элементов управления являются наследниками класса Control. Чаще всего, это прямые наследники, но иногда они имеют и непосредственного родителя, которым может быть абстрактный класс — это верно для кнопок, списков, текстовых элементов управления. Может показаться удивительным, но класс Form является одним из потомков класса Control, так что форма — это элемент управления со специальными свойствами. Будучи наследником классов ScrollAbieControl и ContainerControl, форма допускает прокрутку и размещение элементов управления.
Взаимодействие форм
Обычное Windows-приложение всегда содержит несколько форм. Одни открываются в процессе работы, другие закрываются. В каждый текущий момент на экране может быть открыта одна или несколько форм, пользователь может работать с одной формой или переключаться по ходу работы с одной на другую.
Следует четко различать процесс создания формы — соответствующего объекта, принадлежащего классу Form или наследнику этого класса, — и процесс показа формы на экране. Для показа формы служит метод Show этого класса, вызываемый соответствующим объектом; для скрытия формы используется метод Hide. Реально методы Show и Hide изменяют свойство Visible объекта, так что вместо вызова этих методов можно менять значение этого свойства, устанавливая его либо в true, либо в false.
Заметьте разницу между сокрытием и закрытием формы — между методами Hide и Close. Первый из них делает форму невидимой, но сам объект остается живым и невредимым. Метод close отбирает у формы ее ресурсы, делая объект отныне недоступным; вызвать метод Show после вызова метода Close невозможно, если только не создать объект заново. Открытие и показ формы всегда означает одно и то же — вызов метода Show, у формы есть метод Close, но нет метода Open. Формы, как и все объекты, создаются при вызове конструктора формы при выполнении операции new.
Форма, открываемая в процедуре Main при вызове метода Run, называется главной формой проекта. Ее закрытие приводит к закрытию всех остальных форм и завершению Windows-приложения. Завершить приложение можно и программно, вызвав в нужный момент статический метод Exit класса Application. Закрытие других форм не приводит к завершению проекта. Зачастую главная форма проекта всегда открыта, в то время как остальные формы открываются и закрываются (скрываются). Если мы хотим, чтобы в каждый текущий момент была открыта только одна форма, то нужно принять определенные меры, чтобы при закрытии (скрытии) формы открывалась другая. Иначе возможна клинчевая ситуация — все формы закрыты, предпринять ничего нельзя, а приложение не завершено. Конечно, выход всегда есть — всегда можно нажать магическую тройку клавиш CTRL+ALT+DEL и завершить любое приложение.
Можно создавать формы как объекты класса Form. Однако такие объекты довольно редки. Чаще всего создается специальный класс FormX — наследник класса Form. Так, в частности, происходит в Windows-приложении, создаваемом по умолчанию, когда создается класс Form1 — наследник класса Form. Так происходит в режиме проектирования, когда в проект добавляется новая форма с использованием пункта меню Add windows Form. Как правило, каждая форма в проекте — это объект собственного класса. Возможна ситуация, когда вновь создаваемая форма во многом должна быть похожей на уже существующую, и тогда класс новой формы может быть сделан наследником класса формы существующей. Наследование форм мы рассмотрим подробнее чуть позже.
Модальные и немодальные формы
Первичным является понятие модального и немодального окна. Окно называется модальным, если нельзя закончить работу в открытом окне до тех пор, пока оно не будет закрыто. Модальное окно не позволяет, если оно открыто, временно переключиться на работу с другим окном. Выйти из модального окна можно, только закрыв его. Немодальные окна допускают параллельную работу в окнах. Форма называется модальной или немодальной в зависимости оттого, каково ее окно. Метод Show открывает форму как немодальную, а метод ShowDialog — как модальную. Название метода отражает основное назначение модальных форм — они предназначены для организации диалога с пользователем, и пока диалог не завершится, покидать форму не разрешается.
Передача информации между формами
Часто многие формы должны работать с одним и тем же объектом, производя над ним различные операции. Как это реализуется? Обычная схема такова: объект создается в одной из форм, чаще всего, в главной. При создании следующей формы глобальный объект передается конструктору новой формы в качестве аргумента. Естественно, одно из полей новой формы должно представлять ссылку на объект соответствующего класса, так что конструктору останется только связать ссылку с переданным ему объектом. Заметьте, все это эффективно реализуется, поскольку объект создается лишь один раз, а разные формы содержат ссылки на