1. Increase read-only properties
Adding read-only options to calendar controls is a straightforward process. By adding properties, you can provide a method that enables you to control read-only at design time, and when the property value is set to true, all elements in control are not selectable.
⑴ add private fields for attribute declarations and saved values:
Type
Tdbcalendar=class (Tclendar)
Private
Freadonly:boolean;
Public
Constructor Create (aowner:tcomponent); Override
Published
Property Readonly:boolean Read Freadonly write freadonly default True;
End
Constructor Tdbcalendar.create (aowner:tcomponent);
Begin
Inherited Create (Aowner);
Freadonly: = True;
End
⑵ overrides the Selectcell method so that the selection is not allowed when control is read-only:
function Tdbcalendar.selectcell (Acol, arow:longint): Boolean;
Begin
If Freadonly Then
Result: = False
Else
Result: = inherited Selectcell (Acol,arow);
End
Also declare Selectcell in the Tdbcalendar declaration.
If you now add calendar to the form, you will find that the part completely ignores the mouse and keystroke events, and you cannot change the location of the selection when you change the date. The following updates the control response.
2. Allow the required updates
A read-only calendar uses the Selectcell method to implement various changes, including setting row and Col values. When the date changes, the Updatecalendar method sets the values for row and col, but because Selectcell does not allow you to change, the choice remains where it is, even if the date changes.
You can add a Boolean flag to the calendar to allow changes when the flag is true:
Type
Tdbcalendar=class (Tcalendar)
Private
Fupdating:boolean;
Protected
function Selectcell (Acol, arow:longint); Boolean; Override
Public
Procedure Updatecalendar; Override
End
function Tdbcalendar.selectcell (Acol, arow:longint): Boolean;
Begin
if (not fupdating) and freadonly Then
Result: = False {If the update allows the selection}
Else
Result: = Inherited Selectcell (Acol, Arow); {Otherwise, invoke inherited methods}
End
Procedure Updatecalendar;
Begin
Fupdating: = True; {Set flag to allow updates}
Try
Inherited Updatecalendar; {update} as usual}
Finally
Fupdating: = False; {Always clear flag}
End
End
The calendar still does not allow the user to modify it, but when changing the date attribute, the change is reflected correctly; There is now a truly read-only control, and the next step is to increase data browsing capabilities.
3. Increase Data Connectivity
The control and database joins are handled by an object named Datalink. Delphi offers several types of datalink. The Datalink object that controls the control associated with a single domain of a database is Tfielddatalink. Delphi also provides a datalink that is associated with the entire table.
A data-related control has a Datalink object, that is, control is responsible for creating and Deconstructing datalink.
To establish a datalink as a owning object, perform the following three steps:
Declaring an Object field
Declaring access Properties
Initialize Datalink
⑴ declaring Object fields
Each part declares an object field for its owning object. Therefore, the Calendar object Datalink declares a tfielddatalink type of domain.
The Datalink declarations in the calendar part are as follows:
Type
Tdbcalendar = Class (Tsamplecalendar)
Private
Fdatalink:tfielddatalink;
...
End
⑵ Declaration Access Property
Each data-related control has a DataSource attribute that describes the data source that the application gives control to provide data. Also, a database that accesses a single domain requires a DataField property to describe the domain in the data source.
Here are the declarations of DataSource and DataField and how they are implemented:
Type
Tdbcalendar = Class (Tsamplecalendar)
The private {property is implemented by}
function getdatafield:string; {Returns the name of the database field}
function Getdatasource:tdatasource; {return reference to data source}
Procedure Setdatafield (const value:string); {Assign value to database field name}
Procedure Setdatasource (Value:tdatasource); {Assign value to data source}
Published {make properties available at design time}
Property datafield:string read Getdatafield write Setdatafield;
Property Datasource:tdatasource read Getdatasource write Setdatasource;
End
......
function TDBCalendar.GetDataField:string;
Begin
Result: = Fdatalink.fieldname;
End
function TDBCalendar.GetDataSource:TDataSource;
Begin
Result: = Fdatalink.datasource;
End
Procedure Tdbcalendar.setdatafield (const value:string);
Begin
Fdatalink.fieldname: = Value;
End
Procedure Tdbcalendar.setdatasource (Value:tdatasource);
Begin
Fdatalink.datasource: = Value;
End
Now, there's a chain of calendars and datalink, and a more important step. You must create the Datalink object when the calendar is built, and undo the Datalink object when the calendar is refactored.