18.2.5. TDrawGrid - произвольная таблица

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

Чтобы таблица была работоспособной, в ней как минимум следует определить обработчик события OnDrawCell, которое возникает при необходимости прорисовать ту или иную ячейку. Для прорисовки используется табличное свойство Canvas.

Компонент TDrawGrid является непосредственным родителем строковой таблицы TStringGrid, поэтому передает ей все свои свойства, методы и события за исключением специфичных для строк свойств Cells, Cols, Objects И Rows. Поскольку порядок описания компонентов в этой главе соответствует умалчиваемому порядку их расположения на страницах палитры компонентов, TStringGrid описан раньше своего родителя TDrawGrid, и вы сможете найти информацию о свойствах, методах и событиях последнего в предыдущем параграфе.

В следующем примере компонент TDrawGrid используется для показа текста и картинок одновременно, причем текст можно редактировать. Картинки взяты из каталога images l splash | igcolor (рис. 18.11).

Рис. 18.11. Пример использования таблицы TDrawGrid для отображения картинок и текста

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

public

sIBitMap: TSringList;

Это поле будет использоваться для хранения текстовых строк и картинок. Его необходимо создать и наполнить в момент создания окна и уничтожить при его уничтожении. Поэтому создайте следующие Обработчики событий OnCreate и OnDestroy для формы:

procedure TfmDrawGrid.FormCreate(Sender: TObject);

// Создает и наполняет список sIBitMap

const

FNames: array [0..3] of String = {Имена файлов с картинками} ('athena.bmp', 'construe.bmp', 'earth.bmp', 'technlgy.bmp');

var

k: Integer;

begin

// Создаем список строк:

sIBitMap := TStringList.Create;

// Вставляем в него названия файлов и картинки:

with sIBitMap do for k := 0 to 3 do

begin

Add(FNames[k]) ;

Objects[k] := TBitMap.Create;

(Objects[k] as TBitMap).LoadFromFile(FNames[k])

end;

end;

procedure TfmDrawGrid.FormDestroy(Sender: TObject);

// Уничтожает список строк

begin

sIBitMap.Free

end;

Обратите внимание: в именах файлов нет маршрута поиска, поэтому следует скопировать файлы, перечисленные в константе FNames, из каталога images | splash | 16 color в каталог для размещения ваших учебных программ и в этом же каталоге сохранить форму fmDrawGrid и проект под именем DrawGrid. После этого полезно осуществить прогон программы, чтобы убедиться в доступности файлов. Если при прогоне появится сообщение cannot open file, еще раз убедитесь в том, что файл drawgrid. exe создан в том же каталоге, в котором находятся вмр-файлы.

Поместите на пустую форму компонент TDrawGrid и установите для него следующие значения свойств:

Свойство | Значение | Комментарий
Align | alClient | Таблица занимает всю клиентскую часть окна
ColCount | 2 | В таблице 2 колонки
FixedCols | 0 | Нет фиксированных колонок
FixedRows | 0 | Нет фиксированных рядов
Name | dgDraw | Имя таблицы
Options.goEditing | True | Разрешено редактирование текста
RowCount | 2 | В таблице 2 строки
ScrollBars | sbNone | He надо вставлять полосы прокрутки

Теперь необходимо создать обработчики событий OnGetEditText, OnSetEditText иOnDrawCell. Два первых используются для редактирования текста, а обработчик OnDrawCell обязательно создается для любого компонента TDrawGrid, т. к. без него компонент не сможет заполнить пустые клетки каким-либо изображением или текстом.

procedure TfmDrawGrid.DrawGridlGetEditText(Sender: TObject;

ACol, ARow: Integer;

var Value: String ) ;

// Передает редактору текст из ячейки

begin

Value := slBitMap[2 * ACol + Arow]

end;

procedure TfmDrawGrid.DrawGridlSetEditText(Sentier: TObject;

ACol, ARow: Integer; const Value: String ) ;

// Получает текст из редактора и сохраняет его в sIBitMap

begin

slBitMap[2 * ACol + ARow] := Value

end;

procedure TfmDrawGrid.dgDrawDrawCell(Sender: TObject;

Col, Row: Integer; Rect: TRect; State: TGridDrawState) ;

// Рисует картинку из sIBitMap.Objects и текст из sIBitMap

var

k: Integer;

begin

// Пересчитываем координаты ячейки в индекс списка:

k := 2 * Col + Row;

with dgDraw.Canvas, Rect, sIBitMap do

begin

// Уменьшаем высоту картинки для вывода под ней текста:

Bottom := Bottom - TextHeight('1') - 2;

// Рисуем картинку:

StretchDraw(Rect, (Objects[k] as TBitMap)) ;

// Центрируем текст по горизонтали и выводим его:

TextOut(Left+(Right-Left-TextWidth(sIBitMap[k])) div 2,

Bottom + 1, slBitMap[k])

end

end;

Осталось добиться того, чтобы размеры ячеек таблицы согласовывались с размерами окна программы. Для этого создайте для формы fmDrawGrid такой обработчик события onResize (это событие возникает при каждом изменении размеров окна):

procedure TfmDrawGrid.FormResize(Sender: TObject);

// Изменяет размеры ячеек при изменении размеров окна.

// Запас в один пиксель необходим для предотвращения

// автопрокрутки

begin

with dgDraw do

begin

DefaultColWidth := ClientRect. Right div 2-1;

DefaultRowHeight := ClientRect. Bottom div 2-1

end;

end;