10. Использование компонента TDBGrid

 

10.1. Понятие столбцов TDBGrid *

10.2. TDBGrid и динамические свойства столбцов *

10.3. Редактор столбцов TDBGrid, постоянные столбцы и компонент TDBGridColumns *

10.3.1. Постоянные и динамические столбцы *

10.3.2. Работа с редактором столбцов *

10.3.3. Изменение свойств постоянных столбцов во время выполнения. TDBGridColumns как набор столбцов *

10.3.4. Другие свойства набора столбцов TDBGridColumns *

10.3.5. "Пустые" постоянные столбцы *

10.3.6. Формирование списка возможных значений столбца *

10.4. Управление видом и поведением TDBGrid *

10.5. Редактирование наборов данных непосредственно из TDBGrid *

10.5.1. Добавление записей *

10.5.2. Корректировка *

10.5.3. Возникновение исключений при добавлении и корректировке записей в TDBGrid *

10.6. Определение текущего столбца во время выполнения программы и проверка правильности индекса *

10.7. Изменение порядка следования столбцов в TDBGrid *

10.7.1. Изменение порядка следования столбцов во время разработки приложения *

10.7.2. Изменение порядка следования столбцов во время выполнения приложения *

10.8. Управление отображением данных в TDBGrid *

10.9. Обработка иных событий в DBGrid *

10.9.1. Перемещение между ячейками TDBGrid *

10.9.2. Действия с мышью и клавиатурой в момент, когда TDBGrid обладает фокусом управления *

10.10. Работа с компонентом TDBCtrlGrid *

10. Использование компонента TDBGrid

10.1. Понятие столбцов TDBGrid

Компонент TDBGrid используется для показа содержимого записей НД в табличном формате, когда строки соответствуют записям НД, а столбцы -полям записи (рис. 10 1.):

Свойство DataSource компонента TDBGrid содержит имя компонента TDataSource, который ссылается на соответствующий НД (компоненты TTable или TQuery). Изменяя значение свойства DataSource во время выполнения, можно использовать один компонент TDBGrid для показа содержимого различных наборов данных. При продуманном сценарии диалога с пользователем и интерфейса приложения это может существенно минимизировать объем и конструктивную сложность создаваемых приложений.

Для определения состава столбцов в TDBGrid можно использовать редактор столбцов (Columns Editor). В этом случае используются только те столбцы, которые созданы редакторе столбцов компонента TDBGrid, и принимаются во внимание только их характеристики. Порядок следования столбцов в сетке TDBGrid определяется порядком следования определений столбцов редакторе столбцов.

Если редактор столбцов не использовался, берутся поля (компоненты TField), объявленные при помощи редактора полей НД. При этом вид столбцов определяется соответствующими характеристиками компонентов TField, a порядок следования столбцов - порядком их определении

В случае когда для НД компоненты TField не создавались порядок следования полей и их характеристики соответствуют тем что были заданы при определении структуры записи данной ТБД в момент создания таблицы Заметим что умалчиваемыи порядок следования столбцов в TDBGrid можно изменить лишь при помощи редактора полем или редактора столбцов

Пример В ТБД teachers db находятся сведения о сотрудниках кафедры С данной таблицей в приложении ассоциирован набор данных Table1 Для определения полей в этом НД редактор полей не использовался следовательно по умолчанию для НД Table1 используются все поля объявленные в структуре записи таблицы БД teachers db Пусть порядок следования столбцов в компоненте TDBGrid связанным с НД Table1 взят по умолчанию и совпадает с порядком следования полей в записи таблицы teachers db (рис 10 2 )

Для того чтобы изменить местоположение столбца Doljnost с 3-го на 2-е необходимо

1 Вызвать редактора полей для набора данных Table1

2 Явно добавить все поля в редакторе полеи

3 В инспекторе объектов выбрать поле Doljnost и изменить значение свойства Index с 2 на 1 или перетащить поле мышью на нужное место в окне редактора полей

Чтобы изменить заголовки столбцов в TDBGrid, следует в инспекторе объектов нужным образом изменить значения свойств Display'Label для каждого поля(рис 10 3)

10.2. TDBGrid и динамические свойства столбцов

В том случае когда столбцы таблицы (т е поля записи) определены с использованием редактора полей как компоненты типа TField столбцы показываются в сетке TDBGrid в том состоянии которое определяется их текущими свойствами Если то или иное свойство столбца можно менять в процессе выполнения приложения эти изменения немедленно отобразятся в TDBGrid Например в ходе выполнения можно менять ширину столбца (свойство компонента TField Display Width) его видимость (Visible) возможность редактирования значения столбца (ReadOnlv) порядковый номер (Index) заголовок столбца (Display Label)

Пример Воспользуемся формой из предыдущего примера и добавим в нее компонент CheckBoxl Установим свойство Visible компонента Table lUchStepen (поте Ученая степень"), равным свойству CheckBoxl Checked Тогда отметка CheckBoxl приведет к визуализации столбца 'Ученая степень в таблице TDBGrid (рис 10 4 а), а снятие отметки- к его исчезновению' (рис 1046)

procedure TFormX.CheckBox1Click(Sender: TObject);

begin

Table1UchStepen.Visible := CheckBox1.Checked;

end;

Здесь мы имеем дело с настраиваемым компонентом TDBGnd Многие свойства TDBGnd могут быть переустановлены во время выполнения приложения Это может придать самому приложению значительную гибкостьассический пример - возможность выбора пользователем порядка сортировки записей НД и порядка их расположения в TDBGnd

Пример. Пусть таблица teachers db ассоциирована с НД Table 1, записи которого показываются в компоненте DBGndl Пусть у таблицы teachers db имеются индексы по полям 'TabNum' (уникальный, установлен в таблице по умолчанию) 'Doljnosf, 'ПО', 'UchStepen,FIO' Разместив в форме компонент TRadioGroup, сделаем выбранной по умолчанию радиокнопку с индексом 0 (соответствующую индексу по полю 'TabNum') и опишем обработчик события выбора одной из радиокнопок

procedure TForm!.RadioGrouplClick(Sender: TObject);

begin

WITH Table1 do begin

CASE RadioGroupl.ItemIndex OF

0 : begin

IndexFieldNames := 'TabNum';

Table1TabNum.Index := 0;

Table1Doljnost.Index := 2;

Table1FIO.Index := 1;

Table1UchStepen.Index := 3;

end;

1 : begin

IndexFieldNames := 'Doljnosf;

Table1Doljnost.Index := 0;

TabielFIO.Index := 1;

Table1UchStepen.Index := 2,Table1TabNum Index := 3;

end;

2 : begin

IndexFieldNames := 'FIO';

Table1FIO.Index := 0;

Table1UchStepen.Index := 1;

Table1Doljnost.Index := 2;

Table1TabNum.Index := 3;

end;

3 : begin

IndexFieldNames := 'UchStepen';

Table1UchStepen.Index := 0;

Table1FIO.Index := 1;

Table1Doljnost.Index := 2;

Table1TabNum.Index := 3;

end;

END; {case}

END; {with}

end;

Тогда при выборе любой из радиокнопок произойдет переключение текущего индекса и порядка следования столбцов в TDBGnd (рис 105, 106)

Заметим, что можно было бы написать обработчик и так:

procedure TForm!.RadioGrouplClick(Sender: TObject) ;

begin

WITH Table1 do begin

CASE RadioGroupl.Itemlndex OF

0 : begin

IndexFieldNames := 'TabNum';

Table1TabNum.Index := 0;

end;

1 : begin

IndexFieldNames := 'Doljnost;

Table1Doljnost.Index := 0;

end;

2 : begin

IndexFieldNames := 'FIO';

Table1FIO.Index := 0;

end;

3 : begin

IndexFieldNames := 'UchStepen';

Table1UchStepen.Index := 0;

end;

END; {case}

END; {with}

end;

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

10.3. Редактор столбцов TDBGrid, постоянные столбцы и компонент TDBGridColumns

10.3.1. Постоянные и динамические столбцы

Когда свойства столбцов компонента TDBGrid определяются с помощью свойств компонентов TField, созданных в редакторе полей связанного с TDBGrid НД, всякое изменение свойства в TField ведет к изменению соответствующего свойства столбца. Например, изменение свойства Display Label у компонента Table1FIO для рассмотренного выше примера приведет к соответствующему изменению заголовка столбца в TDBGrid.

Связка "Компонент TField - Столбец DBGrid" хороша до тех пор, пока не возникнет необходимость а) не привязывать столбец к определенному полю ТБД; б)установить характеристики столбца в TDBGrid таким образом, чтобы они не изменялись при изменении свойств TField, даже если столбец и отображает некоторое поле из связанного с TDBGrid НД.

