Разукрашивание ячеек у StringGrid

До чего же оказывается скучен в Delphi компонент StringGrid. В этой статье я расскажу как это хотя бы немного исправить. А именно, как разукрашивать у него ячейки. Но не ячейки которые попадают под конкретное условие, а именно любые. Например: ячейка которая содержит нуль должна быть синей. Для этого мы могли бы воспользоваться кодом:

if StringGrid.Cells[ACol, ARow] = '0' then
with StringGrid.Canvas do
begin
Brush.Color := clBlue;
FillRect(Rect);
end;


Но, а если нам необходимо любой ячейке присваивать нужный нам цвет. Мне встречались на эту тему две или три статьи, но там (не хочу обидеть их авторов) скажем так не полный ход реализации. Но, одна статься меня все-таки вдохновила, воспользоваться примером из книги Дмитрия Осипова «Delphi профессиональные программирование». Там разбирался пример, как можно в ячейки StringGrid вставлять изображения. Собственно это и послужило вдохновением для написания этой статьи, но только по разукрашиванию ячеек, так как данная необходимость встречается чаще. Я решил написать на мой взгляд несколько универсальных функций, чтобы в дальнейшем не приходилось тратить время на написание кода (хотя его и немного) под различные ситуации. Дело в том, что StringGrid может хранить ссылки на объекты. Эти ссылки размещаются в массиве свойств:

Property Objects [ACol, ARow: Integer]: TObject;

Теперь приступим к практике. Создайте форму, поместите на нее StringGrid и одну кнопку. Все как на рисунке 1.

image
Рисунок 1 – Пример

Я обнулил у StringGrid свойства FixedCols и FixedRows. Ну а далее для начала нам необходимо создать новый тип:
type
TCellsColor = class(TObject)
public
BrushColor: TColor; // Наш цвет
end;

Далее создадим процедуру по созданию объектов, в которых и будем хранить значение цвета:
// Создание объектов
procedure TPrimary.CreateObj(Obj: TStringGrid);
var
i, j: Integer;
CellsColor: TCellsColor;
begin
with Obj do
for i := 0 to ColCount - 1 do
for j := 0 to RowCount - 1 do
begin
CellsColor := TCellsColor.Create; // Создаем объект
Objects[i, j] := CellsColor; // Связываем объект с ячейкой

if Obj.Objects[i, j] is TCellsColor then
// Присваиваем ячейкам цвет по умолчанию
with Obj.Objects[i, j] as TCellsColor do BrushColor := clWhite;
end;
end;


Эту процедуру мы вызовем при показе формы:
// Обработчик события формы OnShow
procedure TPrimary.FormShow(Sender: TObject);
begin
// Вызываем процедуру по созданию
// объектов для дальнейшей приязки к ячейкам
CreateObj(StringGrid);
end;


И не будем откладывать на потом создание процедуры по уничтожению объектов, а сразу напишем и ее:
// Уничтожение созданных объектов
procedure TPrimary.FreeObjects(Obj: TStringGrid);
var
i, j: Integer;
begin
for i := 0 to Obj.ColCount - 1 do
for j := 0 to Obj.RowCount - 1 do
if Obj.Objects[i, j] is TCellsColor then
// Уничтожаем объект
with Obj.Objects[i, j] as TCellsColor do free;
end;

Эту процедуру мы вызовем при закрытии формы:
// Закрытие формы
procedure TPrimary.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// Вызов процедуры для уничтожения
// созданных объектов
FreeObjects(StringGrid);
end;


Еще нам осталось создать процедуру по разукрашиванию ячеек и написать немного кода в обработчике события отвечающего за прорисовку ячеек StringGrid. Напишем для начала процедуру для разукрашивания ячеек:
// Раскраска
procedure TPrimary.Painting(Obj: TStringGrid);
var
i, j: Integer;
begin
Randomize;
for i := 0 to Obj.ColCount - 1 do
for j := 0 to Obj.RowCount - 1 do
if Obj.Objects[i, j] is TCellsColor then
with Obj.Objects[i, j] as TCellsColor do BrushColor := Random(10000000);

Obj.Repaint; // Перерисовка Grid
end;


Цвет ячеек для демонстрации выбирается случайно. Теперь делаем последние штрихи, а именно напишем код в обработчике события отвечающего за прорисовку ячеек:
// Прорисовка ячеек
procedure TPrimary.StringGridDrawCell(Sender: TObject; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
if StringGrid.Objects[ACol, ARow] is TCellsColor then
with StringGrid.Canvas do
begin
// Преобразовываем к типу TCellsColor и извлекаем цвет ячейки
Brush.Color := TCellsColor(StringGrid.Objects[ACol, ARow]).BrushColor;
// Заполняем ячейку
FillRect(Rect);
end;
end;


Теперь мы можем посмотреть, что у нас получилось. Для этого вызовем следующую процедуру и передадим ей ссылку на объект StringGrid:
Painting(StringGrid);

Ну, вот и все можно наслаждаться результатом. Пример работы показан на рисунке 2.
image
Рисунок 2 – Результат работы
Самое обидное то, что вот такие мелочи, бывает, иногда стопорят работу. Надеюсь, что кому ни будь это поможет.
Tags:
Delphi, StringGrid, разукрашивание, ячейка

You can't comment this post because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author's username will be hidden by an alias.