打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
DBGrid的应用举例 --逆水行舟




首先声明一下,本人是初学者,内容摘自《delphi source By killghost》

 
2006-01-18 19:58:12 云中霹雳

新建一个Application,在Form1上放Table1,DataSource1,DBGrid1,属性设置如下:

Table1 DatabaseName: DBDEMOS

TableName: EMPLOYEE.DB

Active: True;

DataSource1 DataSet: Table1

DBGrid1 DataSource1: DataSource1

 
2006-01-18 19:58:39 云中霹雳

以上是做下面功能的前奏

 
2006-01-18 19:58:50 fox

先介绍一下今天的主题吧。

一开门就是建工程[:L]

 
2006-01-18 19:59:12 云中霹雳

主题:DBGrid的应用举例

 
2006-01-18 19:59:29 云中霹雳

回车让光标右移动:

 
2006-01-18 19:59:48 云中霹雳

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);

begin

   if key=#13 then                          //如果按下回车

      DBGrid1.SelectedIndex:=DBGrid1.SelectedIndex+1;  

end;

 
2006-01-18 19:59:59 云中霹雳

这个是代码,应该容易理解吧

 
2006-01-18 20:00:15 小龙南翔/mg

OK

 
2006-01-18 20:00:15 云中霹雳

但是当光标到达一行的末尾的时候就下不去了,一直处于行末状态。我们需要当光标到达行末的时候光标会到达下一行的开始。于是代码修改为下面:

 
2006-01-18 20:00:36 云中霹雳

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);

begin

   if key=#13 then

   begin

      if DBGrid1.SelectedIndex<>5 then

         DBGrid1.SelectedIndex:=DBGrid1.SelectedIndex+1

      else

      begin

         table1.RecNo:=Table1.RecNo+1;

         DBGrid1.SelectedIndex:=0;

      end;

   end;

 
2006-01-18 20:00:56 云中霹雳

跟上面比较增加了recNO的设置

 
2006-01-18 20:00:57 Canny岑灿坤

谁有点击标题排序的图表阿姨

 
2006-01-18 20:01:25 Canny岑灿坤

就是三角箭头

 
2006-01-18 20:01:28 杭州-Tommy

先听讲,然后再提出疑问

 
2006-01-18 20:01:36 云中霹雳

要实现这个功能就得了解Selectedindex和RecNo的概念,可以通过delphi帮助了解selectedindex表示当前光标所在的位置,光标在grid中第一数据的话selectedindex的值为0,第二个的话为1,……   RecNo表示一个记录的号码,即Grid中行号,第一行的话表示1,第二行的话表示2,……。

 
2006-01-18 20:02:30 佛山-sislcb

if DBGrid1.SelectedIndex<>5 什么意思?

 
2006-01-18 20:02:40 佛山-sislcb

这里知道是五吗?

 
2006-01-18 20:02:55 云中霹雳

就是当还没到达一行的末尾的

 
2006-01-18 20:03:13 佛山-sislcb

是不是固定就是不等于五/

 
2006-01-18 20:03:15 云中霹雳

这个表就6列

 
2006-01-18 20:03:12 云中霹雳


2006-01-18 20:03:23 云中霹雳

所以我写了5

 
2006-01-18 20:03:37 云中霹雳

根据具体情况来

 
2006-01-18 20:03:52 云中霹雳

这个好了吗

 
2006-01-18 20:04:12 云中霹雳

隔行改变DBGrid网格颜色

云中霹雳 20:04:12

隔行改变DBGrid网格颜色

云中霹雳 20:04:27

 效果图:


云中霹雳 20:04:37


云中霹雳 20:05:22

用DBGrid1的DrawColumnCell方法

云中霹雳 20:05:46

这个方法在设置颜色等方面比较长用

云中霹雳 20:06:10

代码:procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;

  DataCol: Integer; Column: TColumn; State: TGridDrawState);

