请帮助我!我想在DBGrid中用CheckBox控件替代逻辑字段的显示。(200分)

  • 主题发起人 主题发起人 wxemail
  • 开始时间 开始时间
可以在 OnDraw 時控制,拉一個 CheckBox 控件蓋在格子上即可。
 
希望以下代码对你有帮助:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids;

type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
procedure StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormCreate(Sender: TObject);
procedure StringGrid1TopLeftChanged(Sender: TObject);
private
{ Private declarations }
public
procedure cbxOnExit(Sender: TObject);// 定义释放Combobox过程
{ Public declarations }
end;

var
Form1: TForm1;

Last_ACol : integer = -1;
Last_ARow : integer = -1;

implementation

{$R *.DFM}

procedure TForm1.cbxOnExit(Sender: TObject); //定义释放Combobox过程
var i : integer;
begin
for i := Form1.ComponentCount -1 downto 0 do
if Form1.Components is TCombobox then
if (Form1.Components as TCombobox).Tag = 100 then
begin
if (Last_ARow <> -1) and (Last_ACol <> -1) then
begin //把combobox的取值赋予格子
StringGrid1.Cells[Last_ACol, Last_ARow]:= (Form1.Components as TCombobox).Text;
end;

(Form1.Components as TCombobox).Free;
StringGrid1.refresh;
end;
end;


procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);

function GetLeft(aCol: Integer): Integer;//获得左边距坐标函数
var ii,jj: integer;
begin
JJ := 1;
for ii := 0 to ACol -1 do
JJ := JJ + StringGrid1.ColWidths[ii]+1;
Result := JJ;
end;

function GetTop(ARow:Integer): Integer; //获得TOP坐标函数
var ii, JJ : integer;
begin
JJ := 1;
for ii := 0 to ARow-1 do
JJ := JJ + StringGrid1.RowHeights[ii]+1;

Result := JJ;
end;

var cbx : TCombobox;
i, J : Integer;
aCol, ARow : Integer;
begin
cbxOnExit(Sender);//释放在本列生成的combobox
j := 1;
ACol := -1;
for i := 0 to StringGrid1.ColCount -1 do
begin
J := J + StringGrid1.ColWidths+1;
if J >= X then
begin
ACol := i;
Break;
end;
end;

J := 1;
ARow := -1;
for i := 0 to StringGrid1.RowCount -1 do
begin
J := J + StringGrid1.RowHeights+1;
if J >= Y then
begin
ARow :=i;
Break;
end;
end;

ACol := ACol + StringGrid1.LeftCol -1; //相对
ARow := ARow + StringGrid1.TopRow -1;

Last_ARow := ARow;
Last_ACol := ACol;

if (ARow = -1) or (ACol=-1) then Exit;

if (ACol = 1) and ( ARow <> 0 ) then //绝对
begin
cbx := TCombobox.Create(Self);
cbx.Parent := form1; //combobox的拥有者是form1;
cbx.Tag := 100; //作窗体元件标志;

cbx.Items.Add('空闲');
cbx.Items.Add('占用');

cbx.Left := StringGrid1.Left + GetLeft(ACol-StringGrid1.LeftCol +1 ) ;
cbx.Top := StringGrid1.Top + GetTop(ARow -StringGrid1.TopRow +1) ;
cbx.Width := StringGrid1.ColWidths[ACol]+ 1;
cbx.Style := csDropDownList;
cbx.ItemIndex := cbx.Items.IndexOf(StringGrid1.Cells[ACol, ARow]);
onExit := cbxOnExit;

cbx.Visible := True;
end;

end;

procedure TForm1.FormCreate(Sender: TObject);
var i :integer;
begin
for i := 0 to StringGrid1.RowCount -1 do
StringGrid1.Cells[0, i] := intToStr(i);

for i := 0 to StringGrid1.ColCount -1 do
StringGrid1.Cells[i, 0] := intToStr(i);

end;


procedure TForm1.StringGrid1TopLeftChanged(Sender: TObject);
begin
cbxOnExit(Sender);

end;

end.
 
用DBGridEh,很方便的
 
DBGridEh那里有?如果您有的话能不能<A HREF ="mailto:devuser@sina.com">Email给我一份</A>
Email: devuser@sina.com
 
有现成的说教,我就不写了!:)


在DBGrid 网 格 中 实 现 下 拉 列 表, 设 置 好DBGrid 中 该 字 段 的PickList
字 符 串 列 表、 初 始 的 序 号 值DropDownRows 即 可。 以 职 工 信 息 库 中
的 籍 贯 字 段( 字 符 串 类 型) 为 例, 具 体 设 计 步 骤 如 下:
1、 在 窗 体 上 放 置Table1、DataSource1、DBGrid1、DBNavigator1 等 控 件 对 象,
按 下 表 设 置 各 个 对 象 的 属 性:

