我要的是在dbgrid中第一列的每一行都显示一个CheckBox,怎搞的。(50分)

  • 主题发起人 主题发起人 ivw
  • 开始时间 开始时间
I

ivw

Unregistered / Unconfirmed
GUEST, unregistred user!
我要的是在dbgrid中第一列的每一行都显示一个CheckBox,怎搞的。
 
DxDBGrid可以实现。用DX组件吧。
 
如果实在想用DBGRID,你需要自己画
 
dxexpress or infopower
 
我不想用第三方控件。
重画也行,但怎画呢
 
不想用,除非你是天才。
 
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if Column<>dbgrid1.Columns[0] then exit;
if (gdfocused in state) or (gdselected in state) then
begin
if (dbgrid1.SelectedIndex=0) then
With CheckBox1 do
Begin
CheckBox1 .Enabled :=true;
CheckBox1 .Caption :='是否选择';
CheckBox1 .Left :=rect.Left ;
CheckBox1 .Top :=rect.Top ;
CheckBox1 .Parent:=dbgrid1;
End;
end;
 
你这个问题比较麻烦,
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
ARect1: TRect;
CheckState: TCheckBoxState;

function iif(Condition: Boolean; V1, V2: Integer): Integer;
begin
if (Condition) then Result := V1 else Result := V2;
end;
function RectSize(ARect: TRect): TSize;
begin
Result.cx := ARect.Right - ARect.Left;
Result.cy := ARect.Bottom - ARect.Top;
end;

procedure DrawCheck(DC: HDC; R: TRect; AState: TCheckBoxState; AEnabled, AFlat, ADown, AActive: Boolean);
var
DrawState, oldRgn: Integer;
DrawRect: TRect;
Rgn, SaveRgn: HRgn;
begin
SaveRgn := 0;
oldRgn := 0;
DrawRect := R;
with DrawRect do
if (Right - Left) > (Bottom - Top) then
begin
Left := Left + ((Right - Left) - (Bottom - Top)) div 2;
Right := Left + (Bottom - Top);
end else if (Right - Left) < (Bottom - Top) then
begin
Top := Top + ((Bottom - Top) - (Right - Left)) div 2;
Bottom := Top + (Right - Left);
end;
case AState of
cbChecked:
DrawState := DFCS_BUTTONCHECK or DFCS_CHECKED;
cbUnchecked:
DrawState := DFCS_BUTTONCHECK;
else
DrawState := DFCS_BUTTON3STATE or DFCS_CHECKED;
end;
if not AEnabled then
DrawState := DrawState or DFCS_INACTIVE;
if ADown then
DrawState := DrawState or DFCS_PUSHED;

if AFlat then
begin
SaveRgn := CreateRectRgn(0, 0, 0, 0);
oldRgn := GetClipRgn(DC, SaveRgn);
with DrawRect do
Rgn := CreateRectRgn(Left + 1, Top + 1, Right - 1, Bottom - 1);
SelectClipRgn(DC, Rgn);
DeleteObject(Rgn);
end;
if AFlat then InflateRect(DrawRect, 1, 1);
DrawFrameControl(DC, DrawRect, DFC_BUTTON, DrawState);
if AFlat then
begin
if oldRgn = 0 then
SelectClipRgn(DC, 0)
else
SelectClipRgn(DC, SaveRgn);
DeleteObject(SaveRgn);
InflateRect(DrawRect, -1, -1);
if AActive
then FrameRect(DC, DrawRect, GetSysColorBrush(COLOR_BTNFACE))
else FrameRect(DC, DrawRect, GetSysColorBrush(COLOR_BTNSHADOW));

end;
end;

