Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
delphi.pdf
Скачиваний:
191
Добавлен:
24.02.2016
Размер:
6.84 Mб
Скачать

Рисунок 9.61. Вкладки размещены в несколько рядов

А можно ли получить страницы без закладок? Да, для этого в компонентах TTabSheet нужно установить свойство TabVisible в значение False. Заметьте, это свойство не управляет видимостью вкладки, а влияет лишь на ее заголовок — закладку. Переключение между такими страницами становится вашей заботой и осуществляться программно.

В реальной задаче может потребоваться отследить переключения между страницами. Для этого в компоненте PageControl предусмотрены события OnChanging и OnChange. Первое событие — это запрос на переключение страницы, а второе — уведомление о том, что страница переключилась.

9.5.2. Закладки без страниц

Для создания многостраничных окон диалога иногда используется еще один компонент — TabControl, который расположен в палитре компонентов по соседству с компонентом PageControl (рисунок 9.62).

Рисунок 9.62. Компонент TabControl

Характерные свойства компонента TabControl описаны в таблице 9.18.

489

Свойство

Align DockSite HotTrack Images MultiLine

MultiSelect

OwnerDraw

Описание

Способ выравнивания компонента в пределах содержащего компонента.

Определяет, используется ли компонент TabControl для стыковки других компонентов.

Подсвечивает закладку при наведении на нее указателя мыши.

Список значков, отображаемых на закладках. Каждая закладка получает значок в соответствии со своим порядковым номером.

Располагает закладки в несколько рядов.

Если равно значению True, то пользователь может выбрать сразу несколько закладок, удерживая клавишу Ctrl. Работает только в том случае, если свойство

Style содержит значение tsFlatButtons или tsButtons.

Позволяет программно рисовать закладки в обработчике события OnDrawTab. Если свойство OwnerDraw равно значению False, то закладки имеют стандартный вид и событие OnDrawTab не происходит.

RaggedRight

ScrollOpposite

Если равно значению True, то при включенном режиме MultiLine закладки не выравниваются на ширину компонента.

Способ организации рядов закладок. Если равно значению False, то все ряды расположены вместе, например вверху. Если равно значению True, неактивные ряды переносятся на другую сторону компонента, например вниз.

Style

Tabs

TabIndex

TabPosition

TabWidth,

TabHeight

OnChange

OnChanging

OnDrawTab

OnGetImageIndex

OnGetSiteInfo

Стиль закладок: tsTabs — обычные трехмерные закладки, tsFlatButtons — плоские закладки, tsButtons — закладки в виде кнопок.

Закладки в виде списка строк.

Номер выбранной закладки. Если ни одна закладка не выбрана, то значение свойства равно -1.

Местоположение закладок: tpTop — сверху, tpRight — справа, tpLeft — слева, tpBottom — снизу.

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

Происходит после смены закладки. Происходит перед сменой закладки.

Происходит при рисовании закладки на экране. Требует, чтобы свойство OwnerDraw содержало значение True.

Обработчик этого события должен вернуть номер значка для отображаемой закладки.

Происходит, когда у компонента запрашивается место для стыковки.

Таблица 9.18. Важнейшие свойства и события компонента TabControl

Компонент TabControl — это фактически одна страница с множеством закладок. Компонент применяется в том случае, если страницы имеют одинаковый вид, а их переключение влечет лишь изменение отображаемых данных. А ведь так произошло с нашими экзаменационными билетами —

490

все страницы содержали по одному единственному компоненту

RadioGroup.

Каждая вкладка в компоненте PageControl потребляет системные ресурсы. Используя компонент TabControl вместо компонента PageControl, мы значительно снизим потребление оперативной памяти в нашем последнем примере, правда, за счет времени и сил, затраченных на программирование. Давайте не поленимся и переделаем пример с экзаменационными билетами так, чтобы в нем использовался компонент TabControl.

Шаг 12. Удалите из формы ExamForm компонент PageControl и поместите на его место компонент TabControl.

Рисунок 9.63. Компонент TabControl заменил в форме компонент PageControl

Шаг 13. В окне свойств выберите свойство Tabs и щелкните кнопку с многоточием. На экране появится редактор строк.

491

Рисунок 9.64. Список закладок для компонента TabControl

Шаг 14. Введите названия закладок и щелчком кнопки OK закройте окно. Закладки появятся на экране (рисунок 9.65).

Рисунок 9.65. В компоненте TabControl созданы три закладки

Шаг 15. Теперь внутрь компонента TabControl поместите группу взаимоисключающих переключателей и придайте ей соответствующие размеры и положение (рисунок 9.66).

492

Рисунок 9.66. Группа переключателей RadioGroup1 заготовлена для экзаменационного вопроса с вариантами ответа

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

На этом визуальная часть проектирования закончена. Все остальное придется программировать вручную.

Шаг 16. Сначала нужно позаботится о хранении содержания вопросов и их ответов, поэтому добавьте следующие описания в текст модуля MainUnit, поместив их перед всеми обработчиками событий:

const

Questions: array[0..2] of string = ('Правильным является выражение', 'Когда лед в воде тает', 'Чтобы разбавить кислоту, нужно');

Answers: array[0..2, 0..2] of string = (('sin 50° < cos 50°',

'sin 50° > cos 50°', 'sin 50° = cos 50°'),

('уровень воды поднимается', 'уровень воды понижается', 'уровень воды остается неизменным'), ('добавить кислоту в воду', 'добавить воду в кислоту', ''));

ValidAnswers: array[0..2] of Integer = (1, 2, 0);

Шаг 17. Для промежуточного хранения ответов пользователя воспользуемся инициализированной переменной-массивом:

493

var

UserAnswers: array[0..2] of Integer = (0, 0, 0);

Шаг 18. Значения элементов этого массива должны изменяться, когда пользователь выбирает ответ, поэтому создайте компоненту RadioButton1 обработчик события OnClick:

procedure TExamForm.RadioGroup1Click(Sender: TObject); begin

UserAnswers[TabControl1.TabIndex] := RadioGroup1.ItemIndex; end;

Шаг 19. При смене закладки должен изменяться вопрос экзаменационного билета и возможные варианты ответов. Для этого создайте в компоненте

TabControl1 обработчик события OnChange:

procedure TExamForm.TabControl1Change(Sender: TObject); var

I: Integer; begin

// Отобразить новый вопрос

RadioGroup1.Caption := Questions[TabControl1.TabIndex];

//Стереть прежние варианты ответа

RadioGroup1.Items.Clear;

//Добавить новые варианты ответа в группу переключателей for I := 0 to 2 do

if Length(Answers[TabControl1.TabIndex, I]) > 0 then RadioGroup1.Items.Add(Answers[TabControl1.TabIndex, I]);

//Установить ответ, принимаемый по умолчанию

RadioGroup1.ItemIndex := UserAnswers[TabControl1.TabIndex];

end;

Шаг 20. Все готово? Не совсем. Нужно заполнить компонент RadioGroup1 данными первого билета при появлении формы на экране. Проще всего это можно сделать, вставив вызов метода TabControl1Change в обработчик события создания формы:

procedure TExamForm.FormCreate(Sender: TObject); begin

TabControl1Change(TabControl1);

end;

Шаг 21. Последний штрих — доработка метода выставления оценки:

procedure TExamForm.ResultButtonClick(Sender: TObject); const

MarkText: array[0..3] of string =

('Неудовлетворительно', 'Удовлетворительно', 'Хорошо', 'Отлично');

var

494

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]