В этом случае в редакторе столбцов, определяются так называемые постоянные столбцы. Их можно определить, выбрав элемент меню Columns Editor во всплывающем по нажатию правой кнопки мыши меню или нажав кнопку в строке свойства TDBGrid Columns в инспекторе объектов. И тот, и другой путь приводит к активизацииредвктора столбцов компонента TDBGrid.

Заметим, что столбцы TDBGrid, основанные на использовании компонентов TField, называются динамическими столбцами.

10.3.2. Работа с редактором столбцов

Вызвать редактор столбцов можно, проделав следующие действия:

1. Выбрать в форме компонент TDBGrid при помощи мыши;

2. Нажать правую кнопку мыши;

3. В появившемся всплывающем меню выбрать элемент Columns Editor.

В появившемся диалоговом окне Т DBGrid Columns Editor устанавливаются свойства постоянных столбцов. Вначале список столбцов пуст. Для того чтобы добавить столбец, нужно нажать кнопку Add. Тогда будет создан столбец, не связанный ни с каким полем набора данных (рис. 10.7.а)

а) б)

Рис 10.7 а) столбец не связан с конкретным полем набора данных, б) столбец связан с полем Doljnost

Чтобы поставить такому столбцу в соответствие какое-либо поле НД, следует в инспекторе объектов раскрыть список в свойстве Field Name и выбрать нужное поле В этом случае столбец будет назван так же, как поле (рис. 10.7.6).

Когда нужно показывать в TDBGrid столбцы, соответствующие всем или большинству полей набора данных, лучше нажать кнопку AddAllFieldes. Тогда в список полей TDBGrid будут включены столбцы, соответствующие всем полям НД. После этого при помощи кнопки Delete следует удалить определения столбцов, которые не должны показываться в TDBGrid. Используя кнопки Move Up и Move Down, можно изменить порядок следования текущего столбца (рис. 10.8.а, б).

Свойства столбца устанавливаются в инспекторе объектов. Они определяют особенности отображения столбца в TDBGrid.

а) б)

Рис. 10.8. а) до изменения и б) после изменения порядки следования столбцов

Aligment

Определяет выравнивание значений в столбце. По умолчанию TField. Aligment.

BultonStyle

Определяет тип кнопки, появляющейся в столбце в режиме редактирования: cbsAuto (по умолчанию) - автоматическая установка (показывает кнопку раскрытия выпадающего списка возможных значений, если столбец может принимать лишь одно из значений, определенных связью с иным НД, или списком свойства PickList); cbsEllipse - показывает кнопку (...) в столбце справа; обработчик нажатия кнопки соответствует обработчику события OnEditButtonCUck; cbsNone - никакой кнопки в столбце нет.

Color

Определяет цвет фона столбца. По умолчанию TDBGrid.Color.

DropDownRows

Если столбцу назначен выпадающий список возможных значений (посредством связи с другим НД или в свойстве PickList}, определяет число строк в нем. По умолчанию равно 7.

FieldName

Определяет поле ТБД, ассоциированное с данным постоянным столбцом. Может быть пустым (см. "Пустые постоянные столбцы").

Readonly

Определяет возможность редактирования столбца из TDBGrid [True) или невозможность этого {False, по умолчанию).

Width

Определяет ширину столбца в пикселах. По умолчанию значение извлекается из TField. DisplayWidth, где, заметим, ширина дается в символах.

Font

Определяет тип, размер и цвет шрифта для вывода значений в столбце. По умолчанию TDBGrid.Font

PickList

В случае, если для занесения значений в столбец используется раскрывающийся список возможных значений (кроме случая связи с иным НД), определяет этот список

Свойство Title определяет заголовок постоянного столбца:

Подсвойство

Назначение

Aligment

Определяет выравнивание заголовка. По умолчанию -влево.

Caption

Определяет текст заголовка. По умолчанию TField. DisplayLabel или имя поля ТБД.

Color

Определяет цвет фона заголовка. По умолчанию TDBGrid.FixedColor.

Font

Определяет тип, размер и цвет шрифта. По умолчанию TDBGrid.TitleFont.

Пример. Используя НД таблицы teachers.db из предыдущих примеров, создадим постоянные столбцы в TDBGrid, с которым связан с НД, и установим различные свойства отображения этих столбцов (рис. 10.9)

Этот пример показывает, что характеристики столбцов в TDBGrid не должны совпадать друг с другом и каждый столбец может иметь свои собственные, уникальные характеристики.

10.3.3. Изменение свойств постоянных столбцов во время выполнения. TDBGridColumns как набор столбцов

Обратиться к конкретному постоянному столбцу компонента TDBGrid через его свойства можно как к TDBGndl .Columns.Itemsp] или как к TDBGrid l .Columns[i], где i принадлежит диапазону [0.. DBGridl.Columns.Count-1].

Свойство property Columns: TDBGridColumns; является набором столбцов TDBGrid. Методы TDBGrid. Columns мы рассмотрим ниже. В данный момент нас интересует возможность обращения к столбцам. Эту возможность обеспечивает массив property Items[Index: Integer]: TColumn; который доступен только во время выполнения программы.

Каждый i-ый столбец массива Items, в свою очередь, имеет свои собственные свойства и методы. Кратко перечислим их:

property Alignment: TAlignment; - определяет выравнивание;

property ButtonStyle: TColumnButtonStyle; - определяет тип кнопки, назначенной столбцу (см. выше п.10.3.2); TColumnButtonStyle = (cbsAuto, cbsEllipsis, cbsNone);

property Color: TColor; - определяет цвет фона;

property DropDownRows: Integer; - определяет число строк в выпадающем списке возможных значений столбца;

property Field: TField; - ссылается на компонент TField, связанный со столбцом;

property FieldName: String; - определяет имя поля, связанного со столбцом;

