- Borderstyle— стиль обрамления. Здесь возможны варианты bssingie или bsNone. Можно самостоятельно, по очереди, установить оба этих типа и посмотреть, что они собой представляют.
- coiumncount — количество колонок в сетке. Оставим так, как есть — 5 штук.
- Defauitcoiwidth — ширина колонок по умолчанию.
- DefauitDrawing— рисование по умолчанию. Если здесь установлено true, то компонент сам будет отображать введенные данные. Если False, то это придется делать самостоятельно, реагируя на соответствующие события.
- DefauitcoiHeight— высота строк по умолчанию. Значение, установленное здесь, достаточно большое, поэтому давайте введем 16. Так сетка будет выглядеть более элегантно, по крайней мере на мой вкус.
- Fixedcoior— цвет фиксированных колонок и строк. В фиксированные ячейки нельзя вводить текст, они используются в качестве заголовков. На рис. 11.9 первая колонка и первая строка фиксированы и поэтому отображены цветом элементов управления (цвет по умолчанию).
- Fixedcois— количество фиксированных колонок. Они всегда первые, нельзя создать фиксированную колонку в середине сетки. Хотя нет, возможно, все это только вопрос времени, но для этого придется писать код самостоятельно.
- FixedRows— количество фиксированных строк. Они всегда первые, нельзя создать фиксированную строку в середине сетки. Это можно сделать только самостоятельно.
- GridLinewidth — толщина разделительных линий сеток.
- Options— настройки сетки. Если дважды щелкнуть левой кнопкой мыши по этому свойству или один раз по квадратику слева от названия свойства, то раскроется большой список дополнительных свойств.
Рассмотрим каждое из них в отдельности:
- goFixedVertLine— рисовать вертикальные линии сетки у фиксированных ячеек;
- goFixedHorzLine— рисовать горизонтальные линии сетки у фиксированных ячеек;
- govertLine — рисовать вертикальные линии сетки у нефиксированных ячеек;
- goHorzLine— рисовать горизонтальные линии сетки у нефиксированных ячеек;
- goRangeSeiect — позволять выделять несколько ячеек;
- goDrawFocuSeiected — рисовать фокус выделенной ячейки;
- goRowSizing — можно ли изменять размер строк перетягиванием мышью;
- goCoisizing — можно ли изменять размер колонок перетягиванием мышью;
- goRowMoving — можно ли перемещать строки (если true, то можно нажать кнопку мыши, установив ее указатель на фиксированную ячейку строки, и перетащить в новое положение);
- goCoiMoving— можно ли перемещать колонки (если true, то можно нажать кнопку мыши, установив ее указатель на фиксированную ячейку колонки, и перетащить ее в новое положение);
- goEditing— можно ли вводить с клавиатуры данные в сетку (для нашего примера установим в true);
- goTabs — если здесь установить true, то между ячейками можно путешествовать с помощью клавиши <ТаЬ>;
- goRowseiect— если здесь false, то выделяется только выделенная ячейка (если true, то вся строка);
- goAlwaysshowEditor— если false, то когда вы обратились к ячейке, для ее редактирования нужно нажать <Enter> или <F2>, если true, то как только выделяется ячейка, ее сразу можно редактировать;
- goThumbTracking— будут ли данные прорисовываться, пока пользователь перемещает полосу прокрутки.
- RowCount — количество строк. Для первого примера нам хватит пяти.
- scrollBars— нужно ли показывать полосы прокрутки.
- ssNone — не показывать;
- ssHorizontal —только горизонтальную полосу;
- ssVertical — только вертикальную полосу.
procedure TMainForm.FormShow(Sender: TObject) ;
begin
// Заполняем значениями первую колонку
StringGrid1.Cells[0,1]:='Иванов';
StringGrid1.Cells[0,2]:='Петров';
StringGrid1.Cells[0,3]:='Сидоров';
StringGrid1.Cells[0,4]:='Смирнов';
// Заполняем значениями первую строку
StringGrid1.Cells[1,0]:='Год рожд.';
StringGrid1.Cells[2,0]:='Место рожд.';
StringGrid1.Cells[3,0]:='Прописка';
StringGrid1.Cells[4,0]:='Семейное положение';
end;
У объекта TStringGrid есть еще одно свойство, которое не описано в объектном инспекторе—cells. Это свойство—двумерный массив из строк, в которых хранятся данные, отображаемые в сетке. Чтобы получить доступ к какой-либо ячейке, нужно записать StringGridl.Cells[номер колонки, номер ячейки].
Например, если вы хотите записать во вторую колонку и четвертую строку текст "Привет", то необходимо записать:
Таким же способом можно и читать содержимое ячеек:
На рис. 11.10 вы можете увидеть окно, в котором показан пример в запущенном виде.
Давайте усилим этот пример и заодно поглубже познакомимся с сеткой. Как видите, в примере есть поле Год рождения. В это поле должны вводиться даты, а значит, они должны
иметь определенный формат. Было бы очень удобно, если бы в этом поле можно было бы задать маску ввода, но сетка такое не поддерживает. Тут можно использовать одну хитрость— когда пользователь щелкает мышью по нужному полю, подставлять компонент TMaskEdit, и пускай пользователь вводит информацию в него в строго определенном формате.
Давайте, реализуем сказанное на практике. Для этого поместите на форму компонент TMaskEdit (место расположения не имеет значения) и назовите его DateEdit. Установите маску для ввода даты 99/99/9999. Теперь установите у него свойство visible в false, чтобы компонент не был виден.
Создайте обработчик события onDrawCeii и в нем напишите содержимое листинга:
procedure TMainForm.StringGridlDrawCell(Sender: TObj ect; ACol,ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
DateEdit.Visible := false; // Сделать невидимым компонент DateEdit
if (gdFocused in State) then // Если текущая ячейка в фокусе, то ...
begin
if ACol=l then // Если рисуется ячейка первой колонки, то ...
begin
// Записать в DateEdit текст ячейки DateEdit.Text:=StringGridl.Cells[ACol, ARow]; // Установить левую позицию
DateEdit.Left := Rect.Left + StringGridl.Left+2; // Установить верхнюю позицию
DateEdit.Top := Rect.Top + StringGridl.top+2; // Установить ширину
DateEdit.Width := Rect.Right - Rect.Left; // Установить высоту
DateEdit.Height := Rect.Bottom - Rect.Top; // Сделать компонент DateEdit видимым
DateEdit.Visible := true;
exit;
end;
end;
end;
Этот обработчик вызывается каждый раз, когда надо прорисовать какую-нибудь ячейку. Если прорисовывается вся сетка, то он вызывается для каждой ячейки отдельно. ДЛЯ нас Delphi СОЗДал процедуру обработчик события StringGridlDrawCell со следующими параметрами:
sender-—здесь передается указатель на объект, который сгенерировал событие;
- arow и acol — номер строки и номер столбца (координаты) ячейки, которую надо прорисовать;
- Rect— структура, в которой указаны относительные размеры и положения ячейки.
Что понимается под словом "относительные"? Структура Rect выглядит так:
type TRect = record
Left, Top, Right, Bottom: Integer; end;
Как видите, это структура из четырех параметров— левой, верхней, правой и нижней позиции. На рис. 11.11 стрелками показан тот размер, который будет в параметрах Left и Right структуры Rect. Размеры будут указаны в пикселах. В параметре Right будет указано расстояние в пикселах от левого края сетки
до правого края ячейки, а в параметре левая и верхняя позиции ячейки
Bottom будет расстояние от верхнего края сетки до нижнего края ячейки. То есть мы получаем размеры относительно самой сетки, а не всей формы.
Ну и последний параметр, передаваемый нам в процедуру-обработчик события,— state. В нем находится информация о состоянии ячейки, которую надо прорисовать. Состояния могут быть следующими:
- gdseiected — ячейка выделена;
- gdFocused — ячейка имеет фокус ввода;
- gdFixed — ячейка является фиксированной.
Если в параметре state нет ни одного из этих значений, то это простая ячейка. Параметр state объявлен как набор значений. Это значит, что он может принимать любое из указанных значений или их сочетания. Чтобы проверить, установлено ли что-нибудь в state, надо написать:
Именно так проверяется во второй строке кода наличие значения gdFocused. И только если ячейка, которую надо прорисовать, имеет фокус, выполняются следующие действия. Но перед этим мы прячем нашу маскированную строку ввода, потому что она могла находиться видимой в другой ячейке, и чтобы не было проблем, лучше ее спрятать.
Если рисуемая ячейка в фокусе, мы проверяем, в какой колонке находится рисуемая ячейка. Если это первая колонка (где мы должны вводить дату), то мы показываем DateEdit на месте рисуемой ячейки. Для этого сначала присваиваем в DateEdit текст, который должен находиться в данной ячейке. Затем устанавливаем позицию и размеры компонента DateEdit и только потом показываем его.
Как видите, способ очень простой и элегантный. Теперь осталось только создать обработчик события onchange для компонента DateEdit. Это событие происходит, когда данные в строке ввода изменились, а это значит, что нам их надо сразу же прописать в редактируемую ячейку сетки, иначе они потеряются. Это потому, что все данные вводятся в DateEdit, а не в сетку, а переносить их мы должны вручную:
procedure TMainForm.DateEdi tChange(Sender: TObj ect);
begin
StringGridl.Cells[StringGridl.Col, StringGridl.Row]:=DateEdit.Text;
end;
Чтобы еще больше закрепить материал этой части главы, давайте сделаем в последней колонке появление компонента TСhесквох, по которому можно менять значение в ячейке между "Женат" и "Холост". Для этого на форму надо установить компонент CheckBox и сделать его невидимым. Потом надо изменить событие onDrawCeii, как это показано в листинге:
procedure TMainForm.StringGridlDrawCell(Sender: TObj ect; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState); begin
DateEdit.Visible := false;
CheckBoxl.Visible := false;
if (gdFocused in State) then begin if ACol=l then begin
DateEdit.Text:=StringGridl.Cells[ACol, ARow];
DateEdit.Left := Rect.Left + StringGridl.Left+2;
DateEdit.Top := Rect.Top + StringGridl.top+2;
DateEdit.Width := Rect.Right - Rect.Left;
DateEdit.Height := Rect.Bottom - Rect.Top;
DateEdit.Visible := true;
expend;
if ACol=4 then begin
CheckBoxl.Caption:=StringGridl.Cells[ACol, ARow];
i f CheckBoxl.Caption='ao' then CheckBoxl.Checked:=true
else
CheckBoxl.Checked:=false;
CheckBoxl.Left := Rect.Left + StringGridl.Left+2;
CheckBoxl.Top := Rect.Top + StringGridl.top+2;
CheckBoxl.Width := Rect.Right - Rect.Left;
CheckBoxl.Height := Rect.Bottom - Rect.Top;
CheckBoxl.Visible := true;
expend;
end;
end;
Ну и, конечно же, необходимо "поймать" событие onclick компонента CheckBox1, чтобы записать измененное значение обратно в сетку. В этом обработчике напишите код листинга:
procedure TMainForm.CheckBoxlClick(Sender: TObject);
begin
if CheckBoxl.Checked=true then CheckBoxl.Caption:='Женат' else
CheckBoxl.Caption: = гХолост1;
StringGridl.Cells[StringGridl.Col, StringGridl.Row]:=CheckBoxl.Caption;
end;