Хотя StringGrid идеально подходит для отображения больших объемов данных, но их представление оставляет желать лучшего. Действительно при сравнении с другими приложениями, такими как Excel, грид просто выглядит любительски. Если попытаться непосредственно изменить что-нибудь в гриде через интерфейс, то скоро можно убедиться, что из этого ничего не выйдет. Например, невозможно изменить текст или фон ячеек непосредственно, нельзя изменить шрифт на курсив и изменить цвет выбранной ячейки.
В предыдущей статье я объяснил основы класса TStringGrid, как использовать основные его свойства и как использовать некоторые методы для расширения функциональности грида. В этой статье рассмотрим, как настроить внешний вид строки грида и как можно вставить флажок в ячейку грида.
Использование события OnDrawCell
В предыдущей статье мы обсуждали вопрос о том, как работать с текстом ячейки. Для этой цели мы использовали обработчик события OnDrawCell, просто прорисовывая текст функцией DrawText().
В действительности же, событие OnDrawCell может использоваться более широко, чем просто выравнивание текста в ячейки. Можно использовать это событие для изменения внешнего вида ячеек грида.
Обработчик события OnDrawCell, расмотренный в предыдущей статье был относительно прост по той причине, что значение свойства DefaultDrawing было изначально установлено по умолчанию в True. В этом случае прорисовка выполнялась за счет возможностей класса TCustomGrid. Однако для прорисовки грида более утонченно значение свойства DefaultDrawing надо установить в False. Для понимания, зачем это надо рассмотрим, как классы TStringGrid and TCustomGrid выполняют прорисовку каждой ячейки.
Взгляд изнутри на процедуру прорисовки
Подобно всем потомкам класса TCustomControl, класс TCustomGrid выполняет прорисовку в соответствии с возможностями определенными в виртуальном методе Paint(). В пределах этого метода есть две функции: DrawLines() и DrawCells(). Первая отвечает за прорисовку сетки грида, а вторая за прорисовку самих клеток. Из функции DrawCells() вызывается виртуальный метод DrawCell(). Если значение свойства DefaultDrawing установлено в True, то этот метод вызывается, после того как были инициализированы свойства Font и Brush канвы грида, а также после прорисовки фона ячейки методом канвы FillRect().
Метод DrawCell() определенный в классе TDrawGrid вызывает событие OnDrawCell. На самом деле, за некоторым исключением, связанным с незначительным изменением свойства UseRightToLeftAlignment, метод DrawCell() просто вызывает ассоциированный с ним обработчик событий OnDrawCell, если конечно он создан. В частности, текст каждой ячейки прорисовывается через метод TextRect() канвы. Давайте взглянем на определение метода DrawCell():
void __fastcall TStringGrid::DrawCell(
int ACol, int ARow, const TRect& ARect,
TGridDrawState AState)
{
if (DefaultDrawing) {
Canvas->TextRect(ARect,
ARect.Left + 2, ARect.Top + 2,
Cells[ACol][ARow]);
}
TDrawGrid::DrawCell(
ACol, ARow, ARect, Astate);
}
Из этого кода можно увидеть, что текст в каждой ячейке прорисовывается в том случае, если значение свойства DefaultDrawing установлено в True. Также, обратите внимание, что когда класс TStringGrid вызывает метод DrawCell() своего родительского класса, то возможно обращение к обработчику события OnDrawCell. Более того, этот обработчик вызывается после того как в гриде прорисован текст ячейки.
Что всё это означает? Допустим, если определить обработчик для события OnDrawCell и рисовать что-нибудь на канве, пока свойство DefaultDrawing установлено в True, вы действительно рисуете поверх того, что было уже нарисовано классами TCustomGrid и TStringGrid. Все это хорошо пока надо рисовать что-нибудь простое или в ограниченных по количеству ячейках. В других случаях это не эффективное решение.