声明:该篇转载自百度空间http://hi.baidu.com/382943850/blog/item/a5c17cd87687d23632fa1cec%2Ehtml
解决方法:修改引用的顺序
Windows, Messages, SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,ComCtrls,ExtCtrls, StdCtrls, Buttons, DB,ADODB, ImgList, DBCtrls, Mask, GridsEh, DBGridEh,Grids, DBGrids;
//系统默认最先找后面单元中匹配的方法。
由DBGrid与DBGridEh的冲突,引发关于uses单元们的作用顺序的思考
我在编一个铁路物流货场管理程序时,用到了表格控件,最初,我用了DBGrid,但DBGrid无法直接设置表格的行高,于是我删掉DBGrid,改用DBGridEh。至此一切正常。后来我发现其实行高不必控制,于是我又把DBGridEh删掉,换做DBGrid。至此仍然一切正常。
然后,问题来了。由于表格显示的数据记录需要区分来货和走货,也就是说根据操作数量的正负,用不同的颜色显示每一条记录。于是我在DBGrid的OnDrawColumnCell事件里写代码设置颜色,并用DefaultDrawColumnCell方法重绘表格。代码写好后,运行......奇怪!在DefaultDrawColumnCell那一行怎么提示“Incompatible types”错误?
我脑袋开始晕了。应该不会是我设置和代码的问题啊!这个程序很大,从头至尾编来,我几乎没有犯过任何错误的。无奈,旁观者清,我求助于网友伴水清清。伴水说,是不是有哪个单元没有引用啊?
伴水一言提醒了我。乖乖,倒不是哪个单元没有引用,而是多引用了DBGridEh的两个单元!(向窗体上拖放DBGridEh时自动添加的,而删掉控件时添加的单元并不自动删除)于是我把uses部分的GridsEh, DBGridEh这两个单元引用删掉,OK。
由此我想,虽然DBGridEh和DBGrid的DefaultDrawColumnCell方法参数数量是相同的。但DBGridEh的DefaultDrawColumnCell方法的某个参数与DBGrid的该方法的某个参数的类型有细微不同。然后,编译器对于同名方法实际是overload或override的(具体是哪个操作,我没看,不敢乱说)。也就是说,假设在uses部分先后有A、B两个单元,都有一个Proc方法,如果在程序中不指明使用的是哪个单元的Proc方法,编译器会默认使用后者单元。
我懒得去查看DBGridEh是如何定义DefaultDrawColumnCell方法的,朋友们可以去看一下,如果我说得不对,麻烦您联系我指正。
为了让大家体会这个冲突,请使用下面的演示程序:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, DBGrids, GridsEh, DBGridEh, DB, DBTables;
type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
DBGridEh1: TDBGridEh;
DataSource1: TDataSource;
Table1: TTable;
procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
procedure DBGridEh1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumnEh; State: TGridDrawState);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
{ //先把下面的代码注掉,程序是可以正常编译运行的
with TDBGrid(Sender) do begin
if DataSource.DataSet.RecNo mod 2 = 0 then
Canvas.Font.Color := clBlue
else
Canvas.Font.Color := clRed;
DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
}
end;
procedure TForm1.DBGridEh1DrawColumnCell(Sender: TObject;const Rect: TRect; DataCol:Integer; Column: TColumnEh;
State: TGridDrawState);
begin
with TDBGridEh(Sender) do begin
if DataSource.DataSet.RecNo mod 2 = 0 then
Canvas.Font.Color := clBlue
else
Canvas.Font.Color := clRed;
DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Self.Table1.Close;
Self.Table1.DatabaseName := 'DBDEMOS';
Self.Table1.TableName := 'animals.dbf';
Self.DataSource1.DataSet := Table1;
Self.DBGrid1.DataSource := DataSource1;
Self.DBGridEh1.DataSource := DataSource1;
Self.Table1.Open;
end;
end.
编译运行上面的程序,会成功通过。
然后,如果把uses部分“GridsEh, DBGridEh,”这两个单元引用往前移两个位置,移到“Grids, DBGrids,”前面去,就会出错。
如果把程序中注释掉的部分去掉注释,那么,随着“GridsEh, DBGridEh,”和“Grids,DBGrids,”两个的谁在前谁在后,程序出错的位置也分别变换出现在两个DefaultDrawColumnCell方法上。