begin

 if gdSelected in State then Exit;  // 如果所在区域被选中

   if table1.RecNo mod 2 = 0 then     //偶数行

     (Sender as TDBGrid).Canvas.Brush.Color := clinfobk //定义背景颜色

 else

   (Sender as TDBGrid).Canvas.Brush.Color := RGB(191, 255, 223);  //定义背景颜色


 DBGrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State);//定义网格线的颜色:

云中霹雳 20:06:18

还没完。。。

云中霹雳 20:06:35

这个部分是设置行的颜色的代码

云中霹雳 20:06:44

有什么问题?

Canny岑灿坤 20:07:06

单击标题排序的图表有吗?


Canny岑灿坤 20:07:18

单击标题排序的图表有吗?

小箭头的

云中霹雳 20:07:19

没有


云中霹雳 20:08:00

with (Sender as TDBGrid).Canvas do //画 cell 的边框

 begin

   Pen.Color := $00ff0000; //定义画笔颜色(蓝色)

   MoveTo(Rect.Left, Rect.Bottom); //画笔定位

   LineTo(Rect.Right, Rect.Bottom); //画蓝色的横线

   Pen.Color := clGreen; //定义画笔颜色(绿)

   MoveTo(Rect.Right, Rect.Top); //画笔定位

   LineTo(Rect.Right, Rect.Bottom); //画绿色的纵线

 end;

end;

云中霹雳 20:08:30

这段是画线的


佛山-sislcb 20:09:42

不要只给代码,讲点原理

云中霹雳 20:10:24

怎么讲原理

佛山-sislcb 20:10:49

为什么要这样做?

云中霹雳 20:11:21

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;

  DataCol: Integer; Column: TColumn; State: TGridDrawState);

云中霹雳 20:11:24

先看这个

云中霹雳 20:11:37

sender就是所选的DBGrid

  佛山-sislcb 20:11:52

知道

云中霹雳 20:12:01

Rect就是选定的一个网格的区域

云中霹雳 20:12:26

具体就是在这个区域里面画颜色

  佛山-sislcb 20:12:56

ok

云中霹雳 20:12:58

if table1.RecNo mod 2 = 0 then

云中霹雳 20:13:37

这个就是控制当行的号码为偶数的时候,颜色设置成(Sender as TDBGrid).Canvas.Brush.Color := clinfobk 

云中霹雳 20:13:59

反之是奇数行设置

云中霹雳 20:14:45

隔列改变DBGrid的网格颜色

云中霹雳 20:15:15

 


云中霹雳 20:15:21

这个跟上面的隔行应该很相似

云中霹雳 20:15:33

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;

  DataCol: Integer; Column: TColumn; State: TGridDrawState);

begin

  if gdSelected in state then exit;   

  with DBGrid1.Canvas do

  begin

     if datacol mod 2=0 then   

        brush.Color:=clBlue

     else

        Brush.Color:=clAqua;

  end;

  DbGrid1.Canvas.pen.mode:=pmmask;

  DBGrid1.DefaultDrawColumnCell(Rect,Datacol,Column,state);

end;

云中霹雳 20:15:57

这里主要是根据datacol(列号)来控制



云中霹雳 20:17:08

在Delphi的DBGrid中插入其他可视组件

云中霹雳 20:17:26

Delphi提供了功能强大的 DBGrid组件,以方便进行数据库应用程序设计。但是如果我们仅仅利用DBGrid组件,每一个获得焦点(Grid)只是一个简单的文本编辑框,不方便用户输入数据。Delphi也提供了一些其他数据组件来方便用户输入,比如DBComboBox,DBCheckBox等组件,但这些组件却没有DBGrid功能强大。其实我们可以通过在DBGrid中插入其他可视组件来实现这一点。

云中霹雳 20:18:09

 例:分别拖动的Data Access组件板上DataSource、Table,Data Controls组件板上DBGrid,DBComboBox四个组件到Form1上。

云中霹雳 20:18:25

  Form1 Caption '在DBGrid中插入SpinEdit组件示例'