---------------------------------------
对象 属性 设定值
---------------------------------------
Table1 DataBase sy1
Table zgk.dbf //职工信息库
DataSource1 DataSet Table1
DbGrid1 DataSource DataSource1
DBNavigator1 DataSource Datasource1
-------------------------------------------
2、 双 击Table1, 在 弹 出 的Form1.Table1 窗 口 中, 用 右 键 弹 出 快 捷 菜 单,
单 击Add Fields 菜 单 项; 选 择 所 有 的 字 段 后, 按OK 按 钮。
3、 修 改 第2 步 新 增 字 段 的DisplayLabel 属 性。 以Table1ZGBH 字 段 为 例,
在Object Inspector 窗 口 中 选 择Table1ZGBH, 修 改 属 性DisplayLabel= 职 工 编
号, 其 余 字 段 类 似。
4、 双 击DBGrid1, 在 弹 出 的Editing DBGrid1.Columns 窗 口 中, 单 击
Add all Fields 按 钮, 增 加Table1 的 所 有 字 段。
5、 在Editing DBGrid1.Columns 窗 口, 选 择jg 这 一 行, 切 换 到
Object Inspector 窗 口, 修 改 它 的PickList.Strings 为“ 湖 北 枝 江 市
( 换 行) 北 京 市( 换 行) 河 南 平 顶 山 市( 换 行) 浙 江 德 清 市”
6、 在Form1.Oncreate 事 件 中 写 入 语 句:
Table1.Open;
7、F9 运 行, 用 鼠 标 点 击 某 个 记 录 的 籍 贯 字 段, 右 边 即 出 现 一 个
按 钮, 点 击 这 个 按 钮, 可 出 现 一 个 下 拉 列 表, 包 含 第5 步 中 输 入
的 四 行 字 符 串, 可 用 鼠 标 进 行 选 择。 当 然 也 可 以 自 行 输 入 一 个
并 不 属 下 拉 列 表 中 的 字 符 串。
 
对啊,用gcq的方法就挺好的
 
只能用下拉选择,没办法用 CheckBox 了,将就吧。
 
将DBGRID关联到一个TImages组件即可.
 
可以改写DBGRID控件,我已经改写成功了,方法:
改DBGrids单元,改 TCustomDBGrid.drawcell方法, 在 WriteText过程前加入判断字段
的语句,若为你所要的字段则转到自已的处理方法,我就已做了一个和access97差不多的DBGrid

 
为了分只好不怕麻烦了。
procedure TForm1.DBgrid1drawcolumncell(....);
begin
if column.field=复选字段名 then
begin
dbcheckbox1.setbounds(
rect.left+dbgrid1.left+1,
rect.top+dbgrid1.top+1,
rect.right-rect.left,
rect.bottom-rect.top)
end;
end;
procedure TForm1.dbgrid1colenter(..);
begin
if dbgrid1.columns[dbgrid1.selectedindex].field=复选字段名 then
dbcheckbox1.visible:=true
else
dbcheckbox1.visible:=false;
end;
procedure TForm1.dbgrid1keypress(..);
begin
if dbcheckbox1.visible and(ord(key)>31) then
begin
key:=#0;
table1.edit;
dbcheckbox1.checked:=not dbcheckbox.checked;
dbcheckbox1.field.asboolean:=dbcheckbox1.checked;
end;
end;
 
这些办法都不好。
 
补充一下
事件procedure TForm1.DBgrid1drawcolumncell(....);中第一行应该是
if (column.fieldname=复选字段名)and(gdfocused in state) then
 
begin
end;//结束
 
procedure TFrmBankDay.DBGrid1DrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn;
State: TGridDrawState);
if (gdFocused in State) and
(Column.Field = DMBase.TBBankDayCheckIFID) then
begin
DBCheckBoxCheckIF.SetBounds (
Rect.Left + DBGrid1.Left + 1,
Rect.Top + DBGrid1.Top + 1,
Rect.Right - Rect.Left,
Rect.Bottom - Rect.Top);
end;



procedure TFrmBankDay.DBGrid1ColEnter(Sender: TObject);
begin
inherited;
if DBGrid1.Columns [DBGrid1.SelectedIndex].
Field = DMBase.TBBankDayCheckIFID then
begin
// DBGrid1.DrawColumnCell(
dbgrid1.Refresh;//按Enter键改变列进入该栏时,必须Refresh触发Redraw
DBCheckBoxCheckIF.Visible := True;
end
else
DBCheckBoxCheckIF.Visible := False;
 
多人接受答案了。
 
后退
顶部