DBGrid控件使用技巧

发表于:2007-07-04来源:作者:点击数: 标签:
DBGrid控件使用技巧 [返回] 中国计算机报2001年第54期 DBGrid控件使用技巧 刘遵雄 C++ Builder是著名的快速可视化 开发 工具(RAD)之一,它和Delphi共用可视化类库VCL,由于其具有C++语言良好的可操作性,可以用来编写出高效率、高 质量 的应用程序代码
DBGrid控件使用技巧

[返回]
中国计算机报2001年第54期

DBGrid控件使用技巧

刘遵雄

  C++ Builder是著名的快速可视化开发工具(RAD)之一,它和Delphi共用可视化类库VCL,由于其具有C++语言良好的可操作性,可以用来编写出高效率、高质量的应用程序代码,因而越来越受广大程序员的欢迎。

  C++ Builder具有强大的数据操作能力,其集成开发环境(IDE)的控件板给用户提供了大量的数据访问控件,通过对有关数据库控件属性进行适当设置,合理地引用其方法来控制事件,能极大地方便数据库应用程序的创建。

  C++ Builder控件板上提供了数据库应用程序开发中所要使用的控件,其中,数据访问页(Data Aclearcase/" target="_blank" >ccess Page)控件板上的控件用于直接访问数据库中的数据库表,而数据控制页(Data Control Page)控件板上的控件用来与用户交互、显示、修改数据库中的数据,DBGrid就是其中一种功能强大的数据控制控件,它用于全屏幕显示和编辑数据库表中的记录,表现为网格的形式。本文主要介绍DBGrid控件使用过程中的一些技巧。


  实现动态数据排序


  DBGrid控件不具备访问磁盘数据库的能力,它是必须通过DataSource控件来实现的。其属性DataSource指向某一DataSource控件,而DataSource控件的DataSet属性指向的数据集可以是TTable或TQuery控件。通过使用TQuery控件动态编程,我们可以实现程序运行时单击DBGrid控件的标题部分,数据即可按选定字段排序的功能。具体实现过程如下:

  新建工程,在Form1上拖放TQuery、TDatasource 和 TDbGrid控件,Name属性分别是Query1、Datasource1和DbGrid1,然后将它们关联起来,Query1 的DatabaseName属性指向DBDEMOS,DbGrid1的Datasource属性设为Datasource1,Datasource1的Dataset属性值设为Query1。在Form1的CPP文件对应的头文件中声明AnsiString型变量QuerySQL,用于存放SQL语句内容。在Form1的OnActivate事件中检索数据,编写如下代码:

  void __fastcall TForm1::FormActivate(TObject ?Sender)

  {

   QuerySQL = "SELECT ? FROM Customer.DB";

   Query1->SQL->Add(QuerySQL);

   Query1->Open();

  }

  使DbGrid1控件显示的数据排序的关键是在DbGrid1的OnTitleClick事件中编程改变Query1的SQL语句内容,程序如下:

  void __fastcall TForm1::DBGrid1TitleClick(TColumn ?Column)

  {

   AnsiString str;

   int i;

   str= Column->FieldName ;

  //获取鼠标点击数据栏的字段名称

   Query1->DisableControls();

   Query1->Close();

   Query1->SQL->Clear();

   Query1->SQL->Add(QuerySQL);

   Query1->SQL->Add("ORDER BY "+str);

   Query1->Open();

   DBGrid1->Columns->RestoreDefaults();

   //使鼠标点击的数据栏的标题改变颜色

   for (int i = 0; i < i < Query1->FieldCount; i++)

   {

   //遍历Query1的字段,判断其是否是鼠标点击的字段

   if (Query1->Fields->Fields[i]->FieldName ==str)

   {

  DBGrid1->Columns->Items[i]->Title->Font->Color= clRed;

   DBGrid1->Columns->Items[i]->Title->Alignment= taCenter;//标题居中

   } ;

   };

   Query1->EnableControls();

  }


  在数据栏中显示图像


  使用DBGrid1控件来全屏显示编辑数据时,为了使界面生动活泼,我们希望能根据字段枚举数值(其取值通常为几个特定值)的不同显示不同的图像。

  我们可以在DBGrid控件的OnDrawColumnCell事件中编写代码来增强DBGrid控件的显示效果,如果其DefaultDrawing属性为true,DBGrid控件在OnDrawColumnCell事件响应前按默认效果显示,然后以此为基础执行OnDrawColumnCell事件的代码。需要完全取代DBGrid控件的显示效果时,可将其DefaultDrawing属性设为false,并在OnDrawColumnCell事件中编写控制显示效果的脚本。如果希望某些列产生特定效果,可以在OnDrawColumnCell事件中调用DefaultDrawColumnCell方法,然后修正特定列的输出效果。以下示例是在DBGrid控件数据栏中显示图像效果的程序。

  新建工程,在Form1上拖放TTable、TDatasource 、TDbGrid和TImageList控件,Name属性分别是Table1、Datasource1、DbGrid1和ImageList1,然后将它们关联起来,Table1 的DatabaseName属性指向DBDEMOS(该别名指代C++ Builder自带的例程数据库表)、TableName属性为Clients.dbf、Datasource1的Dataset属性值为Table1、DbGrid1的Datasource属性等于Datasource1。使用DbGrid1的列编辑器让DbGrid1仅显示Last_Name、First_Name、Risk_Level和 Occupation四个字段,再设置DbGrid1的DefaultDrawing属性为false,然后设置ImageList1存放向下、向上、向左的三种箭头图像。DBGrid1的On DrawColumnCell事件代码如下:

  void __fastcall TGridDrawForm::DBGrid1DrawColumnCell(TObject ?Sender,

   const TRect &&Rect, int DataCol, TColumn ?Column,TGridDrawState State)

  {

  if (DBGrid1->Columns->Items[DataCol]->FieldName == "RISK_LEVEL")

   {

   DBGrid1->Canvas->FillRect(Rect);

   if (DBGrid1->Columns->Items[DataCol]->Field->AsString == "LOW")

   {//字段值为“LOW”,绘制向下的箭头

   ImageList1->Draw(DBGrid1->Canvas,Rect.Left+4,Rect.Top,0,True);

   }

   else if (DBGrid1->Columns->Items[DataCol]->Field->AsString == "MED")

   {//字段值为“MED”,绘制向左的箭头

   ImageList1->Draw(DBGrid1->Canvas,Rect.Left+4,Rect.Top,1,True);

   }

   else

   {//否则绘制向上的箭头

   ImageList1->Draw(DBGrid1->Canvas,Rect.Left+4,Rect.Top,2,True);

   }

   }

   else

   DBGrid1->DefaultDrawColumnCell(Rect,DataCol,Column,State);

   }

   当绘制DBGrid时,绘制屏幕上当前可见行的每个数据单元都调用上述事件过程。DataCol用于显示DBGrid的Columns属性的顺序。根据DataCol值可以确定将绘制的数据单元的栏目名称。此例中,如果栏目的字段不是“Risk_Level”则调用DefaultDrawColumnCell方法,使其成默认的显示效果。反之,则先调用FillRect方法清除背景,然后根据该字段值的不同,调用ImageList的Draw方法,实施对象是DBGrid控件的画布对象,Rect中参数Left和Top值决定了绘制坐标的位置,图像列表中不同的值决定了产生图像的不同。


  将当前行以不同颜色显示


   DBGrid控件中当前的数据通常是用蓝色背景显示的,有时我们为了达到提示及操作界面美化方面的要求,希望能将DBGrid控件显示的数据用不同的颜色背景显示,比如红色。我们只需将DBGrid控件的Option属性中的dgRowSelect值设为true,在DBGrid控件的OnDrawColumnCell事件中编写程序,根据某行是否有方格被选中或是否处于活动状态来改变DBGrid控件中画布Canvas的Brush对象的颜色值,然后调用DefaultDrawColumnCell方法。

   以前面实现动态数据排序的程序为基础,在DBGrid1的OnDrawColumnCell事件中编写如下代码:

  void __fastcall TForm1::DBGrid1DrawColumnCell(TObject ?Sender, const TRect &&Rect, int DataCol, TColumn ?Column, TGridDrawState State)

  {//如果某行有方格被选中,则置以红色背景,否则设成白色

   if (State.Contains(gdFocused) || State.Contains(gdSelected))

   {

   DBGrid1->Canvas->Brush->Color=clRed;

   }

   else

   {

   DBGrid1->Canvas->Brush->Color= clWhite ;

   };

   DBGrid1->DefaultDrawColumnCell(Rect,DataCol,Column,State);

  }

   我们同样可以根据DBGrid控件显示的数据行某个字段值的不同,应用OnDrawColumnCell事件改变该行数据的字体颜色或背景颜色。


  禁止控件自动添加空行


  使用DBGrid控件全屏显示数据记录时,若DBGrid控件Option属性的dgEditting值设置是true,或者DBGrid控件的各个显示字段Column的ReadOnly属性值是false时,当达到最后一条记录行并继续敲击键盘下箭头键,DBGrid控件会增加新行,这样可能会引起数据输入问题,大部分时间我们并不希望如此。

  为解决此问题,我们可以将DBGrid控件Option属性的dgEditting值设置为false,或者将DBGrid控件的显示字段Column的ReadOnly属性值设置为true,但是会产生DBGrid控件显示数据不可编辑的问题,我们可以用下面的两种方法来加以解决:

  1.可以编辑DBGrid控件引用的DataSource控件对应的数据集Table的BeforeInsert事件,只需在其中写入Abort即可。代码如下:

  void __fastcall TForm1::Query1BeforeInsert(TDataSet ?DataSet)

  {

  Abort;

  }

  2.通过DBGrid1的onKeydown事件判别是否按了“下箭头”键和Table1的记录是否为最末记录,人为地改变当前记录行,DBGrid控件显示数据的当前行与数据集的当前行是一致的。

  void __fastcall TForm1::DBGrid2KeyDown(TObject ?Sender, WORD &&Key,

   TShiftState Shift)

  {

  if (Key = VK_DOWN)//判断按键是否为下箭头键

   {//是,使Table1记录指针下移一条记录,再判断是否是表尾

   Table1->DisableControls() ;

   Table1->Next() ;

   if (Table1->Eof)

   { Key = 0 ;}

  //是表尾,赋Key值为0,不添加空行

   else

   {Table1->Prior();} ;

  //将表的记录指针回移到原位置

   Table1->EnableControls() ;

   }

  }

  以上,笔者谈了DBGrid控件的几种使用技巧,其实程序开发中有许多技巧能够使应用程序更好地满足用户的需求,利用不同开发工具的程序开发人员可以互相借鉴,使开发的应用程序更加精致。

原文转自:http://www.ltesting.net