Li Xiaoping / Hebei Gu'an North China Petroleum University
---- Whether it is developing what kind of procedure, data input is indispensable. It is undoubtedly greatly improved the efficiency of program development in a beautiful input interface. The original controls of the system often do not even satisfactorily. In Delphi, if the optional control is dblabel, dbedit, etc. if a field is for a field; if the full table is input, there is DBGRID. When using the controls such as DBEDIT, the user must fully arrange the location of each field, although it can achieve aesthetic effect, but if the number of fields, it is undoubtedly a troublesome. If you use DBGRID, no matter how many fields, only one control is enough, simply, it is simple, but each field is a word arrangement, it is a bit inconvenient to use. For a general user, adopt the form of entry is convenient and beautiful. This is the problem you have to solve this article.
---- Technical Key
---- The main function of this Control is to implement editing of the database field. According to the general rules, the control should contain TDATALINK objects, and should be implemented with TDATAlink; however, a lot of code will be consumed. The larger the code amount, the more complicated the system, the greater the possibility of error. The development idea of this control is to achieve the most functionality with the least code. So, the editing of the data field directly uses the TDBCOMBOBOX control.
---- In order to achieve versatility, a field editing control array and field title array is maintained inside the control. as follows:
Editors: array of tdbcombobo;
-> Data controls used in specific editing, dynamically generated
Array of TLABEL;
-> Title of each field, dynamic generation
---- TDBCOMBOBOX advantage is that it can not only have a general editing function, but also add a corresponding prompt information for each field. code show as below:
{Add a message to the i-th field}
Procedure tdbpanel.addhits
(Itemindex: Integer; Hits: array of string);
VAR
m, n, i: integer;
Begin
N: = Length (Editors);
M: = Length (HITS);
IF itemIndex For i: = 0 to m-1 do editors [itemindex] .Items.Add (Hits [i]); END; END; ---- Specific application is a thousand words, so the control also needs to have enough event processing interface to implement specific functions in specific applications. This requires a certain event processing method for user implementation in the control. Here is an onokclick event that is performed after all field editing is completed. code show as below: Okbutton: tbutton; -> Last increased determination button for implementation of the submission action. Property OnokClick: TNOTIFYEVENT Read Fclick Write Fclick; ---- By implementing the onokclick method, users can complete various processing work such as submission, data rationality. Another need specially processed the conversion between various fields. The default is to click on the mouse. However, users' habits are often four arrow keys in the keyboard "upper, lower, left, right". To achieve this feature, you need to define two methods: Procedure akeypress (Sender: TOBJECT; VAR Key: char); Procedure akeydown (sender: TOBJECT) Var key: word; shift: tshiftstate; --- assigning the above two methods to dynamically generated Editors to implement the response to the arrow keys. ---- Different table fields are different, there is a possibility that there is no display, which requires scrolling features. So, insert a TScrollBox control in the control. The last thing you need to pay attention is that the revoking and memory release of dynamic controls. The removal of the array of controls and the release of memory is sequentially - the order in which the created is complete. Otherwise it will be wrong. ---- Use of controls ---- First put the DBPANEL control on the form, then set the data source properties, the number of columns of the data input table, and so on. In the program, after the data source is turned on, the method of creating a data editing control is called. which is: Query1.Open; -> Open data source DBPANEL1.CREATEDITORS; -> Edit control of each field DBPANEL1.ADDHITS (0, ['1111', '11222', 'eeee']); -> Set the prompt information for a certain field DBPANEL1.ADDHITS (1, ['1111', '11222', 'Eeee']); -> Set the prompt information for a certain field This control and sample program debug passes in the Win98 Delphi 5.0 environment. ---- Attachment: TDBPANEL source code Unit dbpanel; Interface Uses Windows, Messages, Sysutils, Classes, Graphics, Controls, Forms, Dialogs, EXTCTRLS, DBCTRLS, STDCTRLS, DB; Type TDBPANEL = Class (TPANEL) Private {Private Declarations} Fleft: integer; FTOP: Integer; MaxTextlen: Integer; Maxlabellen: integer; FScrollbox: TscrollBox; {Scrolling Controls} FLINEHEIGHT: Integer; Fclick: tnotifyeent; Editors: array of tdbcombobo; -> Data controls used in specific editing, dynamically generated Array of TLABEL; -> Title of each field, dynamic generation Okbutton: tbutton; -> Last increased determination button for implementation of the submission action. { data source} FDataSource: TDataSource; FColumns: integer; -> Enter the number of columns in the table protected {Protected Declarations} Procedure freeeditors; -> Release data input controls public Procedure createEditors; // (DS: TDataSource; colcount: integer); -> Data input control for creating each field Constructor Create (Aowner: Tcomponent; Override; DESTRUCTOR DESTROY; OVERRIDE; Procedure akeypress (Sender: TOBJECT; VAR Key: char); Procedure akeydown (Sender: TOBJECT; VAR Key: Word; Shift: TshiftState; Procedure Clearhits (ItemInDex: Integer); Procedure Addhits (ItemIndex: Integer; Hits: array of string; Function Editor (INDEX: Integer): TDBCOMBOBOX; {Public declarations} Published Property LeftLimit: Integer Read Fleft Write Fleft default 10; Property Toplimit: Integer Read FTOP WRITE FTOP DEFAULT 10; Property editorlen: integer read Maxtextlen Write MaxTextlen; Property Labellen: Integer Read Maxlabellen Write Maxlabellen Default 100; Property Lineheight: Integer Read FLINEHEIGHT WRITE FLINEHEIGHT DEFAULT 15; Property OnokClick: TNOTIFYEVENT Read Fclick Write Fclick; Property DataSource: TDataSource Read FDataSource Write FDataSource; -> Data Source Property Column: Integer Read Fcolumns Write Fcolumns; -> Table Column {Published Declarations} END; PROCEDURE register; IMPLEMENTATION PROCEDURE register; Begin Registercomponents ('additional', [tdbpanel]); END; {Add a message to the i-th field} Procedure TDBPanel.Addhits (ItemIndex: Integer; Hits: array of string; VAR m, n, i: integer; Begin N: = Length (Editors); M: = Length (HITS); IF itemIndex For i: = 0 to m-1 do editors [itemindex] .Items.Add (Hits [i]); END; END; Procedure tdbpanel.akedown (Sender: TOBJECT; VAR Key: Word; Shift: tshiftstate; Begin IF (sender is tdbcombobo) THEN BEGIN Case Key of VK_Next: (Sender as TDBCOMBOBOX) .Datasource.DataSet.next; VK_Prior: (Sender as TDBCOMBOBOX) .Datasource.DataSet.Prior; END; END; END; Procedure TDBPanel.akeypress (Sender: TOBJECT; VAR Key: char); Begin IF (sender is tdbcombobo) THEN BEGIN If key = # 13 dam (Owner as TForm) .Perform (wm_nextdlgctl, 0, 0); END; END; Procedure Tdbpanel.clearhits (ItemIndex: Integer); VAR N: integer; Begin N: = Length (Editors); IF ItemIndex Constructor TDBPANEL.CREATE (Aowner: Tcomponent); Begin Inherited Create (Aowner); Fleft: = 10; FTOP: = 10; Maxtextlen: = 100; Maxlabellen: = 100; FLINEHEIGHT: = 15; END; {Method for creating data input controls for each field} Procedure tdbpanel.createEditors; // (DS: TDataSource; colcount: integer); VAR I, N, RowCount: Integer; Textheight: integer; Begin if DataSource.DataSet.Active The Begin N: = datasource.dataset.fieldcount; {Calculated maximum title length and display length} DataSource.DataSet.first; {Calculation height} Textheight: = Canvas.TextHeight (Datasource .Dataset.fields [0] .displayLabel) FlineHeight; // 10; {Calculation rantric number} Rowcount: = n Div Column; IF N MOD Column <> 0 THEN INC (Rowcount); { Allocate memory} Freeeditors; SETLENGTH (Editors, N); SETLENGTH (Labels, N); {Creating a scroll box} Fscrollbox: = TscrollBox.create (Owner); Fscrollbox.parent: = Self; FscrollBox.Align: = AlClient; {Creation editing} For i: = 0 to n-1 do begin {Creation title} Labels [I]: = TLABEL.CREATE (OWNER); Labels [i] .parent: = fscrollbox; // Self; Labels [i] .caption: = datasource.dataset.fields [i] .displaylabel; Labels [i] .left: = fleft (MaxLabellen Maxtextlen 10) * (i Div Rowcount); Labels [i] .width: = Maxlabellen; Labels [i] .top: = ftop (i mod rowcount) * TextHeight 5; {Create editing object} Editors [I]: = TDBCOMBOBOX.CREATE (OWNER); Editors [i] .parent: = fscrollbox; // Self; Editors [I] .left: = labels [i] .left labels [i] .width; Editors [i] .width: = MaxTextlen; Editors [i] .top: = ftop (i mod rowcount) * textHeight; Editors [i] .datasource: = Datasource; Editors [i] .datafield: = Datasource.DataSet.fields [i] .fieldname; Editors [i] .onkeypress: = akeypress; editors [i] .onkeydown: = akeydown; END; {Create OK button} Okbutton: = TButton.create (Owner); Okbutton.parent: = fscrollbox; Okbutton.Left: = Editors [N-1] .left; Okbutton.top: = Editors [N-1] .top textheight; Okbutton.caption: = 'determination'; Okbutton.onclick: = fclick; END; END; DESTRUCTOR TDBPANEL.DESTROY; Begin Freeeditors; Inherited destroy; END; Function TDBPAnel.editor (INDEX: Integer): TDBCOMBOBOX; Begin If Index Else Result: = NIL; END; Procedure tdbpanel.freeeditors; VAR I, N: Integer; Begin {Memory release is the order! Must be carried out in the opposite order of creation! Especially when there is a father and child relationship between the components. IF okbutton <> nil dam.free; IF Editors <> nil dam N: = Length (Editors); For i: = 0 to n-1 do editors [i] .free; Editors: = NIL; N: = Length (labels); For i: = 0 to n-1 do labels [i] .free; Labels: = NIL; END; IF fscrollbox <> nil damin Fscrollbox.free; Fscrollbox: = NIL; END; END; End.