property Font: TFont; - определяет шрифт для отображения содержимого столбца, его размер и цвет;

property PickList: TStrings; - определяет список возможных значений столбца;

property ReadOnly: Boolean; - разрешает (False) или запрещает (True) редактирование значений в столбце;

property Title: TColumnTitle; - определяет свойства и методы для работы с заголовком столбца:

property Alignment: TAlignment; - определяет выравнивание;

property Caption : String; - содержит текст заголовка столбца;

property Color: TColor; - определяет цвет фона заголовка столбца;

property Font: TFont; - определяет шрифт заголовка столбца, его размер и цвет;

function DefaultFont: TFont; - восстанавливает умалчиваемый шрифт;

function DefaultCaption: String; - восстанавливает умалчиваемый текст заголовка;

function DefaultColor: TColor; - восстанавливает умалчиваемый цвет заголовка;

procedure RestoreDefaults; - восстанавливает все умалчиваемые свойства заголовка столбца;

property Width: Integer; - определяет ширину столбца в пикселах;

function DefaultWidth: Integer; - восстанавливает умалчиваемую ширину столбца;

function DefaultReadOnly: Boolean; - восстанавливает умалчиваемое значение ReadOnly столбца;

function DefaultColor: TColor; - восстанавливает умалчиваемый цвет столбца;

function DefaultFont: TFont; - восстанавливает умалчиваемый шрифт столбца;

procedure RestoreDefaults; - восстанавливает все умалчиваемые свойства столбца.

Пример. Введем в приложение, рассмотренное выше, возможность динамического изменения свойств постоянных столбцов TDBGrid. Для этого разместим в форме компоненты обеспечивающие диалоги выбора шрифта и цвета - FontDialog! и ColorDialog соответственно, а также экранные кнопки, нажатие которых инициирует изменения свойств постоянных столбцов (рис. 10.10).

Рис 10.10. Форма с кнопками, нажатие которых реализует изменение шрифта, фона у столбца и т заголовка столбца

Опишем следующие обработчики событий нажатия экранных кнопок:

// Обработчик нажатия кнопки "Шрифт столбцов" Вызывает диалог выбора шрифта и устанавливает выбранный шрифт для всех столбцов

procedure TForm1.AssigningColumnsFontButtonClick(Sender: TObject) ;

var i : Integer;

begin

// в диалоге выбора шрифта текущим будет шрифт 0-го столбца

FontDialog1.Font := DBGrid1.Columns.Items [0].Font;

IF FontDialog1.Execute THEN

FOR i := 0 TO DBGrid1.Columns.Count - 1 do

DBGrid1.Columns.Items[i].Font := FontDialog1.Font;

end;

// Обработчик нажатия кнопки "Шрифт заголовков" Вызывает диалог выбора шрифта и устанавливает выбранный шрифт для заголовков всех столбцов

procedure TForml.AssignFontToColumnsCaptionsButtonClick(Sender: TObject) ;

var i : Integer;

begin

// в диалоге выбора шрифта текущим будет шрифт заголовка 0-го столбца

FontDialog1.Font := DBGrid1.Columns.Items[0].Title.Font;

IF FontDialog1.Execute THEN

FOR 1 := 0 TO DBGrid1.Columns.Count - 1 do

DBGrid1.Columns.Items[i].Title.Font := FontDialog1.Font;

end;

// Обработчик нажатия кнопки "Шрифт столбца" Вызывает диалог выбора шрифта и устанавливает выбранный шрифт для текущего столбца, индекс которого определяется как DBGrid1.Selectedlndex

procedure TForm1.AssignFontToSelectedColumnButtonClick(Sender: TObject) ;

begin

// в диалоге выбора шрифта текущим будет шрифт текущего столбца

FontDialog1.Font := DBGrid1.Columns.Items[DBGrid1.Selectedlndex].Font;

IF FontDialog1.Execute THEN

DBGrid1.Columns.Items[DBGrid1.Selectedlndex].Font :=FontDialog1.Font;

end;

// Обработчик нажатия кнопки "Фон столбца" Вызывает диалог выбора цвета и устанавливает выбранный цвет для фона текущего столбца, индекс которого определяется как DBGrid1.Selectedlndex

procedure TForm1.AssignColorToSelectedColumnButtonClick(Sender: TObject) ;

begin

// в диалоге выбора шрифта текущим будет шрифт текущего столбца

ColorDialog1. Color := DBGrid1. Columns. Items [DBGrid1. Selectedlndex] .Color;

IF ColorDialog1.Execute THEN

DBGrid1.Columns.Items[DBGrid1.Selectedlndex].Color := ColorDialog1.Color;

end;

// Обработчик нажатия кнопки "Фон заголовка столбца" Вызывает диалог выбора цвета и устанавливает выбранный цвет для фона заголовка текущего столбца, индекс которого определяется как DBGrid1.Selectedlndex

procedure TForm1.AssignColorToSelectedColumnsTitleButtonClick ( Sender: TObject) ;

begin

// в диалоге выбора шрифта текущим будет шрифт заголовка текущего столбца

ColorDialog1.Color :=

DBGrid1.Columns.Items[DBGrid1.Selectedlndex].Title.Color,

IF ColorDialog1.Execute THEN

DBGrid1.Columns.Items[DBGrid1.Selectedlndex].Title.Color := ColorDialog1.Color;

end;

Пример динамического изменения характеристик столбцов показан на рис 10.11.

10.3.4. Другие свойства набора столбцов TDBGridColumns

Кроме рассмотренных выше, свойство TDBGrid. Columns обладает иными полезными свойствами и методами:

property State: TDBGridColumnsState;

где TDBGridColumnsState = (csDefault, csCustomized);

Это свойство дает возможность определить во время выполнения, имеются ли в данном TDBGrid постоянные столбцы Возможные значения:

csDefault - столбцы TDBGrid формируются на основе свойств полей ТБД;

csCustomized - в TDBGrid присутствуют постоянные столбцы.

function Add: TColumn:

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

procedure RebuildColumns;

Удаляет все существующие столбцы, затем, пользуясь взятой из ТБД информацией о полях, создает столбцы заново с умалчиваемыми свойствами. Если TDBGrid не ассоциирован ни с одним компонентом-источником данных TDataSource, или последний не ассоциирован ни с каким НД, выполнение данного метода приведет к уничтожению столбцов в TDBGrid.

procedure RestoreDefaults;

Возвращает всем постоянным столбцам их свойства, принятые по умолчанию.

От описанного выше метода RebuildColumns метод RestoreDefaults отличается тем, что если в TDBGrid есть постоянные столбцы, не ассоциированные ни с каким полем, эти столбцы не уничтожаются.

10.3.5. "Пустые" постоянные столбцы

Постоянный столбец в TDBGrid не обязательно должен быть ассоциирован с каким-либо полем набора данных. В этом случае свойство столбца FiledName остается незаполненным. Такие столбцы называются пустыми. В них можно выводить какую-либо информацию, основываясь на информации из действительно существующих полей набора данных. Например, из поля набора данных, содержащего фамилию, имя и отчество, можно вывести информацию в 3 "пустых" столбца, содержащих соответственно фамилию, имя и отчество в отдельности.

