Многостраничный блокнот — компоненты TTabControl
и TPageControl
В Палитре компонентов имеется два элемента управления, обеспечивающих создание многостраничных блокнотов. Это компоненты TTabControl и TPageControl. Переключение между страницами осуществляется при помощи закладок. Закладки могут выглядеть как "настоящие" в бумажном блокноте, а могут быть похожи на стандартные кнопки Windows. Кстати, сама Палитра компонентов Delphi является примером использования такого элемента управления.
Компонент TTabControl отличается тем, что представляет собой как бы "виртуальный" блокнот. Это — единый объект с одной фактической страницей. При переключении закладок осуществляется вызов метода-обработчика события
property OnChange: TNotifyEvent;
соответствующий код в котором может изменить набор видимых элементов управления и создать для пользователя иллюзию "переключения страниц".
Компонент TFageControl является контейнером для объектов TTabSheet, соответствующих отдельным страницам блокнота. Страницы в нем могут нести каждая свой набор дочерних компонентов; их можно переключать уже во время разработки.
Первый подход удобен, если на разных страницах у вас должны располагаться одни и те же компоненты, "начиненные" различными данными. Идеальный пример приводится самими разработчиками Delphi (папка Help\Samples\TabCntrl — обязательно посмотрите пример!). Здесь TTabControl используется для редактирования базы данных. Закладки для страниц создаются по одной для каждой записи в таблице. А на одной-единственной странице располагаются компоненты для отображения данных. При переключении закладок происходит навигация по таблице, содержимое полей меняется, и создается впечатление перехода на другую страницу.
Второй подход необходим, если у вас действительно разные страницы с различными наборами компонентов на них. Компонент TPageControl используют для создания редакторов свойств и настроек программы, а также для разного рода мастеров (Wizards).
Оба компонента в своей основе имеют общий элемент управления из библиотеки ComCtl32 (в документации Microsoft он называется Tab Control). Соответственно, в иерархии классов Delphi они оба произошли от класса TCustomTabcontrol, от которого унаследовачи значительную часть свойств и методов. А вот механизмы работы отдельных страниц у каждого компонента свои. Поэтому сначала мы рассмотрим общие для двух компонентов свойства, а затем особенности использования страниц. Свойства и методы-обработчики класса-предка TCustomTabcontrol представлены в табл. 5.1 и 5.2 соответственно. Обратите внимание, что перечисленные свойства и методы в потомках объявляются как опубликованные (published).
Таблица 5.1. Основные свойства, общие для TTabControl и TPageContrli
Объявление |
Описание |
property Tablndex: Integer; |
Задает номер текущей страницы, начиная с 0 |
property TabHeight: Smallint; |
Задает высоту закладок в пикселах. При значении 0 высота определяется автоматически так, чтобы вместить текст |
property TabWidth: Smallint; |
Задает ширину закладок. При значении 0 ширина определяется автоматически так, чтобы вместить текст |
type TTabStyle = (tsTabs, tsButtons, tsFlatButtons); property Style: TtabStyle; |
Определяет стиль закладок компонента:
|
type TTabPosition = (tpTop, tpBottom, tpLeft, tpRight); property TabPosition: TTabPosition; |
Определяет расположение закладок на компоненте. Расположение, отличное от tpTop, возможно только для стиля tsTabs |
property HotTrack: Boolean; |
При значении True названия страниц выделяются цветом при перемещении над ними указателя мыши |
property Images : TCustomlmageList; |
Указывает на список картинок, появляющихся на закладках страниц |
property RaggedRight: Boolean; |
При значении True ширина закладок изменяется таким образом, чтобы они не занимали всю сторону блокнота |
property MultiLine: Boolean; |
При значении True закладки страниц могут располагаться в несколько рядов (если они не помещаются в один). При значении False в верхнем правом углу появляются кнопки, организующие прокрутку невидимых заголовков |
property ScrollOpposite: Boolean; |
При значении True, если закладки расположены в несколько рядов, при переходе к закладке следующего ряда все остальные ряды перемещаются на противоположную сторону блокнота. Действительно только при MultiLine=True |
Таблица 5.2. Основные методы-обработчики, общие для TTabControl и TPageControl
Объявление |
Описание |
type TTabChangingEvent = procedure (Sender: TObject; var AllowChange: Boolean) of object; property OnChanging: TTabChangingEvent; |
Вызывается непосредственно перед открытием новой страницы. Параметр AllowChange, установленный в значение False, запрещает открытие |
property OnChange: TNotifyEvent; |
Вызывается при открытии новой страницы |
property OnDrawTab: TDrawTabEvent; |
Вызывается при перерисовке страницы, только если свойство OwnerDraw = True |
property OnGetlmagelndex: TTabGetlmageEvent; |
Вызывается при отображении на закладке картинки |
Как видно из таблицы, большинство свойств обеспечивают различные стили представления многостраничного блокнота. При настройке стиля обратите внимание, что свойство RaggedRight может не работать, т. к. вступает в противоречие со свойством Tabwidth. При Tabwidth = 0 компонент изменяет ширину закладок в соответствии с длиной текста, в противном случае ширина закладок всегда равна значению свойства Tabwidth.
Для того чтобы в закладках совместно с текстом показать картинки, используется свойство images, в котором необходимо задать требуемый экземпляр компонента TImageList (см. ниже).
Свойство Tabindex, задающее номер текущей страницы, позволяет переключать страницы программно. Для компонента TTabControl это единственный способ изменить текущую страницу на этапе разработки. При смене страниц сначала происходит событие onchanging — в этот момент Tabindex еще содержит индекс старой страницы (и смену можно запретить), а затем OnChange — это свойство уже указывает на новую страницу.
В компоненте TTabControl число и заголовки страниц полностью зависят от свойства
property Tabs: TStrings;
В списке перечисляются заголовки страниц, для которых автоматически создаются закладки. Порядок следования страниц зависит от расположения текстов заголовков в свойстве Tabs.
При этом забота о правильном чередовании элементов управления при смене страниц полностью ложится на программиста. Для этого необходимо в методе-обработчике OnChange определить видимость элементов в зависимости от индекса текущей страницы:
procedure TForml.TabControllChange(Sender: TObject);
begin
with TabControll do
begin
Editl.Visible := Tablndex = 0;
Edit2.Visible := Tablndex = 1;
Edit3.Visible := Tablndex = 2;
end;
end;
Компонент TPageControl, в отличие от TTabControl, для обеспечения работы создает "настоящую" страницу — экземпляр класса TTabSheet. Список указателей на все созданные экземпляры страниц хранится в свойстве Pages, доступном только для чтения:
property Pages[Index: Integer]: TTabSheet;
Номер индекса соответствует порядковому номеру страницы. Для создания новой страницы используется команда New Page из всплывающего меню компонента, перенесенного на форму. Если же вы хотите создать страницу на этапе выполнения, создайте экземпляр TTabSheet самостоятельно и в свойстве Pagecontrol укажите на родительский блокнот:
pcMain: TPageControl;
ts : TTabSheet;
...
ts := TTabSheet.Create(pcMain);
with ts do
begin
PageControl := pcMain;
ts.Caption :='New page' ;
end;
Общее число страниц хранится в свойстве
property PageCount: Integer;
доступном только для чтения. Текущую страницу можно задать свойством:
property ActivePage: TTabSheet;
Если во время разработки (этой возможностью компонент TPageControl отличается от своего собрата) или во время выполнения переключиться на другую страницу, значение свойства ActivePage изменится.
Также для перехода на соседнюю страницу программными средствами можно использовать метод
procedure SelectNextPage(GoForward: Boolean);
в котором параметр GoForward при значении True задает переход на следующую страницу, иначе — на предыдущую.
Рассмотрев свойства блокнота, обратимся к его страницам и остановимся подробнее на возможностях класса TTabSheet. На владельца страницы указывает значение свойства
property PageControl: TPageControl;
Расположение страницы в блокноте задает свойство Pageindex:
property Pageindex: Integer;
Если в блокноте одновременно выделено несколько страниц, то положение данной страницы среди выделенных определяется свойством только для чтения
property Tablndex: Integer;
Страница может временно "исчезнуть" из блокнота, а затем опять появиться. Для этого применяется свойство
property TabVisible: Boolean;