DataSource1 DataSet Table1

Table1  DatabaseName DBDEMOS

      TableName 'employee.db'

      Active True

DBGrid1      DataSource DataSource1

DBComboBox1 DataField  Firstname

              DataSource DataSource1

              Visible False

              Strings Items:'Kim'|'Bruce'|'Ann'|'Pete' 

云中霹雳 20:18:29

前奏


云中霹雳 20:24:15

 

云中霹雳 20:24:22

上面是效果图

云中霹雳 20:25:10

procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;

  Field: TField; State: TGridDrawState);

begin

     if (gdFocused in State) then

     begin

         if Field.FieldName=DBEdit1.DataField then

         begin

             DBEdit1.Left:=Rect.Left+DBGrid1.Left;

             DBEdit1.Top:=Rect.Top+DBGrid1.Top;

             DBEdit1.Width:=Rect.right-Rect.left;

             DBEdit1.Height:=Rect.Bottom-Rect.Top;

             DBEdit1.Visible:=True;

         end;


     end;

end;

云中霹雳 20:25:27

错了

云中霹雳 20:25:37

procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect; Field: TField; State: TGridDrawState);

begin

 if (gdFocused in State) then

 begin

   if (Field.FieldName = DBComboBox1.DataField ) then

   begin

     DBComboBox1.Left := Rect.Left + DBGrid1.Left;

     DBComboBox1.Top := Rect.Top + DBGrid1.top;

     DBComboBox1.Width := Rect.Right - Rect.Left;

     DBComboBox1.Height := Rect.Bottom - Rect.Top;

     DBComboBox1.Visible := True;

   end;

 end;

end;


云中霹雳 20:25:55

这个功能好象跟直接在DBGrid1.column[2]上的picklist中添加'Kim'|'Bruce'|'Ann'|'Pete'一样的功能,不知道后者是不是在以前的版本中没有的?


云中霹雳 20:28:10

 if (gdFocused in State) then   //如果state=gdfocused就是当cell处于焦点的时候,然后把DBComboBox1画到rect区域中

云中霹雳 20:28:30

上面这个例子中DBGrid指定单元格未获得焦点时不显示DBComboBox,设置DBGrid1的OnColExit事件如下:

procedure TForm1.DBGrid1ColExit(Sender: TObject);

begin

 If DBGrid1.SelectedField.FieldName = DBComboBox1.DataField then

   begin

     DBComboBox1.Visible := false;

   end;

end;

云中霹雳 20:29:55

当DBGrid指定列获得焦点时DrawDataCell事件只是绘制单元格,并显示DBComboBox,但是DBComboBox并没有获得焦点,数据的输入还是在单元格上进行。在DBGrid1的KeyPress事件中调用SendMessage这个 Windows API函数将数据输入传输到DBComboBox上,从而达到在DBComboBox上进行数据输入。因此还要设置KeyPress事件如下:

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);

begin

 if (key <> chr(9)) then

 begin

   if (DBGrid1.SelectedField.FieldName =DBComboBox1.DataField) then

   begin

     DBComboBox1.SetFocus;

     SendMessage(DBComboBox1.Handle,WM_Char,word(Key),0);

   end;

 end;

云中霹雳 20:30:36

LRESULT SendMessage(


    HWND hWnd,       // handle of destination window

    UINT Msg,     // message to send

    WPARAM wParam,       // first message parameter

    LPARAM lParam   // second message parameter

   );

云中霹雳 20:31:47

SendMessage(DBComboBox1.Handle,WM_Char,word(Key),0); 其中 DBComboBox1.handle是操作的实体

云中霹雳 20:32:04

WM_Char是消息类型

云中霹雳 20:32:24

WParam,LParam是传递的信息参数

云中霹雳 20:34:50

使dbgrid的某几笔资料变色 

 曾经拥有 20:35:53

这是干吗的?

云中霹雳 20:36:04

procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;

  Field: TField; State: TGridDrawState);

