DBGrid内使用CheckBox功能
? Delphi內DBGrid使用CheckBox功能一般有兩種方法,最簡單的就是使用第三方控件,如TDBGridEh,使用非常方便,唯一的缺點就是編譯出的文件大,大概要大500KB那個樣子。另外一種相對簡單的方法就是使用DBCheckBox與DBGrid結合并使用繪制控件的方法實現,下面是使用后者實現的一個簡單示例,不足之處請指教。
??????使用DBCheckBox與DBGrid結合并使用繪制控件的方法實現可以封裝為控件以便以后方便使用,但控件部署麻煩,個人使用的話修改麻煩,下面我們使用一個實用類進行了封裝,這樣修改代碼也比較方便,便于自行擴展。具體如下:
效果見圖:
(1)主要代碼如下:
{*******************************************************}
{ Description : TDBGrid 擴展功能控制單元??????????????????????? }
{ Creater : 張皓??????????????????????????????????????? }
{ Create Date : 2010-6-30 22:40:12????????????????????? }
{ Modifier :??????????????????????????????????????????? }
{ Modify Remark :?????????????????????????????????????? }
{ Modify Date : 2010-7-7 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:TNotifyEvent;
??? FGridOnColEnter:TNotifyEvent;
??? FGridOnColExit:TNotifyEvent;
??? FGridOnKeyPress:TKeyPressEvent;
??? FGridOnMouseUp:TMouseEvent;
??? FDataField:WideString;
??? FValueChecked:string;
??? FValueUnchecked:string;
??? AllowEditing:Boolean;
??? /// <summary>
??? /// 判斷是否是選中
??? /// </summary>
??? function AreChecked(AValue:string):Boolean;
??? /// <summary>
??? /// 設置事件
??? /// </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:TNotifyEvent);
??? procedure SetGridColEnterEvent(AValue:TNotifyEvent);
??? procedure SetGridColExitEvent(AValue:TNotifyEvent);
??? procedure SetGridKeyPressEvent(AValue:TKeyPressEvent);
??? procedure SetGridMouseUpEvent(AValue:TMouseEvent);
? end;
implementation
{$REGION '事件'}
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);
? // 解決當Grid獲取焦點且進入第一列時Grid的OnColEnter不執行的問題
? 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
??? // 在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:TNotifyEvent);
begin
? FGridOnEnter:=AValue;
? FGrid.OnEnter:=Self.Enter;
end;
procedure TDBGridExControler.SetGridColEnterEvent(AValue:TNotifyEvent);
begin
? FGridOnColEnter:=AValue;
? FGrid.OnColEnter:=Self.ColEnter;
end;
procedure TDBGridExControler.SetGridColExitEvent(AValue:TNotifyEvent);
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>
/// 設置事件
/// </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.
?
(二)調用方法:
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
??// 如有多個字段都顯示CheckBox只需創建多個TDBGridExControler對象即可
? 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.
轉載于:https://www.cnblogs.com/zhmore/archive/2010/07/01/1768821.html
總結
以上是生活随笔為你收集整理的DBGrid内使用CheckBox功能的全部內容,希望文章能夠幫你解決所遇到的問題。