Другим предназначением пустого столбца является вывод информации по требованию. Например, графические поля, если их выводить для каждой записи в отдельном столбце TDBGrid или даже для текущей записи с помощью отдельного компонента TDBImage, требуют существенных временных затрат для вывода. Поэтому поступают так: устанавливают свойство пустого столбца ButtonSty/e в значение cbsEllips и кодируют обработчик события OnEditButtonClick, которое наступает, когда нажата кнопка (...) в конкретной строке пустого столбца. Заметим, что кнопка становится видна только в режиме редактирования столбца. В обработчике события OnEditButtonClick предусматривают вызов формы, показывающей содержимое графического поля текущей записи, или активизацию компонента TDBImage, расположенного на той же форме, что и TDBGrid. Аналогичным образом можно поступать с мемо-полями набора данных.

Используя механизм кнопки (...), можно также выводить форму, показывающую записи дочерних НД. Также можно вызывать формы для расшифровки того или иного значения. Например, при показе рассчитанного значения "на руки" для приложения расчета заработной платы с помощью кнопки можно вызвать форму, в которой расшифровывается, какая сумма начислена данному работнику, какова сумма премий, как производились вычеты, налогообложение и пр.

Для рассмотренного выше примера приложения введем пустой столбец "Столбец без поля", назначим ему кнопку и напишем обработчик, констатирующий, что данный сотрудник работает в конкретной должности (рис. 10.12).

procedure TForm!.DBGrid1EditButtonClick(Sender: TObject);

begin

WITH Table1 do