begin

 with TDBGrid(Sender) do

 begin

   if (条件) then

     Canvas.TextOut(Rect.Left + 4, Rect.Top + 2,'要显示的文字如表格的资料');

end;

云中霹雳 20:36:07

哪个?

 曾经拥有 20:36:10

这是干吗的?


云中霹雳 20:36:42

这个是在DBGrid里面自己输入文字


 曾经拥有 20:36:55

这些是干吗的?


云中霹雳 20:37:08

哪些?

 曾经拥有 20:37:30


这些是干吗的? 

云中霹雳 20:37:47

然后再

在 DBGrid.OnDrawColumnCell(...) 中:


begin

 if TableField.AsInteger < 0 then

   DBGrid.Canvas.Font.Color := clRed

 else

   DBGrid.Canvas.Font.Color := clBlack;

 DBGrid.DefaultDrawColumnCell(...);

end;

iamy 20:38:16

晕~


云中霹雳 20:38:16

上面那个没用

云中霹雳 20:38:52

什么

 曾经拥有 20:38:59


那这个呢?是干吗的?

云中霹雳 20:39:42

是在网格里面显示ComboBox


 曾经拥有 20:39:53

能用吗?

云中霹雳 20:39:59

   

云中霹雳 20:40:34

相当于直接在DBGRid1.column[index]里面设置picklist一样

 曾经拥有 20:40:51

ComboBox里面的数据是从哪里来的?

能动态改变吗?


云中霹雳 20:41:15

是在ComboBox的stringitem里面写好的

 曾经拥有 20:41:29

我试一下/。。。

云中霹雳 20:41:43

你可以对DBComboBox1进行操作来改变

 曾经拥有 20:42:14


云中霹雳 20:42:38

DBComboBox1.items.add()

 曾经拥有 20:42:53

 谢谢。

云中霹雳 20:43:42

点击DBGrid的Title对查询结果排序


云中霹雳 20:44:16

这个我还没弄怎么懂,大家一起来讨论一下

云中霹雳 20:44:26

欲实现点击DBGrid的Title对查询结果排序,想作一个通用程序,不是一事一议,例如不能在SQL语句中增加Order by ...,因为SQL可能原来已经包含Order by ...,而且点击另一个Title时又要另外排序,目的是想作到象资源管理器那样随心所欲。

云中霹雳 20:44:55

procedure TFHkdata.SortQuery(Column:TColumn);

var

 SqlStr,myFieldName,TempStr: string;

 OrderPos: integer;

 SavedParams: TParams;

begin

 if not (Column.Field.FieldKind in [fkData,fkLookup]) then exit;   // FieldKind to determine if a 

field is a data field, a calculated field, a lookup field, or an aggregate field.



 if Column.Field.FieldKind =fkData then

   myFieldName := UpperCase(Column.Field.FieldName)     

else

   myFieldName := UpperCase(Column.Field.KeyFields);   // Set KeyFields only on      

lookup fields

 while Pos(myFieldName,';')<>0 do                   //确定分号的位置

 myFieldName:=copy(myFieldName,1,Pos(myFieldName,';')-1)+','+    //取分号前面的字符

copy(myFieldName,Pos(myFieldName,';')+1,100);        //取分号后面的字符

 with TQuery(TDBGrid(Column.Grid).DataSource.DataSet) do    //查询功能

 begin

   SqlStr := UpperCase(Sql.Text);

   // if pos(myFieldName,SqlStr)=0 then exit;   

   if ParamCount>0 then

   begin

     SavedParams := TParams.Create;

     SavedParams.Assign(Params);

   end;

   OrderPos := pos('ORDER',SqlStr);

   if (OrderPos=0) or (pos(myFieldName,copy(SqlStr,OrderPos,100))=0) then

     TempStr := ' Order By ' + myFieldName + ' Asc'

   else if pos('ASC',SqlStr)=0 then

     TempStr := ' Order By ' + myFieldName + ' Asc'

   else

     TempStr := ' Order By ' + myFieldName + ' Desc';

   if OrderPos<>0 then SqlStr := Copy(SqlStr,1,OrderPos-1);

   SqlStr := SqlStr + TempStr;

   Active := False;

   Sql.Clear;

   Sql.Text := SqlStr;

   if ParamCount>0 then

   begin

     Params.AssignValues(SavedParams);

     SavedParams.Free;

   end;

   Prepare;

   Open;

 end;

