Работа с TDBGrid

Что можно поместить в DBGrid

Нередко при разработке приложений, использующих табличный вывод данных, требуется отобразить те или иные строки таблиц нестандартным образом, например, с целью привлечения внимания пользователя к этим строкам. В данной статье содержатся некоторые советы, касающиеся нестандартного отображения данных в компоненте TDBGrid.

Как изменить цвет строки в TDBGrid
Предположим, нам требуется изменить атрибуты текста и фона строки в компоненте TDBGrid, если значение какого-либо поля удовлетворяет заранее заданному условию. Для этой цели принято использовать обработчик события OnDrawColumnCell этого компонента. Отметим, что возможности, предоставляемые при его использовании, весьма разнообразны.

Рассмотрим простейшее приложение с TDBGrid, содержащее один компонент TTable, один компонент TDataSource и один компонент TDBGrid: Установим значения их свойств в соответствии с приведенной ниже таблицей:

Компонент Свойство Значение
Table1 DatabaseName BCDEMOS (или DBDEMOS)
TableName events.db
Active true
DataSource1 DataSet Table1
DBGrid1 DataSource DataSource1
Обычно для перерисовки изображения в ячейках используется метод 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, фон ячеек будет окрашен в зеленый цвет, а текст будет выведен белым цветом.

При выводе выделенных строк все данные в ячейках оказались выровненными по левому краю. Если мы хотим более корректно отобразить выравнивание текста в колонке, следует слегка модифицировать наш код, учтя значение свойства 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 пиксела), вообще говоря, зависит от гарнитуры и размера шрифта, используемого в данной колонке, и должна подбираться индивидуально.

Если необходимо отобразить нестандартным образом не всю строку, а только некоторые ячейки, следует проанализировать имя поля, отображаемого в данной колонке, как в приведенном ниже обработчике событий. Пример для 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;  

В результате выделенными оказываются только ячейки, для которых выполняются выбранные нами условия:

Как заменить данные в столбце компонента TDBGrid
Нередко в колонке DBGrid нужно вывести не реальное значение, хранящееся в поле соответствующей таблицы, а другие данные, соответствующие имеющимся (например, символьную строку вместо ее числового кода). В этом случае также используется метод TextOut свойства Canvas компонента TDBGrid:


void __fastcall TForm1::DBGrid1DrawColumnCell(TObject *Sender,  
      const TRect &Rect, int DataCol, TColumn *Column,  
      TGridDrawState State)  
{  
if  
(Column->FieldName=="VenueNo")  
{  
DBGrid1->Canvas->Brush->Color=clWhite;  
DBGrid1->Canvas->FillRect(Rect);  
if (Table1->FieldByName("VenueNo")->Value==1)  
{  
DBGrid1->Canvas->Font->Color=clRed;  
DBGrid1->Canvas->TextOut(Rect.Right-2-  
  DBGrid1->Canvas->TextWidth("our venue"),  
  Rect.Top+2,"our venue");  
}  
else  
{  
DBGrid1->Canvas->TextOut(Rect.Right-2-  
  DBGrid1->Canvas->TextWidth("other venue"),  
  Rect.Top+2,"other venue");  
}  
}  
}  

Соответствующий код для Delphi имеет вид:


procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;  
  DataCol: Integer; Column: TColumn; State: TGridDrawState);  
begin  
if  (Column.FieldName='VenueNo')  then begin  
with  DBGrid1.Canvas do begin  
Brush.Color:=clWhite;  
FillRect(Rect);  
if (Table1.FieldByName('VenueNo').Value=1) then begin  
Font.Color:=clRed;  
TextOut(Rect.Right-2-  
  DBGrid1.Canvas.TextWidth('our venue'),  
  Rect.Top+2,'our venue');  
end else begin  
 TextOut(Rect.Right-2-  
  DBGrid1.Canvas.TextWidth('other venue'),  
  Rect.Top+2,'other venue');  
end;  
end;  
end;  
end;  

Еще один пример - использование значков из шрифтов Windings или Webdings в качестве подставляемой строки.


