Delphi is convenient and fast to develop C/S applications because it has a large number of easy-to-use data access and data-aware controls. However, everything is always difficult to perfect. DELPHI's DBEdit control is very inconvenient for entering date and time fields. In order to improve this disadvantage, the author has developed a DBDateTime data-aware control, which greatly facilitates the input of time and date. When creating a widget, the most important step is to select the correct parent class, which can reduce the writing of the code. DELPHI's component library already has a TDateTimePicker component, which can easily enter and change dates and time by pulling the calendar or using SpinButton increment and decrement, but it does not have the ability to sense data. Therefore, we can take it as the parent class and derive a new control, plus the data-aware function that can communicate with the data set. Data-aware controls interact with DataSource through DataLink objects, so adding data-awareness to the control requires creating a TDataLink (or its derived class) object as a member of the control, and creating public DataField and DataSource properties for the control; then responding to the TDataLink object OnDataChange and OnUpdateData events. Below is the main source code of the control, with corresponding comments: {Define the TDBDateTime class derived from TDateTimePicker. Note that DB should be added to the Uses of the unit interface, DBCTRLS reference}type
TDBDateTime=class(TDateTimePicker)
PRivate
FDataLink:TFieldDataLink;
//TFieldDataLink is a derived class of TDataLink that handles the interaction of a single field with a DataSource
procedureDataChange(sender:Tobject);
// When the OnDataChange event is triggered when the record of the DataSet changes (such as browsing history), DataChange will be used as the event handling handle for the event
procedureUpdateData(sender:Tobject);
// The OnUpdateData event is triggered before updating the DataSet, UpdateData will be used as the event processing handle for the event
functionGetDataSource:TDataSource;
procedureSetdataSource(value:TDataSource);
FunctionGetDataField:String;
procedureSetdataField(Value:String);
procedureCMexit(varMessage:TCMExit);message CM_EXIT;//Flashes CM_EXIT message when the control loses focus
protected
procedureChange;override;// OnChange event is triggered when the date and time in the control change.
procedureNotification(AComponent:TComponent;
Operation:Toperation);override;
//DELPHI's IDE calls this method to notify other controls when a control is removed from the FORM
public
constrUCtorCreate(AOwner:Tcomponent);override;
destructorDestroy;override;
lished
propertyDataSource:TDataSourcereadGetDataSource
writeSetDataSource;//Add DataSource property to the control so that it can be connected to the DataSource component
propertyDataField:StringreadGetDataField
writeSetDataField;
end;//Add DataField attribute to the control,
Make it point to a TField object representing a field
procedureRegister;//Register component
Implementation
procedureTDBDateTime.CMExit;
Begin
try
FDataLink.UpdateRecord;
// Update DataSet when the control loses focus, which will trigger the OnUpdateData event
except
Setfocus;
raise;
end;
DoExit;
end;
constructorTDBDateTime.Create(Aowner:Tcomponent);
Begin
inheritedCreate(Aowner);
//Create DataLink object, mount OnDataChange,
OnUpdateData event processing handle
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;
//If the control is connected to the active DataSet, the dataset will change
The control displays the corresponding field value of the current record
ifFDataLink.Field nilthen
ifFDataLink.Field.Text then
DateTime:=FDatalink.Field.AsDateTime;
end;
ProcedureTDBDateTime.UpdateData(sender:Tobject);
Begin
FDatalink.Field.AsDateTime:=DateTime;
//Update the corresponding fields with the date and time in the control
end;
procedureTDBDateTime.Change;
Begin
// Set DataSet to edit state when the user changes the content in the control
FDataLink.Modified;
ifnotFDataLink.Editingthen
FdataLink.Edit;
inheritedChange;
end;
procedureTDBDateTime.Notification(AComponent:
TComponent;Operation:TOperation);
Begin
inheritedNotification(Acomponent,Operation);
// When the TdataSource connected to the control is
Set the control's DataSource property to empty when deleted
if(Operation=opRemove)and(FDataLink nil)
and(AComponent=Datasource)then
DataSource:=nil;
end;
procedureRegister;
Begin
RegisterComponents(DataControls,
[TDBDateTime]);// After the control is registered, it is installed on the DataControls page
end;
end.
After installation, this control can pull down the calendar and increase or decrease the date and time fields of the database, and can display dates in two formats, which is convenient and practical. The controls are safe and reliable in DELPHI3 and DELPHI4.