ShowMessage(FieldByName('FIO').Value + ' - ' + FieldByName('Doljnosf).Value) ;

end;

10.3.6. Формирование списка возможных значений столбца

Если значения постоянного столбца должны выбираться из некоторого фиксированного множества и Вы хотите получать список значений при редактировании столбца непосредственно в TDBGrid, этот список должен содержаться в свойстве PickList данного постоянного столбца.

При этом возможны 2 варианта - список возможных значений столбца является фиксированным и переменным.

Вариант 1. Список возможных значений столбца является фиксированным, т.е. не изменяется во времени. Тогда достаточно на этапе конструирования программы заполнить список свойства PickList (этот список имеет тип TStrings) постоянного столбца. В свойство ButtonSty/e необходимо установить значение cbsAuto. Тогда Delphi, обнаружив, что список PickList заполнен, автоматически будет помещать в столбце при редактировании его ячейки кнопку типа ComboBox (стрелка вниз).

Например, пусть для рассматриваемого примера сотрудники кафедры могут обладать учеными степенями доктора физико-математических наук (д.ф.-м.н.), доктора технических наук (д.т.н.), кандидата физико-математических наук (к.ф.-м.н.) и кандидата технических наук (к.т.н.). Предположим, что на работу не принимаются обладатели иных ученых степеней (например, доктора и кандидаты химических или социологических наук). Таким образом, список возможных значений столбца "Уч. степень" состоит из 4 значений (рис. 10.13).

При работе приложения, если мы корректируем ячейку столбца "Уч. степени", на экране появляется кнопка типа "Стрелка вниз" (рис.10.14).

Нажатие данной кнопки приведет к появлению выпадающего списка с фиксированными значениями (рис. 10.15).

При этом выбор значения в списке приведет к копированию его в текущую ячейку столбца, и, если данный столбец связан с полем ТБД, к последующему запоминанию в качестве значения поля ТБД в текущей записи.

Заметим, что наличие выпадающего списка не препятствует пользователю занести в столбец и иную информацию (рис. 10.16).

Рассмотрим второй вариант, когда список возможных значении столбца не является фиксированным, т.е. может изменяться во времени. Почти всегда в

таком случае источником значений служит другая, справочная ТБД В процессе работы справочная ТБД может меняться, записи в ней могут корректироваться, добавляться или удаляться Все внесенные изменения должны отображаться в списке PickList для рассматриваемого столбца TDBGnd

Пусть для рассматриваемого примера список возможных должностей находится в ТБД "UCHSTEP DB" (в поле UchStepen) Тогда проблема решается, если при всякой активизации формы, на которой расположен TDBGnd с постоянным столбцом, произвести следующие действия

1 Очистить список PickList для постоянного столбца "Уч степени",

2 Поместить все значения из поля UchStepen таблицы БД "UCHSTEP DB" в список PickList для постоянного столбца "Уч степени"

procedure TForm1.FormActivate(Sender: TObject);

begin

DBGrid1.Columns.Items[3].PickList.Clear;

WITH Table2 do begin

First;

WHILE not EOF do begin

DBGrid1.Columns.Items[3].PickList.Add (FieldByName('UchStepen').Value) ;

Next;

END; {while}

END; {with}

end;

Результат работы показан на рис 1017

ЗАМЕЧАНИЕ 1. Поле UchStepen в ТБД "UCHSTEP DB" должно быть уникальным, иначе в списке PickList появятся дублирующие друг друга значения Если поле, по которому строится PickList, неуникально, нужно программно предусмотреть дополнительный анализ дублирования в списке PickList

ЗАМЕЧАНИЕ 2. Аналогичного или сходного результата можно добиться путем использования поля, возвращающего значение (lookup-поля) Более подробно см раздел "Использование компонента TField"

ЗАМЕЧАНИЕ 3. Если таблица-справочник содержит больше 10-15 записей, в список PickList ее заносить нерационально, поскольку пользователю весьма трудно будет искать нужное значение К другим недостаткам описываемого подхода можно отнести то, что список PickList не позволяет редактировать таблицу-источник (представим, что в процессе работы с кадровым составом кафедры нам понадобилось внести в справочник ученых степеней степень "кандидата философских наук")

Два этих обстоятельства делают работу с выпадающим списком не очень удобной Поэтому, на взгляд автора, более рационально не формировать список PickList вручную или программно, а установить в свойство ButtonStyle постоянного поля значение cbsElhps и написать в обработчике нажатия кнопки (. .) OmtButtonChck вызов модальной формы, содержащей НД справочника После этого следует определить код занесения выбранного в справочнике значения в текущую ячейку постоянного столбца. Пример Для рассмотренной выше формы

1 Добавим в приложение форму Form2 (рис. 10.18), содержащую компонент TDBGnd, в котором показываются значения из ТБД "UCHSTEP DB" с возможностью их корректировки, а также 2 экранные кнопки - "Выбрать" (со свойством Moda/Result = mrOk) и "Отменить" (со свойством ModalResult = mrCancel);

2 Установим у постоянного столбца "Уч степень" в свойство ButtonStyle значение cbsElhps,

3. Напишем такой обработчик нажатия кнопки:

procedure TForm1.DBGridlEditButtonClick(Sender: TObject);

begin

// модальный вызов справочной ТБД "Ученые степени"

Form2.ShowModal;

// Если выбрана клавиша с модальным результатом mrOk // (т.е. клавиша "Выбрать" в Form2)

IF Form2.ModalResult = mrOK THEN

begin

// если НД сотрудников кафедры не находится в режиме dsEdit или dslnsert, переводим НД в режим dsEdit,

// поскольку иначе мы не сможем изменить значения поля UchStepen

IF Tablel.State = dsBrowse THEN TableI.Edit;

// производим присваивание значения поля

Formi.Tablel.FieldByName('UchStepen').Value := Form2.Tablel.FieldByName('UchStepen').Value;

end;

end;

Результат работы показан на рис. 10.19.

Заметим, что при выходе из обработчика мы не выполняем метод Tablel. Post, т.е. оставляем НД сотрудников кафедры в одном из режимов корректировки с тем, чтобы пользователь затем смог сам либо отменить внесение изменений в TDBGrid (клавишей Esc) или подтвердить внесение изменений (перейдя на другую запись в TDBGrid).

В вызываемой форме (Form2) можно добавлять, изменять и удалять записи, прежде чем осуществить выбор.

Заметим также, что в Form2 нужно предусмотреть ситуацию, когда нажата кнопка "Выбрать" или "Отменить", а НД, связанный с ТБД "UCHSTEP.DB", остался в одном из режимов редактирования. Например, в этом случае можно не производить выбора по нажатию кнопки "Выбрать" в обработчике события OnEditButtonClick формы Formi и принудительно переводить НД Form2.Table2 в режим dsBrowse с потерей последних неподтвержденных изменений (выполняя метод Cancel):

procedure TFormI.DBGridlEditButtonClick(Sender: TObject);

begin

Form2.ShowModal;

IF Form2.Tablel.State о dsBrowse THEN

begin

Form2.Tablel.Cancel ;

ShowMessage('Изменения в справочнике не запомнены');

Exit;

end;

IF Form2.ModalResult = mrOK THEN

begin

IF Tablel.State = dsBrowse THEN TableI.Edit;

Form1.Tablel.FieldByName('UchStepen').Value :=Form2.Tablel.FieldByName('UchStepen').Value;

end;

end;

10.4. Управление видом и поведением TDBGrid

Свойство Options управляет видом и поведением TDBGrid во время выполнения. Это свойство состоит из группы логических опций, поэтому в инспекторе объектов оно помечено знаком (+). Чтобы получить доступ ко всем опциям, следует щелкнуть мышью на знаке (+). Тогда он преобразуется в знак (-) и будет раскрыт следующий список:

dgEditing

True (по умолчанию) разрешает редактирование, вставку и удаление записей непосредственно из TDBGrid. False запрещает указанные действия.

DgA IwaysShowEditor

True выбор поля означает его перевод в состояние редактирования. False (по умолчанию).- поле при его выборе не переводится автоматически в режим редактирования.

dgTitles

True (по умолчанию), показывает заголовки столбцов в TDBGrid.

False: заголовки столбцов не показываются.

Dglndicator

True (по умолчанию)- показывается индикатор текущей записи как самый левый серый столбец. Указатель в режиме dsBrowse - стрелка влево, в режиме dsEdit - символ I-Beam, в режиме dslnsert -звездочка.False: указатель текущей записи не показывается.

DgColumnsResize

True (по умолчанию).- возможно изменение ширины столбцов путем сдвига границы столбца в области заголовка. False: изменение ширины столбцов не допускается.

DgColLines

True (по умолчанию); показываются вертикальные линии-разделители между столбцами. Falsе: вертикальные разделители столбцов не показываются.

DgRowLines

True (по умолчанию).- показываются горизонтальные линии-разделители строк.

False: разделители строк не показываются.

dgTabs

True (по умолчанию): клавиша TAB используется для передвижения между столбцами текущей записи. False: клавиша TAB используется для выхода из TDBGrid.

DgRowSelect

True; инверсная полоса, показывающая текущую строку TDBGrid, отмечает всю строку.False (по умолчанию).' инверсная полоса отмечает только ячейку текущего столбца.

DgAIwaysShowSelection

True." Инверсная полоса для отметки текущей строки показывается в TDBGrid независимо от того, обладает он фокусом управления, или нет. False (по умолчанию); инверсная полоса видна только в то время, когда TDBGrid обладает фокусом упр-ния.

DgConfirmDelete

True (по умолчанию).' при удалении записи из TDBGrid (комбинация клавиш Ctrl+Del) запрашивается подтверждение удаления.

False: подтверждение удаления не запрашивается, запись удаляется немедленно.

Установка той или иной опции производится путем операции включения ее в множество Options или исключения из него:

// Включение-выключение показа заголовка столбцов TDBGrid

IF CheckBoxl.Checked THEN DBGrid1.Options := DBGridI.Options + [dgTitles]

ELSE DBGrid1.Options := DBGrid1.Options - [dgTitles];

// Включение-выключение показа вертикальных и горизонтальных разделительных линий DBGrid

IF CheckBox2.Checked THEN

DBGrid1.Options := DBGrid1.Options + [dgColLines, dgRowLines]

ELSE DBGrid1.Options := DBGrid1.Options - [dgColLines, dgRowLines];

10.5. Редактирование наборов данных непосредственно из TDBGrid

Записи НД, отображаемые в компоненте TDBGrid, можно добавлять, изменять или удалять, если одновременно выполняются следующие условия:

• свойство CanModify набора данных установлено в True;

• свойство Readonly компонента TDBGrid установлено в False.

Изменение записей внутри TDBGrid удобно в том случае, если НД состоит из небольшого числа полей или, если число полей в нем велико, требуется вводить или корректировать лишь некоторые из них. Преимущества такого подхода состоят и в том, что в этом случае нет необходимости вставки в приложение новой формы для изменения или добавления записи. Удобству работа с записями непосредственно из TDBGrid служит и наличие таких механизмов, как формирование выпадающего списка возможных значений в столбце -фиксированного или вновь формируемого из иного НД, а также наличие кнопки (...), по нажатию которой в обработчике события OnEditButtonClick можно, вообще говоря, делать что угодно, в том числе и вызывать форму для ввода или корректировки дополнительных полей.

10.5.1. Добавление записей

НД переводится в режим добавления dslnsert, если:

• пользователь нажал на клавиатуре клавишу Insert; в этом случае в TDBGrid вставляется пустая запись между текущей записью и предшествующей ей;

• пользователь нажал на клавиатуре кнопку "стрелка вниз", находясь на последней записи НД; в этом случае в конец НД добавляется новая запись.

После этого пользователь тем или иным способом должен заполнить поля новой записи. Запоминание добавленной записи в ТБД (с автоматической выдачей метода Post) производится при переходе курсора НД на другую запись в компоненте TDBGrid. Отмена добавления новой записи (с автоматической выдачей метода Саncel) производится, если пользователь нажмет на клавиатуре клавишу Esc.

10.5.2. Корректировка

НД переводится в режим добавления dsEdit, если пользователь, находясь в ячейке TDBGrid, осуществил ввод любого символа.

Если ввод символа не осуществлен, то НД остается в режиме dsBrowse. При использовании в постоянном столбце TDBGrid списка возможных значений

НД остается в режиме dsBrowse и после показа в корректируемой ячейке кнопки (...) или кнопки раскрытия комбинированного списка, и в момент перемещения по списку, заданному свойством PickList или содержащемуся в иной форме. НД переходит в режим dsEdit только после ввода значения, выбранного из списка, в ячейку TDBGrid.

10.5.3. Возникновение исключений при добавлении и корректировке записей в TDBGrid

Возникновение исключений при добавлении или корректировки записей в компоненте TDBGrid чаще всего связано с нарушением уникальности первичного индекса или незаполнения значением поля, для которого установлено требование обязательного ввода значения. В этом случае возбуждается исключение класса EDBEngineError с сообщением 'Key Violation ' или подобным. Возникновение такого исключения не приводит к фатальным последствиям для приложения, но при этом происходит отказ от запоминания записи в ТБД. Запись остается в том режиме, в котором она была на момент попытки автоматической выдачи метода Post - в режимах dslnsert или dsEnter. Пользователю остается либо исправить значение в ключевом поле (или ввести значение в поле, помеченное как обязательное к заполнению, и т.д.), либо отказаться от запоминания записи.

10.6. Определение текущего столбца во время выполнения программы и проверка правильности индекса

Компонент TDBGrid обладает рядом методов и свойств, которые позволяют:

а) обращаться к полю TField, ассоциированному с текущим столбцом TDBGrid;

б) проверять правильность обращения к тому или иному столбцу TDBGrid.