void __fastcall TForm1::DBGrid1DrawColumnCell(TObject *Sender,  
      const TRect &Rect, int DataCol, TColumn *Column,  
      TGridDrawState State)  
{  
if  
(Column->FieldName=="VenueNo")  
{  
DBGrid1->Canvas->Brush->Color=clWhite;  
DBGrid1->Canvas->FillRect(Rect);  
DBGrid1->Canvas->Font->Name="Wingdings";  
DBGrid1->Canvas->Font->Size=-14;  
if (Table1->FieldByName("VenueNo")->Value==1)  
{  
DBGrid1->Canvas->Font->Color=clRed;  
DBGrid1->Canvas->TextOut(Rect.Right-2-  
  DBGrid1->Canvas->TextWidth("J"),  
  Rect.Top+1,"J");  
}  
else  
{  
DBGrid1->Canvas->Font->Color=clBlack;  
DBGrid1->Canvas->TextOut(Rect.Right-2-  
  DBGrid1->Canvas->TextWidth("F"),  
  Rect.Top+1,"F")    ;  
}  
}  
}  

Соответствующий код для Delphi имеет вид:


procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;  
  DataCol: Integer; Column: TColumn; State: TGridDrawState);  
begin  
if  (Column.FieldName='VenueNo')  then begin  
with  DBGrid1.Canvas do begin  
Brush.Color:=clWhite;  
FillRect(Rect);  
Font.Name:='Wingdings';  
Font.Size:=-14;  
if (Table1.FieldByName('VenueNo').Value=1) then begin  
Font.Color:=clRed;  
TextOut(Rect.Right-2-  
  DBGrid1.Canvas.TextWidth('J'),  
  Rect.Top+1,'J');  
end else begin  
 Font.Color:=clBlack;  
 TextOut(Rect.Right-2- DBGrid1.Canvas.TextWidth('F'),  
  Rect.Top+1,'F');  
end;  
end;  
end;  
end;  

Как поместить графическое изображение в TDBGrid
Использование свойства Canvas компонента TDBGrid в методе OnDrawColumnCell позволяет не только выводить в ячейке текст методом TextOut, но и размещать в ячейках графические изображения. В этом случае используется метод Draw свойства Canvas.

Модифицируем наш пример, добавив на форму компонент TImageList и поместив в него несколько изображений.

Модифицируем код нашего приложения:


void __fastcall TForm1::DBGrid1DrawColumnCell(TObject *Sender,  
      const TRect &Rect, int DataCol, TColumn *Column,  
      TGridDrawState State)  
{  
 Graphics::TBitmap *Im1;  
 Im1= new   Graphics::TBitmap;  
if  
(Column->FieldName=="VenueNo")  
{  
DBGrid1->Canvas->Brush->Color=clWhite;  
DBGrid1->Canvas->FillRect(Rect);  
if (Table1->FieldByName("VenueNo")->Value==1)  
{  
ImageList1->GetBitmap(0,Im1);  
}  
else  
{  
ImageList1->GetBitmap(2,Im1);  
}  
DBGrid1->Canvas->Draw((Rect.Left+Rect.Right-Im1->Width)/2,Rect.Top,Im1);  
}  
}  

Соответствующий код для Delphi имеет вид:


procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;  
  DataCol: Integer; Column: TColumn; State: TGridDrawState);  
var Im1: TBitmap;  
begin  
Im1:=TBitmap.Create;  
if  (Column.FieldName='VenueNo' ) then begin  
with  DBGrid1.Canvas do begin  
Brush.Color:=clWhite;  
FillRect(Rect);  
if (Table1.FieldByName('VenueNo').Value=1)  
then begin  
ImageList1.GetBitmap(0,Im1);  
end else begin  
ImageList1.GetBitmap(2,Im1);  
end;  
Draw(round((Rect.Left+Rect.Right-Im1.Width)/2),Rect.Top,Im1);  
end;  
end;  
end;  

Теперь в TDBGrid в колонке VenueNo находятся графические изображения.
Теги:
TDBGrid
Добавлено: 07 Августа 2018 08:18:46 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...