procedure PaintCheckBox(DC: HDC; ARect: TRect; ParentColor: TColor;
Flat, Active, Enabled: Boolean; State: TCheckBoxState);
var
ASize: TSize;
begin
ASize := RectSize(ARect);
if ASize.cx < ASize.cy then
begin
ARect.Top := ARect.Top + (ASize.cy - ASize.cx) div 2;
ARect.Bottom := ARect.Bottom - (ASize.cy - ASize.cx) div 2 - (ASize.cy - ASize.cx) mod 2;
end else if ASize.cx > ASize.cy then
begin
ARect.Left := ARect.Left + (ASize.cx - ASize.cy) div 2;
ARect.Right := ARect.Right - (ASize.cx - ASize.cy) div 2 - (ASize.cx - ASize.cy) mod 2;
end;
DrawCheck(DC, ARect, State, Enabled, Flat, False, Active);
end;

begin
with DBGrid1 do
if Column.Field.DataType = ftBoolean then
begin

if Column.Field.AsBoolean then
CheckState := cbChecked
else
CheckState := cbUnchecked;
Canvas.FillRect(Rect);
ARect1.Left := Rect.Left + iif(Rect.Right - Rect.Left < DefaultCheckBoxWidth, 0,
(Rect.Right - Rect.Left) shr 1 - DefaultCheckBoxWidth shr 1);
ARect1.Right := iif(Rect.Right - Rect.Left < DefaultCheckBoxWidth, Rect.Right,
ARect1.Left + DefaultCheckBoxWidth);
ARect1.Top := Rect.Top + iif(Rect.Bottom - Rect.Top < DefaultCheckBoxHeight, 0,
(Rect.Bottom - Rect.Top) shr 1 - DefaultCheckBoxHeight shr 1);
ARect1.Bottom := iif(Rect.Bottom - Rect.Top < DefaultCheckBoxHeight, Rect.Bottom,
ARect1.Top + DefaultCheckBoxHeight);
PaintCheckBox(Canvas.Handle, ARect1,
Canvas.Brush.Color, False, False, True, CheckState);
end;
end;
 
我以前练习用的:
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if Column<>dbgrid1.Columns[0] then exit;
if (gdfocused in state) or (gdselected in state) then
begin
if (dgfocused in state) and (column.field=table1senior)then
Begin
dbcheckbox1.setbounds(rect.lest+dbgrid1.left+1,
rect.top+dbgrid1.top+1,
rect.right-rect.left,
rect.bottom-rect.top)
End;
end;

procedure tform1.dbgridcolenter(sender:Tobject);
begin
if dbgrid1.columns[dbgrid1..selectedindex].field=table1senior then
dbcheckbox1.visble:=true
else
dbcheckbox1.visble:=false;
end;

procedure tform1.dbgrid1keypress(sender:tobject;var key:char)
begin
if (dbcheckbox1.visble) and (ord(key))>31 then
begin
key:=#0;
dbcheckbox1.check:=not dbcheckbox1.checked
end;
end;
 
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
Begin
If Column<>DBGrid1.Column[0] then Exit;
DBGrid1.Canvas.Brush.Color := DBGrid1.Color;
DBGrid1.Canvas.FillRect(Rect); //擦掉显示的值
If DBGrid1.DataSource.DataSet.Fields[0].AsString='0' then //如果是0,只画框
DBGrid1.Canvas.Rectangle(Rect.Left + 2,Rect.Top + 2, Rect.Left+12,Rect.Top+12)
Else
  //是1则画个框再画个叉(有兴趣可改为勾)
Begin
DBGrid1.Canvas.Pen.Color := clBlack;
DBGrid1.Canvas.Rectangle(Rect.Left + 2,Rect.Top + 2, Rect.Left+12,Rect.Top+12);
DBGrid1.Canvas.MoveTo(Rect.Left + 2,Rect.Top + 2);
DBGrid1.Canvas.LineTo(Rect.Left+12,Rect.Left+12,Rect.Top+12);
DBGrid1.Canvas.MoveTo(Rect.Left+12,Rect.Top + 2);
DBGrid1.Canvas.LineTo(Rect.Left + 2 ,Rect.Top +12);
End;
End;
 
其实我建议你用第三方的控件,别人DBGridEH,
如果自己做比较麻烦,你要控制很多地方,楼上的方法也可以,但是
你要将DBGrid的Options属性中的dgEditing属性设为False,
 
用第三方组件吧。
 
多人接受答案了。
 
后退
顶部