Свойство property SelectedField: TField; позволяет обратиться к полю, ассоциированному с текущим столбцом в TDBGrid. Поскольку свойство имеет тип TField, можно использовать все свойства и методы компонента TField.

Пример. Пусть произведен двойной щелчок мышью по некоторой ячейке TDBGrid. Если текущее поле - Doljnost, его значение записывается в компонентEdit1 с помощью такого обработчика события OnDblClick:

procedure TForm!.DBGrid1DbiClick(Sender: TObject);

begin

IF DBGrid1.SelectedField.FieldName = 'Doljnost' THEN Editl.Text := DBGrid1.SelectedField.Text ELSE Editl.Text :=";

end;

Свойство property Selectedlndex: Integer; возвращает номер поля, ассоциированного с текущим столбцом в TDBGrid. Нумерация полей идет от 0. Если возвращено значение -1, никакое поле с данным столбцом не ассоциировано.

Пример, приведенный выше для свойства SelectedField с использованием Selectedlndex, можно переписать так:

procedure TForm1.DBGrid1DbiClick(Sender: TObject);

begin

IF DBGrid1.Fields[DBGrid1.Selectedlndex].FieldName = 'Doljnost' THEN

Editl.Text := DBGrid1.SelectedField.Text ELSE Editl.Text := ";

end;

Метод function ValidFieldIndex(FieldIndex: Integer): Boolean; возвращает True, если значение Fieldlndex является правильным индексом столбца TDBGrid, и False - в противном случае. Индекс признается правильным, если в TDBGrid показывается информация из поля с индексом Fieldlndex и обращение TDBGrid.Fields[FieldIndex] не вызовет ошибки. Заметим, что в НД, ассоциированном с TDBGrid, поле с индексом Fieldlndex может существовать, а в самом компоненте TDBGrid - нет. В этом случае выдается False. Такая ситуация возможна, если для формирования столбцов TDBGrid использовался редактор столбцов.

Пример.

var IndexOfSomeField : Integer;

IF DBGrid1.ValidFieldIndex(IndexOfSomeField) THEN

Labell.Caption := DBGrid1.Fields[IndexOfSomeField].Text ELSE Labell.Caption := 'Неверный индекс поля';

10.7. Изменение порядка следования столбцов в TDBGrid

10.7.1. Изменение порядка следования столбцов во время разработки приложения

Порядок следования столбцов в TDBGrid на этапе разработки можно изменить так:

• при наличии постоянных столбцов в TDBGrid - путем изменения порядка их следования редакторе столбцов или путем перетаскивания столбцов в TDBGrid (что приводит к автоматическому изменению порядка следования столбцов и в редакторе столбцов );

при формировании колонок TDBGrid на основании списка компонентов TField - путем изменения порядка следования компонентов TField в редакторе полей или путем перетаскивания столбцов в TDBGrid;

• при формировании столбцов TDBGrid, исходя из физической структуры ТБД (что имеет место, если не применялись редактор полей илиредактор столбцов) - изменение порядка следования невозможно

10.7.2. Изменение порядка следования столбцов во время выполнения приложения

Изменение порядка следования столбцов во время выполнения может производиться путем перетаскивания мышью заголовка столбца на новую позицию. Это возможно только если в свойство DragMode установлено значение dmManual; если свойство имеет значение dmAutomatic, перетаскивание столбцов запрещено После перетаскивания возникает событие OnColumnMoved.

При наличии постоянных столбцов возвращение к состоянию столбцов по умолчанию

DBGndl. Columns . State

csDefault;

приведет, помимо прочего, к восстановлению исходного их порядка следования в TDBGrid.

Если в TDBGrid не используются постоянные столбцы, а источником для формирования столбцов служат компоненты TField, добавленные посредством редактора полей, изменять местоположение столбца можно:

а) путем перетаскивания столбца (что ведет к автоматическому изменению свойства TField Index};

б) программно изменяя значение свойства TFiexd Index

Если для формирования состава столбцов в TDBGrid использована физическая структура ТБД, изменить местоположение столбцов в TDBGrid нельзя.

10.8. Управление отображением данных в TDBGrid

Ниже рассмотрены средства для выделения (цветом, шрифтом и т.д.) какого-либо столбца в TDBGrid.

На характеристики представления значений в ячейках TDBGrid также могут оказывать влияние такие свойства компонентов TField, как DisplayFormat и EditFormat, которые позволяют задавать формат поля соответственно при его показе и при редактировании, причем эти свойства актуальны для всех компонентов, визуализирующих значение поля (полей), а не только для столбцов TDBGrid.

Перечисленные средства носят безусловный характер, то есть позволяют изменять характеристики показа всех значений в конкретном столбце. Однако может потребоваться выделять тем или иным образом не целый столбец, а определенные ячейки столбца, отвечающие какому-либо условию. Например, для бухгалтерских и складских программ часто принято выделять красным цветом отрицательные остатки или остатки, находящиеся ниже установленного лимита.

То, как осуществляется прорисовка данных в TDBGrid - стандартным способом или по особому сценарию - определяется свойством property DefaultDrawing: Boolean;

В случае, если имеет место управление прорисовкой со стороны самого приложения, алгоритм прорисовки должен содержаться в обработчиках событий OnDrawColumnCell или OnDrawDataCell. Заметим, что обработчик события OnDrawDataCell введен для совместимости с ранними версиями Delphi.

При автоматической прорисовке (DefaultDrawing = True) метод Paint использует цвет и шрифт свойства Canvas для прорисовки ячейки. Событие

property OnDrawColumnCell: TDrawColumnCellEvent;

TDrawColumnCellEvent = procedure (Sender: TObject; const Rect:

TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState) of object;

где параметры имеют следующий смысл:

Rect - определяет область ячейки, в которой, собственно, происходит прорисовка,

Тип TRect = record

CASE Integer of

0: (Left, Top, Right, Bottom: Integer);

1: (TopLeft, BottomRight: TPoint);

END;

END;

определяет прямоугольник, в котором прорисовывается ячейка TDBGrid, координаты прямоугольника указываются или как 4 целых числа, содержащие границы прямоугольника в пиксельном исчислении, или как 2 значения типа TPoint, определяющих левый верхний и правый нижний углы прямоугольника:

TPoint = record

X: Longint;

Y: Longint;

end;

DataCol - определяет порядковый номер текущего столбца, начиная с 0-го;

Column. TColumn - определяет текущий столбец.

• State TGridDrawState - определяет состояние ячейки.

