创建一个构件时,最重要的一步是选择正确的父类,这样可以减少代码的编写。DELPHI的构件库中已有一个TDateTimePicker构件,可以以下拉日历或利用SpinButton递增、递减的方式方便地输入和改变日期、时间,但它没有数据感知的能力。因此,我们可以以它为父类,派生出一个新的控件,加上能与数据集通信的数据感知功能。
数据感知控件通过DataLink对象与DataSource进行交互,所以为控件增加数据感知能力需要创建一个TDataLink(或其派生类)对象作为控件的成员,并为控件创建公开的DataField和DataSource属性;然后需响应TDataLink对象的OnDataChange和OnUpdateData事件。下面是控件的主要源代码,并带有相应的注释:
{定义从TDateTimePicker派生的TDBDateTime类。注意,在单元接口的Uses中应加入DB,DBCTRLS引用}type TDBDateTime=class(TDateTimePicker) private FDataLink:TFieldDataLink; //TFieldDataLink是TDataLink的派生类,处理单个字段与DataSource的交互 procedureDataChange(sender:Tobject); //当DataSet的记录改变(如浏览记录)时触发OnDataChange事件,DataChange将作为该事件的事件处理句柄 procedureUpdateData(sender:Tobject); //更新DataSet前触发OnUpdateData事件,UpdateData将作为该事件的事件处理句柄 functionGetDataSource:TDataSource; procedureSetdataSource(value:TDataSource); FunctionGetDataField:String; procedureSetdataField(Value:String); procedureCMexit(varMessage:TCMExit);message CM_EXIT;//当控件失去焦点时触发CM_EXIT消息 protected procedureChange;override;//控件中日期、时间改变时触发OnChange事件 procedureNotification(AComponent:TComponent; Operation:Toperation);override; //当某一控件从FORM上移走时DELPHI的IDE调用该方法通知其它控件 public constructorCreate(AOwner:Tcomponent);override; destructorDestroy;override; lished propertyDataSource:TDataSourcereadGetDataSource writeSetDataSource;//为控件增加DataSource属性,使它能与DataSource构件连接 propertyDataField:StringreadGetDataField writeSetDataField; end;//为控件增加DataField属性, 使它指向代表某一字段的TField对象
procedureRegister;//注册构件
implementation
procedureTDBDateTime.CMExit; begin try FDataLink.UpdateRecord; //控件失去焦点时更新DataSet,这将触发OnUpdateData事件 except Setfocus; raise; end; DoExit; end;
constructorTDBDateTime.Create(Aowner:Tcomponent); begin inheritedCreate(Aowner); //创建DataLink对象,挂接OnDataChange、 OnUpdateData事件处理句柄 FDataLink:=TFieldDataLInk.Create; FDataLink.OnDataChange:=DataChange; FDataLink.OnUpdateData:=Updatedata; end;
DestructorTDBDateTime.Destroy; begin FDataLink.OnDataChange:=nil; FDataLink.OnUpdateData:=nil; FDataLink.Free; inheritedDestroy; end;
functionTDBDateTime.GetdataSource:TdataSource; begin result:=FDataLink.DataSource; end;
ProcedureTDBDateTime.SetDataSource(Value:TDataSource); begin FDataLink.DataSource:=Value; end;
functionTDBDateTime.GetDatafield:String; begin result:=FDataLink.FieldName; end;
procedureTDBDateTime.SetDataField(value:String); begin FdataLink.FieldName:=value; end;
procedureTDBDateTime.DataChange(Sender:Tobject); begin DateTime:=now; //若控件连了活动的DataSet则数据集变动时 控件显示当前记录的相应字段值 ifFDataLink.Field nilthen ifFDataLink.Field.Text then DateTime:=FDatalink.Field.AsDateTime; end;
ProcedureTDBDateTime.UpdateData(sender:Tobject); begin FDatalink.Field.AsDateTime:=DateTime; //用控件中的日期、时间更新相应字段 end;
procedureTDBDateTime.Change; begin //当用户改变了控件中的内容时将DataSet置为编辑状态 FDataLink.Modified; ifnotFDataLink.Editingthen FdataLink.Edit; inheritedChange; end;
procedureTDBDateTime.Notification(AComponent: TComponent;Operation:TOperation); begin inheritedNotification(Acomponent,Operation); //当与控件相连的TdataSource 被删除时将控件的DataSource属性置为空 if(Operation=opRemove)and(FDataLink nil) and(AComponent=Datasource)then DataSource:=nil; end;
procedureRegister; begin RegisterComponents(DataControls, [TDBDateTime]);//控件注册后安装于DataControls页 end;
end.
本控件安装后能以下拉日历和递 增递减方式改变数据库的日期时间型字段,并能以长、短两种格式显示日期,方便实用。控件在DELPHI3、DELPHI4中使用安全可靠。
|
请发表评论