Как изменить цвет строки в TDBGrid
Предположим, нам требуется изменить атрибуты текста и фона строки в компоненте TDBGrid, если значение какого-либо поля удовлетворяет заранее заданному условию. Для этой цели принято использовать обработчик события OnDrawColumnCell этого компонента. Отметим, что возможности, предоставляемые при его использовании, весьма разнообразны.
Рассмотрим простейшее приложение с TDBGrid, содержащее один компонент TTable, один компонент TDataSource и один компонент TDBGrid: Установим значения их свойств в соответствии с приведенной ниже таблицей:
Компонент | Свойство | Значение |
Table1 | DatabaseName | BCDEMOS (или DBDEMOS) |
TableName | events.db | |
Active | true | |
DataSource1 | DataSet | Table1 |
DBGrid1 | DataSource | DataSource1 |
Рис. 1 Тестовое приложение на этапе проектирования
Обычно для перерисовки изображения в ячейках используется метод OnDrawColumnCell.
Его параметр Rect - структура, описывающая занимаемый ячейкой прямоугольник, параметр Column - колонка DBGrid, в которой следует изменить способ рисования изображения. Для вывода текста используется метод TextOut свойства Canvas компонента TDBGrid.
Предположим, нам нужно изменить цвет текста и фона строки в зависимости от значения какого-либо поля (например, VenueNo). Создадим обработчик события OnDrawColumnCell компонента DBGrid1. В случае C++Builder он имеет вид:
void __fastcall TForm1::DBGrid1DrawColumnCell(TObject *Sender, const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State) { if (Table1->FieldByName("VenueNo")->Value==1) { DBGrid1->Canvas->Brush->Color=clGreen; DBGrid1->Canvas->Font->Color=clWhite; DBGrid1->Canvas->FillRect(Rect); DBGrid1->Canvas->TextOut(Rect.Left+2,Rect.Top+2,Column->Field->Text); } }
В случае Delphi соответствующий код имеет вид:
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); begin if (Table1.FieldByName('VenueNo').Value=1) then begin with DBGrid1.Canvas do begin Brush.Color:=clGreen; Font.Color:=clWhite; FillRect(Rect); TextOut(Rect.Left+2,Rect.Top+2,Column.Field.Text); end; end; end;
В результате на этапе выполнения при отображении строк, в которых значение поля VenueNo равно 1, фон ячеек будет окрашен в зеленый цвет, а текст будет выведен белым цветом.
Рис. 2 Изменение цвета фона и шрифта в строках со значением поля VenueNo=1 на этапе выполнения.
При выводе выделенных строк все данные в ячейках оказались выровненными по левому краю. Если мы хотим более корректно отобразить выравнивание текста в колонке, следует слегка модифицировать наш код, учтя значение свойства Alignment текущей (то есть рисуемой в данный момент) колонки:
void __fastcall TForm1::DBGrid1DrawColumnCell(TObject *Sender, const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State) { if (Table1->FieldByName("VenueNo")->Value==1) { DBGrid1->Canvas->Brush->Color=clGreen; DBGrid1->Canvas->Font->Color=clWhite; DBGrid1->Canvas->FillRect(Rect); if (Column->Alignment==taRightJustify) { DBGrid1->Canvas->TextOut(Rect.Right-2- DBGrid1->Canvas->TextWidth(Column->Field->Text), Rect.Top+2,Column->Field->Text); } else { DBGrid1->Canvas->TextOut(Rect.Left+2,Rect.Top+2,Column->Field->Text); } } }
Соответствующий код для Delphi имеет вид:
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); begin if (Table1.FieldByName('VenueNo').Value=1) then begin with DBGrid1.Canvas do begin Brush.Color:=clGreen; Font.Color:=clWhite; FillRect(Rect); if (Column.Alignment=taRightJustify) then TextOut(Rect.Right-2- TextWidth(Column.Field.Text), Rect.Top+2,Column.Field.Text) else TextOut(Rect.Left+2,Rect.Top+2,Column.Field.Text); end; end; end;
В этом случае выравнивание текста в колонках совпадает с выравниванием столбцов.
Отметим, что величина смещения (в данном случае 2 пиксела), вообще говоря, зависит от гарнитуры и размера шрифта, используемого в данной колонке, и должна подбираться индивидуально.
Рис. 3 Изменение цвета с учетом выравнивания текста в колонках.
Если необходимо отобразить нестандартным образом не всю строку, а только некоторые ячейки, следует проанализировать имя поля, отображаемого в данной колонке, как в приведенном ниже обработчике событий. Пример для C++Builder выглядит так:
void __fastcall TForm1::DBGrid1DrawColumnCell(TObject *Sender, const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State) { if ((Table1->FieldByName("VenueNo")->Value==1) & (Column->FieldName=="VenueNo") ) { DBGrid1->Canvas->Brush->Color=clGreen; DBGrid1->Canvas->Font->Color=clWhite; DBGrid1->Canvas->FillRect(Rect); DBGrid1->Canvas->TextOut(Rect.Right-2- DBGrid1->Canvas->TextWidth(Column->Field->Text), Rect.Top+2,Column->Field->Text); } }
Соответствующий код для Delphi имеет вид:
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); begin if (Table1.FieldByName('VenueNo').Value=1) and (Column.FieldName='VenueNo') then begin with DBGrid1.Canvas do begin Brush.Color:=clGreen; Font.Color:=clWhite; FillRect(Rect); TextOut(Rect.Right-2- TextWidth(Column.Field.Text), Rect.Top+2,Column.Field.Text) end; end; end;
В результате выделенными оказываются только ячейки, для которых выполняются выбранные нами условия:
Рис. 4 Выделение цветом данных в одной колонке.