Тип TGridDrawState = set of (gdSelected, gdFocused, gdFixed) ;

определяет множество возможных состояний ячейки TDBGrid.

Если ячейка находится в состоянии gdFocused (т.е. является текущей), в обработчике события OnDrawColumnCell происходит прорисовка инверсной полосы.

Для вывода ячеек стандартным образом используется метод

procedure DefaultDrawColumnCell(const Rect: TRect; DataCol: Integer; Column:

TColumn; State: TGridDrawState);

Используя информацию, содержащуюся в передаваемых в обработчик OnDrawColumnCell параметрах, можно изменять отображение как целых строк, так и отдельных ячеек.

Пример. Пусть необходимо выводить белым шрифтом на красном фоне те строки НД, у которых поле'Doljnost' содержит значение 'профессор'(рис. 10.20).

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;

DataCol: Integer; Column: TColumn; State: TGridDrawState);

begin

WITH DBGrid!.Canvas do begin

// поле "Должность" содержит значение "профессор"?

IF (Table1Doljnost.AsString = 'профессор') AND not (gdFocused in State) THEN

// - да. Выводить все ячейки строки бельм шрифтом на красном фоне

begin

Brush.Color := cIRed;

Font.Color := clWhite;

FillRect(Rect) ;

TextOut(Rect.Left, Rect.Top,Column.Field.Text) ;

end

ELSE

// - нет, текущее значение "Должности" - не "профессор". Выводим все ячейки строки стандартным образом

DBGrid1.DsfaultDrahColumnCellfRect, DataOol, Column, State);

END; {with}

end;

В отличие от предыдущего примера, в следующем выделяются не строки, а ячейки:

procedure TForm!.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;

DataCol: Integer; Column: TColumn; State: TGridDrawState);

begin

WITH DBGrid!.Canvas do begin

// текущий столбец - "Должность"?

IF (Column.Field.FieldName = 'Doljnost') AND not(gdFocused in State) THEN

// Текущая ячейка содержит значение "профессор"?

IF Column.Field.Text = 'профессор' THEN

// - да. Тогда вывести ячейку белым шрифтом на красном фоне

begin

Brush.Color := cIRed;

Font.Color := clWhite;

FillRect(Rect) ;

TextOut(Rect.Left, Rect.Top, Column.Field.Text);

Exit;

end;

// сюда попадаем, только если текущий столбец - не "Должность" или "Должность", но значение ячейки столбца - не "профессор"

DBGrid!.DefaultDrawColumnCell(Rect, DataCol, Column, State);

END; {with}

end;

ЗАМЕЧАНИЕ. В показанном выше примере значение поля "Должность" имеет строковый тип. Строковые значения в ячейках TDBGrid принято выводить выровненными влево. Поэтому в процедуре

TextOut(Rect.Left, Rect.Top,Column.Field.Text) ;

используется горизонтальная координата Rect.Left.

В случае, когда показываемое в ячейке значение должно быть выровнено вправо (как часто имеет место для цифровых значений), необходимо заменить координату Rect.Left на правую координату ячейки, уменьшенную на ширину выводимого в ячейке текста. Ширина текста возвращается методом TextWidth компонента TDBGrid. Canvas:

function (const Text: string): Integer;

В этом случае содержимое ячейки выводится следующим образом:

TextOutfRect.Right - 3 - TextWidth(Column.Field.Text), Rect.Top,Column.Field.Text) ;

Заметим, что дополнительный сдвиг на 3 пиксела нужен, чтобы оставить справа от текста небольшой пробел.

Заметим также, что сдвиг на 3 пиксела хорош для шрифта MS Sans Serif размером 12 пунктов, который использовался в данном примере; для других шрифтов и размеров эта величина нуждается в изменении. В общем случае, содержание алгоритма, реализующего выравнивание текста, состоит в определении длины и высоты ячейки TDBGrid, а также в определении длины и высоты выводимого в ячейку текста и в их последующем сопоставлении.

10.9. Обработка иных событий в DBGrid

10.9.1. Перемещение между ячейками TDBGrid

Для перехода от текущего столбца к другому можно воспользоваться клавишей TAB - для перехода к столбцу справа от текущего;

• комбинацией клавиш SHIFT+TAB - для перехода к столбцу слева от текущего;

мышью - независимо от того, к какому столбцу нужно перейти.

При смене столбца возникают 2 события в такой очередности:

OnColExit - наступает в момент, когда мы покидаем текущий столбец;

OnColEnter - наступает в момент, когда новый столбец становится текущим.

В следующем примере на экран выводятся имена полей, ассоциированных с покидаемым и новым столбцами:

procedure TForm1.DBGrid1ColEnter(Sender: TObject);

begin

ShowMessage('Мы вошли в ' + DBGrid1.SelectedField.FieldName );

end;

procedure TForm1.DBGrid1ColExit(Sender: TObject);

begin

ShowMessage ('Мы покинули ' + DBGrid1.SelectedField.FieldName );

end;

10.9.2. Действия с мышью и клавиатурой в момент, когда TDBGrid обладает фокусом управления

Для компонента TDBGrid предусмотрены следующие события:

OnDblChck - наступает после двойного щелчка мышью.

Пример. Пусть требуется изменить на желтый цвет фон столбца, на котором произведен двойной щелчок мышью:

procedure TFormI.DBGrid1DblClick(Sender: TObject);

begin

DBGrid1.Columns.Items[DBGrid1.SelectedIndex].Color := clYellow;

end;

OnKeyDown - наступает, когда пользователь нажимает любую клавишу или комбинацию клавиш на клавиатуре (но еще не отпустил).

OnKey Up - наступает, когда пользователь отпускает любую клавишу или комбинацию клавиш.

