In Delphi, DBGrid uses the checkbox function in two ways. The simplest method is to use third-party controls, such as tdbgrideh, which is very convenient. The only drawback is that the compiled file is large, the size is about KB. Another relatively simple method is to use dbcheckbox in combination with DBGrid and draw controls. The following is a simple example of the latter implementation. For more information, see.
The use of dbcheckbox and DBGrid combined with the Method of Drawing controls can be encapsulated as controls for convenience in the future, but it is difficult to deploy the controls and may be difficult to modify when used by individuals, below we use a category class for encapsulation, so it is more convenient to modify the code and facilitate self-extension. The details are as follows:
The effect is shown in the following figure:
(1) The main code is as follows:
{*************************************** ****************}
{Description: TDBGrid Extension function control unit}
{Creater: Zhang Hao}
{Create Date: 22:40:12}
{Modifier :}
{Modify remark :}
{Modify Date: 16:00:00}
{Version: 1.0}
{*************************************** ****************}
Unit dbgridexcontroler;
Interface
Uses
Classes, dbgrids, grids, types, controls, dbctrls, windows, messages,
Sysutils, forms, dB;
Type
Tdbgridexcontroler = Class (tcomponent)
Private
{Private Declarations}
Fgrid: TDBGrid;
Fdbcheckbox: tdbcheckbox;
Fgridondrawcolumncell: tdrawcolumncellevent;
Fgridonenter: tpolicyevent;
Fgridoncolenter: tpolicyevent;
Fgridoncolexit: tpolicyevent;
Fgridonkeypress: tkeypressevent;
Fgridonmouseup: tmouseevent;
Fdatafield: widestring;
Fvaluechecked: string;
Fvalueunchecked: string;
Allowediting: Boolean;
/// <Summary>
/// Determine whether it is selected
/// </Summary>
Function arechecked (avalue: string): Boolean;
/// <Summary>
/// Set the event
/// </Summary>
Procedure setevents ();
Procedure setdatafield (avalue: widestring );
Procedure setvaluechecked (avalue: string );
Procedure setvalueunchecked (avalue: string );
Procedure setgrid (avalue: TDBGrid );
Procedure drawcolumncell (Sender: tobject; const rect: trect;
Datacol: integer; column: tcolumn; State: tgriddrawstate );
Procedure enter (Sender: tobject );
Procedure colenter (Sender: tobject );
Procedure colexit (Sender: tobject );
Procedure keypress (Sender: tobject; var key: Char );
Procedure mouseup (Sender: tobject; button: tmousebutton; shift: tshiftstate; X, Y: integer );
Procedure checkboxclick (Sender: tobject );
Public
{Public declarations}
Property datafield: widestring read fdatafield write setdatafield;
Property valuechecked: String read fvaluechecked write setvaluechecked;
Property valueunchecked: String read fvalueunchecked write setvalueunchecked;
Property grid: TDBGrid read fgrid write setgrid;
Constructor create (aowner: tcomponent); overload;
Constructor create (aowner: tcomponent; agrid: TDBGrid; adatafield: widestring;
Avaluechecked: String = 'true'; avalueunchecked: String = 'false'); overload;
Procedure setgriddrawcolumncellevent (avalue: tdrawcolumncellevent );
Procedure setgridenterevent (avalue: tpolicyevent );
Procedure setgridcolenterevent (avalue: tpolicyevent );
Procedure setgridcolexitevent (avalue: tpolicyevent );
Procedure setgridkeypressevent (avalue: tkeypressevent );
Procedure setgridmouseupevent (avalue: tmouseevent );
End;
Implementation
{$ Region 'event '}
Function tdbgridexcontroler. arechecked (avalue: string): Boolean;
Begin
Result: = sametext (TRIM (avalue), trim (fvaluechecked ));
End;
Procedure tdbgridexcontroler. drawcolumncell (Sender: tobject; const rect: trect;
Datacol: integer; column: tcolumn; State: tgriddrawstate );
Const ischecked: array [Boolean] of integer =
(Dfcs_buttoncheck, dfcs_buttoncheck or dfcs_checked );
VaR
Drawstate: integer;
Drawrect: trect;
Chkleft, chktop: integer;
Begin
If (gdfocused in State) or (gdselected in State) then
Begin
If (column. Field. fieldname = fdbcheckbox. datafield) then
Begin
Fdbcheckbox. Width: = 13;
Fdbcheckbox. Height: = 13;
Fdbcheckbox. Left: = fgrid. Left + rect. Left + (rect. Right-Rect.Left-fdbcheckbox. width) Div 2 + 2;
Fdbcheckbox. Top: = fgrid. Top + rect. Top + (rect. Bottom-Rect.Top-fdbcheckbox. Height) Div 2 + 2;
Fgrid. Canvas. fillrect (rect );
Fdbcheckbox. Visible: = true;
End
End
Else
Begin
If (column. Field. fieldname = fdbcheckbox. datafield) then
Begin
Drawrect: = rect;
Inflaterect (drawrect,-1,-1 );
Drawstate: = ischecked [arechecked (column. Field. asstring)];
Fgrid. Canvas. fillrect (rect );
Drawframecontrol (fgrid. Canvas. Handle, drawrect, dfc_button, drawstate );
End;
End;
If assigned (fgridondrawcolumncell) then
Fgridondrawcolumncell (sender, rect, datacol, column, State );
End;
Procedure tdbgridexcontroler. Enter (Sender: tobject );
Begin
If assigned (fgridonenter) then
Fgridonenter (sender );
// Solve the problem that the oncolenter of the grid is not executed when the grid obtains the focus and enters the first column.
If fgrid. selectedindex = 0 then colenter (sender );
End;
Procedure tdbgridexcontroler. colenter (Sender: tobject );
Begin
If fgrid. selectedfield. fieldname = fdbcheckbox. datafield then
Begin
Allowediting: = dgediting in fgrid. options;
If allowediting then
Fgrid. Options: = fgrid. Options-[dgediting];
End;
If assigned (fgridoncolenter) then
Fgridoncolenter (sender );
End;
Procedure tdbgridexcontroler. colexit (Sender: tobject );
Begin
If fgrid. selectedfield. fieldname = fdbcheckbox. datafield then
Begin
If allowediting and not (dgediting in fgrid. Options) then
Fgrid. Options: = fgrid. Options + [dgediting];
Fdbcheckbox. Visible: = false;
End;
If assigned (fgridoncolexit) then
Fgridoncolexit (sender );
End;
Procedure tdbgridexcontroler. keypress (Sender: tobject; var key: Char );
Begin
If (Key <> CHR (9) then
Begin
If (fgrid. selectedfield. fieldname = fdbcheckbox. datafield) then
Begin
Fdbcheckbox. setfocus;
Sendmessage (fdbcheckbox. Handle, wm_char, word (key), 0 );
Fgrid. datasource. dataset. Edit;
If arechecked (fgrid. selectedfield. asstring) then
Fgrid. selectedfield. asstring: = fvalueunchecked
Else
Fgrid. selectedfield. asstring: = fvaluechecked;
// Fgrid. selectedfield. asstring: = Not fgrid. selectedfield. asboolean;
Fgrid. datasource. dataset. post;
End;
End;
If assigned (fgridonkeypress) then
Fgridonkeypress (sender, key );
End;
Procedure tdbgridexcontroler. mouseup (Sender: tobject; button: tmousebutton; shift: tshiftstate; X, Y: integer );
Begin
If (fgrid. selectedfield. fieldname = fdbcheckbox. datafield) or (dgrowselect in fgrid. Options) then
Begin
// Within the range of checkbox
If (x + fgrid. Left> fdbcheckbox. Left) and (x + fgrid. Left <fdbcheckbox. Left + fdbcheckbox. width) and
(Y + fgrid. Top> fdbcheckbox. Top) and (y + fgrid. Top <fdbcheckbox. Top + fdbcheckbox. Height) then
Begin
Fdbcheckbox. setfocus;
With fgrid. datasource. dataset do
Begin
Edit;
If arechecked (fieldbyname (fdbcheckbox. datafield). asstring) then
Fieldbyname (fdbcheckbox. datafield). asstring: = fvalueunchecked
Else
Fieldbyname (fdbcheckbox. datafield). asstring: = fvaluechecked;
// Post;
End;
// Fgrid. datasource. dataset. Edit;
// Fgrid. datasource. dataset. fieldbyname (fdbcheckbox. datafield). asboolean: =
// Not fgrid. datasource. dataset. fieldbyname (fdbcheckbox. datafield). asboolean;
// Fgrid. datasource. dataset. post;
End;
End;
If assigned (fgridonmouseup) then
Fgridonmouseup (sender, button, shift, x, y );
End;
Procedure tdbgridexcontroler. checkboxclick (Sender: tobject );
Begin
// If tform (fgrid. Owner). Showing then
// If (fdbcheckbox. datasource <> nil) and (fdbcheckbox. datasource. dataset <> nil) then
// If (dsedit = fdbcheckbox. datasource. dataset. State) or (dsinsert = fdbcheckbox. datasource. dataset. State) then
// Fdbcheckbox. datasource. dataset. post;
End;
{$ Endregion}
Constructor tdbgridexcontroler. Create (aowner: tcomponent );
Begin
Inherited;
Fgrid: = nil;
Fdbcheckbox: = nil;
Fdatafield: = '';
Fvaluechecked: = 'true ';
Fvalueunchecked: = 'false ';
End;
Constructor tdbgridexcontroler. Create (aowner: tcomponent; agrid: TDBGrid;
Adatafield: widestring; avaluechecked: String = 'true'; avalueunchecked: String = 'false ');
Begin
Create (aowner );
Fgrid: = nil;
Fdbcheckbox: = nil;
Fgrid: = agrid;
Fdatafield: = adatafield;
Fvaluechecked: = avaluechecked;
Fvalueunchecked: = avalueunchecked;
Setevents ();
End;
Procedure tdbgridexcontroler. setdatafield (avalue: widestring );
Begin
Fdatafield: = avalue;
If fdbcheckbox <> nil then
Fdbcheckbox. datafield: = fdatafield;
End;
Procedure tdbgridexcontroler. setvaluechecked (avalue: string );
Begin
Fvaluechecked: = avalue;
If fdbcheckbox <> nil then
Fdbcheckbox. valuechecked: = fvaluechecked;
End;
Procedure tdbgridexcontroler. setvalueunchecked (avalue: string );
Begin
Fvalueunchecked: = avalue;
If fdbcheckbox <> nil then
Fdbcheckbox. valueunchecked: = fvalueunchecked;
End;
Procedure tdbgridexcontroler. setgrid (avalue: TDBGrid );
Begin
If fgrid <> avalue then
Begin
Fgrid: = avalue;
Setevents ();
End;
End;
Procedure tdbgridexcontroler. setgriddrawcolumncellevent (avalue: tdrawcolumncellevent );
Begin
Fgridondrawcolumncell: = avalue;
Fgrid. ondrawcolumncell: = self. drawcolumncell;
End;
Procedure tdbgridexcontroler. setgridenterevent (avalue: tpolicyevent );
Begin
Fgridonenter: = avalue;
Fgrid. onenter: = self. enter;
End;
Procedure tdbgridexcontroler. setgridcolenterevent (avalue: tpolicyevent );
Begin
Fgridoncolenter: = avalue;
Fgrid. oncolenter: = self. colenter;
End;
Procedure tdbgridexcontroler. setgridcolexitevent (avalue: tpolicyevent );
Begin
Fgridoncolexit: = avalue;
Fgrid. oncolexit: = self. colexit;
End;
Procedure tdbgridexcontroler. setgridkeypressevent (avalue: tkeypressevent );
Begin
Fgridonkeypress: = avalue;
Fgrid. onkeypress: = self. keypress;
End;
Procedure tdbgridexcontroler. setgridmouseupevent (avalue: tmouseevent );
Begin
Fgridonmouseup: = avalue;
Fgrid. onmouseup: = self. mouseup;
End;
/// <Summary>
/// Set the event
/// </Summary>
Procedure tdbgridexcontroler. setevents ();
Begin
If fgrid <> nil then
Begin
Fgridondrawcolumncell: = fgrid. ondrawcolumncell;
Fgridonenter: = fgrid. onenter;
Fgridoncolenter: = fgrid. oncolenter;
Fgridoncolexit: = fgrid. oncolexit;
Fgridonkeypress: = fgrid. onkeypress;
Fgridonmouseup: = fgrid. onmouseup;
Allowediting: = dgediting in fgrid. options;
Fgrid. ondrawcolumncell: = self. drawcolumncell;
Fgrid. onenter: = self. enter;
Fgrid. oncolenter: = self. colenter;
Fgrid. oncolexit: = self. colexit;
Fgrid. onkeypress: = self. keypress;
Fgrid. onmouseup: = self. mouseup;
If fdbcheckbox = nil then
Begin
Fdbcheckbox: = tdbcheckbox. Create (Self );
Fdbcheckbox. onclick: = self. checkboxclick;
Fdbcheckbox. Visible: = false;
End;
Fdbcheckbox. Parent: = fgrid. parent;
Fdbcheckbox. datasource: = fgrid. datasource;
Fdbcheckbox. datafield: = fdatafield;
Fdbcheckbox. valuechecked: = valuechecked;
Fdbcheckbox. valueunchecked: = valueunchecked;
End;
End;
End.
(2) Call method:
Unit examplefrm;
Interface
Uses
Windows, messages, sysutils, variants, classes, graphics, controls, forms,
Dialogs, dbgridexcontroler, DB, dbclient, grids, dbgrids, stdctrls, dbctrls,
Actnlist;
Type
Tform2 = Class (tform)
Dbgrd1: TDBGrid;
Cds1: tclientdataset;
Intgrfldcds1id: tintegerfield;
Strngfldcds1name: tstringfield;
Blnfldcds1checked: tbooleanfield;
Ds1: tdatasource;
Dbgrd2: TDBGrid;
Private
{Private Declarations}
Public
{Public declarations}
Dbgridexcontroler: tdbgridexcontroler;
// Dbgridexcontroler2: tdbgridexcontroler;
End;
VaR
Form2: tform2;
Implementation
{$ R *. DFM}
Procedure tform2.formcreate (Sender: tobject );
Begin
// If multiple fields are displayed in the checkbox, you only need to create multiple tdbgridexcontroler objects.
Dbgridexcontroler: = tdbgridexcontroler. Create (self, dbgrd1, 'checked ');
// Dbgridexcontroler2: = tdbgridexcontroler. Create (self, dbgrd1, 'id', '1', '0 ');
With cds1 do
Begin
Append;
Fieldbyname ('id'). asinteger: = 1;
Fieldbyname ('name'). asstring: = 'name1 ';
Fieldbyname ('checked'). asboolean: = false;
Post;
Append;
Fieldbyname ('id'). asinteger: = 2;
Fieldbyname ('name'). asstring: = 'name2 ';
Fieldbyname ('checked'). asboolean: = true;
Post;
Append;
Fieldbyname ('id'). asinteger: = 3;
Fieldbyname ('name'). asstring: = 'name3 ';
Fieldbyname ('checked'). asstring: = 'false ';
Post;
End;
End;
End.