end;

 曾经拥有 20:45:24

那怎么在DBGrid的Title显示三角和倒三角?

云中霹雳 20:45:25

好象被我弄的太乱了,原版发一下

云中霹雳 20:45:39

什么三角,倒三角?

 曾经拥有 20:45:41

那怎么在DBGrid的Title排序时显示三角和倒三角?


云中霹雳 20:46:09

就是用图表表示出来?

云中霹雳 20:46:15

图标?

 曾经拥有 20:46:16

不是。

云中霹雳 20:46:31

还是按从小到大还是从大到小?

 曾经拥有 20:46:54

你等等。。。

云中霹雳 20:47:06

procedure TFHkdata.SortQuery(Column:TColumn);

var

 SqlStr,myFieldName,TempStr: string;

 OrderPos: integer;

 SavedParams: TParams;

begin

 if not (Column.Field.FieldKind in [fkData,fkLookup]) then exit;

 if Column.Field.FieldKind =fkData then

   myFieldName := UpperCase(Column.Field.FieldName)

 else

   myFieldName := UpperCase(Column.Field.KeyFields);

 while Pos(myFieldName,';')<>0 do

 myFieldName := copy(myFieldName,1,Pos(myFieldName,';')-1)+ ',' + copy(myFieldName,Pos(myFieldName,';')+1,100);

 with TQuery(TDBGrid(Column.Grid).DataSource.DataSet) do

 begin

   SqlStr := UpperCase(Sql.Text);

   // if pos(myFieldName,SqlStr)=0 then exit;

   if ParamCount>0 then

   begin

     SavedParams := TParams.Create;

     SavedParams.Assign(Params);

   end;

   OrderPos := pos('ORDER',SqlStr);

   if (OrderPos=0) or (pos(myFieldName,copy(SqlStr,OrderPos,100))=0) then

     TempStr := ' Order By ' + myFieldName + ' Asc'

   else if pos('ASC',SqlStr)=0 then

     TempStr := ' Order By ' + myFieldName + ' Asc'

   else

     TempStr := ' Order By ' + myFieldName + ' Desc';

   if OrderPos<>0 then SqlStr := Copy(SqlStr,1,OrderPos-1);

   SqlStr := SqlStr + TempStr;

   Active := False;

   Sql.Clear;

   Sql.Text := SqlStr;

   if ParamCount>0 then

   begin

     Params.AssignValues(SavedParams);

     SavedParams.Free;

   end;

   Prepare;

   Open;

 end;

end;


 曾经拥有 20:47:31

显示倒三角 

云中霹雳 20:48:06

哦,那不知道了

杭州-Tommy 20:48:52

只是用个flag来判断下不就可以了?

深圳-♂沙子 20:49:05

有这个特殊符号,画上去的

 曾经拥有 20:49:18

那这个 是怎么显示出来的?

云中霹雳 20:49:39

procedure TForm1.DBGrid1TitleClick(Column: TColumn);

begin

     TFHkdata.SortQuery(Column);

end;

结束!

杭州-Tommy 20:50:00

不是可以设置它的title吗?后面再加上个三角形啊


云中霹雳 20:50:28

好象有道理可能就是这么弄的


曾经拥有 20:51:08

后面再加上个三角形啊


不是这样做的。。。

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
转载DBGrid和DBGridEH
在Delphi的DBGrid中插入其他可视组件
dbgrid 使用小结
Lazarus的DBGrid中回车键的处理
破邪掌
DBGrid中顯示多行的方法
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服