OnKeyPress - возникает, когда пользователь нажимает отдельную клавишу (цифрового или алфавитного символа) на клавиатуре, а также комбинацию клавиш, что приводит к формированию кода цифрового или алфавитного символа (например, клавишу 'и' или SHIFT + "и, что в результате дает 'U').

Пример вызова различных форм в зависимости от нажатия той или иной клавиши:

procedure TFormI.DBGrid1KeyPress(Sender: TObject; var Key: Char);

begin

ShowMessage(key);

CASE Key OF

'u' : Form2.ShowModal;

's' : Form3.ShowModal ;

END;

10.10. Работа с компонентом TDBCtrlGrid

TDBGrid является универсальным средством для отображения групповых данных (записей из одной таблицы реляционной БД, или записей из различных связанных таблиц). Однако известно, что универсальность никогда не является полной. В некоторых случаях применение компонента TDBGrid бывает затруднено:

большим количеством полей, в этом случае приходится или помещать все поля в TDBGrid, что обычно приводит к необходимости их горизонтальной прокрутки, или помещать в TDBGrid лишь часть полей, а прочие либо выводить в отдельной форме, активизирующейся по нажатию экранной кнопки, или располагать ниже TDBGrid как компоненты TDBText, TDBEdit, TDBRadioGroup и т.д.;

длинными заголовками столбцов; в этом случае приходится их сокращать, что ведет к потере смысла и удобочитаемости;

невозможностью отображать в TDBGrid значения полей в виде, предоставляемом компонентом TDBCheckBox, и т.п.

Этот список при желании можно продолжить. Для преодоления подобных трудностей создан компонент типа TDBCtrlGrid, введенный в версию Delphi 3.0. Обладая основной функциональностью обычного компонента TDBGrid, он позволяет отображать информацию из одной записи НД в прямоугольной панели и размещать эту информацию на ней произвольным образом (рис. 10.22.):

Для работы с компонентом TDBCtrlGrid необходимо поместить его в форму, связать с компонентом TDataSource, который, в свою очередь, связать с каким-либо набором данных (TTable или TQuery) и затем разместить необходимые компоненты для работы с полями базы данных (TDBText, TDBEdit, TDBCheckBox) в верхней строке TDBCtrlGrid (рис. 10.23.):

Во время выполнения приложения расположение компонентов в верхней строке TDBCtrlGridvi их состав будет реплицирован на все оставшиеся строки, как это видно из рис. 10.22.

Порядок редактирования, добавления и удаления записей непосредственно из TDBCtrlGrid аналогичен порядку редактирования, добавления и удаления записей из TDBGrid. Для вставки новой записи необходимо нажать на клавиатуре клавишу Insert или попытаться перейти с последней записи в НД вниз на одну строку (рис. 10.24).

Для изменения записи достаточно ввести новое значение в какое-либо поле. Для удаления записи необходимо нажать комбинацию клавиш Ctrl+Delete. При этом на возможности редактирования, добавления и удаления записей в TDBCtrlGrid влияет ряд свойств как других компонентов (Table. Readonly, TField.ReadOnly, TDBEdit.Readonly), размещенных на панелях TDBCtrlGrid, так и самого компонента TDBCtrlGrid (AllowDelete, Allowlnsert).

Произведем выборочный обзор свойств, методов и событий TDBCtrlGrid:

Свойства

Разрешение корректировки

property AllowDelete: Boolean; - определяет возможность удаления записей из TDBCtrlGrid {True, по умолчанию) или невозможность удаления (False);

property Allowlnsert: Boolean; - определяет возможность вставки записей в TDBCtrlGrid (True, по умолчанию) или невозможность вставки (False);

Параметры показа:

property PanelHeight: Integer; - высота в пикселах;

property PanelWidth: Integer; - ширина в пикселах;

property Orientation: DBCtrlGridOrientation; - определяет ориентацию TDBCtrlGrid- вертикальную (по умолчанию) или горизонтальную; DBCtrlGridOrientation = (go Vertical, goHorizontal);

property Pane/Border: DBCtrlGridBorder; - определяет тип края панели -выступающий (по умолчанию) или отсутствующий; DBCtrlGridBorder = (gbNone, gbRaised); Число панелей, текущая панель, число колонок:

property Pane/Count: Integer; - число панелей, видимых в TDBCtrlGrid.

property Panellndex: Integer; - показывает, какая панель (в диапазоне 0.-PanelCount - 1) отображает текущую запись.

property RowCount: Integer; - содержит число панелей в TDBCtrlGrid, начиная с 1. Изменение этого свойства ведет, к увеличению/уменьшению числа панелей в TDBCtrlGrid без изменения их высоты (PanelHeight). Отличие этого свойства от PanelCount состоит в том, что число RowCount можно изменять, например:

WITH DBCtrlGridl do RowCount := StrToInt(Edit1.Text) ;

property ColCount: Integer; - определяет число колонок в TDBCtrlGrid. По умолчанию равно 1.

Метод procedure DoKey(Key: DBCtrlGridKey);

Выполняет определенное действие над TDBCtrlGrid. Действие определяется параметром А'еу. Некоторые из возможных значений:

gkNull Действия нет

gkEditMode Переводит компонент в режим редактирования

gkLeft Moves Перемещает компонент на 1 колонку влево, при необходимости делает прокрутку окна компонента

gkRight Перемещает на 1 колонку вправо

gkUp Перемещает на 1 запись вверх

gkDown Перемещает на 1 запись вниз

gkScrolIUp Делает запись в предыдущей строке текущей без изменения ее местоположения

gkScrollDown Делает запись в следующей строке текущей без изменения ее местоположения

gkPageUp Перемещает к предыдущей странице TDBCtrlGrid

gkPageDown Перемещает к следующей странице TDBCtrlGrid

gkHome Перемещает на первую запись

gkEnd Moves Перемещает на последнюю запись

Пример. Разместим в форме 4 кнопки для перемещения к первой, последней, следующей и предыдущей записи в TDBCtrlGrid (рис. 10.25).

и напишем такие обработчики событий нажатия соответствующих клавиш:

// нажата клавиша "1-я запись"

procedure TForm1. FirstButtonCiick (Sender : T0bj]ect);

begin

DBCtrlGridl.DoKey(gkHome) ;

end;

// нажата клавиша "Последняя запись"

procedure TForm!.LastButtonClick(Sender: TObject) ;

begin

DBCtrlGridl.DoKey(gkEnd) ;

end;

// нажата клавиша "Запись вверх"

procedure TForm!.UpButtonClick(Sender: TObject) ;

begin

DBCtrlGridl.DoKey(gkScrolIUp) ;

end;

// нажата клавиша "Запись вниз"

procedure TForm! . DownButtonClick (Sender : TObjiect);

begin

DBCtrlGridl.DoKey(gkDown) ;

end;

Тогда нажатие соответствующей экранной клавиши приведет к соответствующим перемещениям компонента TDBCtrlGrid.

Можно также поставить в соответствие отдельным клавишам на клавиатуре определенные действия с TDBCtrlGrid. Например, пусть мы хотим, чтобы при нажатии клавиш происходили следующие действия:

u (up) переход на одну запись вверх

d (down) переход на одну запись вниз

f (first) переход на первую запись

I (list) переход на последнюю запись

Тогда в обработчике события OnKeyDown для TDBCtrlGrid следует записать такой код:

procedure TFormI.DBCtrlGridlKeyDown (Sender: TObject; var Key: Word; Shift: TShiftState) ;

var S : TDBCtrlGridKey;

begin

CASE Key OF

68 : S := gkScrollDown; // нажата "d"

70 : S := gkHome; // нажата "f"

76 : S := gkEnd; // нажата "1"

85 : S := gkDown; // нажата "и"

END; {case}

DBCtrlGridl.DoKey(S) ;

end;

События

Для TDBCtrlGrid определены следующие события, аналогичные одноименным событиям TDBGrid: OnClick, OnDblClick, OnDragDrop, OnDragOver, OnEndDrag, OnEnter, OnExit, OnKeyDown, OnKeyPress, OnKeyUp, OnStartDrag.

Дополнительно введены события property OnPaintPanel: TPaintPanelEvent;

TPaintPanelEvent = procedure(DBCtrlGrid: TDBCtrlGrid; Index: Integer) of object;

Наступает для каждой панели TDBCtrlGrid перед ее показом. Обработчик этого события может управлять рисованием панели. Параметр TDBCtrlGrid показывает, какой именно компонент TDBCtrlGrid отображается в данный момент; параметр Index' определяет индекс отображаемой панели. /

property OnMouseDown: TMouseEvent; наступает, когда пользователь нажимает левую кнопку мыши, находясь при этом на TBCtrlGrid.

property OnMouseUp: TMouseEvent; наступает, когда пользователь отпускает нажатую ранее кнопку мыши, находясь при этом на TBCtrlGrid.