RSS订阅 | 匿名投稿
您的位置:网站首页 > 数据库 > 正文

delphi DBgrid应用全书

作者:admin 来源: 日期:2013/11/15 11:34:38 人气: 标签:DBgrid

在 Delphi 语言的数据库编程中,DBGrid 是显示数据的主要手段之一。但是 DBGrid 缺省的外观未免显得单调和缺乏创意。其实,我们完全可以在我们的程序中通过编程来达到美化DBGrid 外观的目的。通过编程,我们可以改变 DBGrid 的表头、网格、网格线的前景色和背景色,以及相关的字体的大小和风格。
    以下的示例程序演示了对 DBGrid 各属性的设置,使 Delphi 显示的表格就像网页中的表格一样漂亮美观。
    示例程序的运行:
    在 Form1 上放置 DBGrid1、Query1、DataSource1 三个数据库组件,设置相关的属性,使 DBGrid1 能显示表中的数据。然后,在 DBGrid1 的 onDrawColumnCell 事件中键入以下代码,然后运行程序,就可以看到神奇的结果了。本代码在 Windows98、Delphi5.0 环境下调试通过。
procedure TMainForm.DBGrid1DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;State: TGridDrawState);
var i :integer;
begin
  if gdSelected in State then Exit;
//定义表头的字体和背景颜色:
    for i :=0 to (Sender as TDBGrid).Columns.Count-1 do
    begin
      (Sender as TDBGrid).Columns[i].Title.Font.Name :=\'宋体\'; //字体
      (Sender as TDBGrid).Columns[i].Title.Font.Size :=9; //字体大小
      (Sender as TDBGrid).Columns[i].Title.Font.Color :=$000000ff; //字体颜色(红色)
      (Sender as TDBGrid).Columns[i].Title.Color :=$0000ff00; //背景色(绿色)
    end;
//隔行改变网格背景色:
  if Query1.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);
  with (Sender as TDBGrid).Canvas do //画 cell 的边框
  begin
    Pen.Color := $00ff0000; //定义画笔颜色(蓝色)
    MoveTo(Rect.Left, Rect.Bottom); //画笔定位
    LineTo(Rect.Right, Rect.Bottom); //画蓝色的横线
    Pen.Color := $0000ff00; //定义画笔颜色(绿色)
    MoveTo(Rect.Right, Rect.Top); //画笔定位
    LineTo(Rect.Right, Rect.Bottom); //画绿色的竖线
  end;
end; 
2003-11-5 17:30:00    
查看评语???    
2003-11-5 17:31:41    
原来还有这个办法啊,在没有DevExpress之前....
我会陆续添加的 
2003-11-11 17:07:42    问题: Delphi5 - 隔行改变DBGrid网格颜色 
   在 Form1 上放置 DBGrid1、Query1、DataSource1 三个数据库组件,设置相关的属性,使 DBGrid1 能显示表中的数据。然后,在 DBGrid1 的 onDrawColumnCell 事件中键入以下代码,然后运行程序
代码:
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var i:integer;
begin
  if gdSelected in State then Exit;  //隔行改变网格背景色: 
    if adoQuery1.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);
  with (Sender as TDBGrid).Canvas do //画 cell 的边框
  begin
    Pen.Color := $00ff0000; //定义画笔颜色(蓝色)
    MoveTo(Rect.Left, Rect.Bottom); //画笔定位
    LineTo(Rect.Right, Rect.Bottom); //画蓝色的横线
    Pen.Color := clbtnface; //定义画笔颜色(兰色)
    MoveTo(Rect.Right, Rect.Top); //画笔定位
    LineTo(Rect.Right, Rect.Bottom); //画绿色
  end;
end;
用BDE中的table1未能通过,颜色没有隔行变化。  
2003-11-11 17:12:09    在Delphi的DBGrid中插入其他可视组件 
   Delphi提供了功能强大的 DBGrid组件,以方便进行数据库应用程序设计。但是如果我们仅仅利用DBGrid组件,每一个获得焦点(Grid)只是一个简单的文本编辑框,不方便用户输入数据。Delphi也提供了一些其他数据组件来方便用户输入,比如DBComboBox,DBCheckBox等组件,但这些组件却没有DBGrid功能强大。Delphi能不能象Visual Foxpro那样让DBGrid中获得焦点网格可以是其它可视数据组件以方便用户呢?其实我们可以通过在DBGrid中插入其他可视组件来实现这一点。
    Delphi对DBGrid处理的内部机制,就是在网格上浮动一个组件——DBEdit组件。你输入数据的网格其实是浮动DBEdit组件,其他未获得焦点地方不过是图像罢了。所以,在DBGrid中插入其他可视组件就是在网格上浮动一个可视组件。因此任何组件,包括从简单的DbCheckBox到复杂的对话框,都可以在DBGrid中插入。下面就是一个如何在DBGrid中插入DBComboBox组件的步骤,采用同样的办法可以插入其他组件。
  1、在Delphi 4.0中新建一个项目。
  2、分别拖动的Data Access组件板上DataSource、Table,Data Controls组件板上DBGrid,DBComboBox四个组件到Form1上。
  3、设置各个组件的属性如下:
rcf1对象 属性 设定植
Form1 Caption \'在DBGrid中插入SpinEdit组件示例\'
DataSource1 DataSet Table1
Table1 DatabaseName DBDEMOS
TableName \'teacher.DBF\'
Active True
DBGrid1 DataSource DataSource1
DBComboBox1 DataField SEX
DataSource DataSource1
Visible False
Strings Items. \'男\'| \'女\'
注意:我在这里用了Teacher.dbf,那是反映教职工的性别,只能是“男”或者是“女”。
  4、DrawDataCell事件是绘制单元格,当获得焦点网格所对应的字段与组合框所对应的字段一致时,移动组合框到获得焦点的网格上,并且使组合框可视,从而达到在DBGrid指定列上显示DBComboBox的功能。设置DBGrid1的OnDrawDataCell事件如下:
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;
  5、DBGrid指定单元格未获得焦点时不显示DBComboBox,设置DBGrid1的OnColExit事件如下:
procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
  If DBGrid1.SelectedField.FieldName = DBComboBox1.DataField then
    begin
      DBComboBox1.Visible := false;
    end;
end;
  6、当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;
end;
    程序在中文Windows 98,Delphi 4.015 下调试通过。希望本文能使你可以更加方便快捷的开发数据库应用程序。   
 
锁定DBGrid左边的列 
   我在使用 Delphi3 进行数据库编程的时候,希望 DBGRID 构件在显示数据的时候能象FoxPro 的 BROWSE 命令一样,锁定左边指定的几列不进行滚动,请问应用什么方法来实现?
    我们知道 Delphi 的 TStringGrid 有一个属性 FixedCols 来指定不滚动的列。虽然TDBGrid 不能直接使用这一属性,但通过强制类型转换也可以首先这一功能,因为这两个类都来自 TCustomGrid 类。下面我们以 Delphi 3.0的 Demos\\Db\\CtrlGrid 为例来说明具体的用法。在这个例子的 TFmCtrlGrid.FormShow 过程中加入如下一行: 
    TStringGrid(DbGrid1).FixedCols := 2; 
    运行该程序,在左右移动各列时,Symbol 列不会移动。除了这种方法,也可以采用下面的方法:首先在 Form 声明部分加上
    type TMyGrid = Class(TDBGrid) end; 
    然后在 TFmCtrlGrid.FormShow 过程中加入: 
    TMyGrid(DbGrid1).FixedCols := 2; 
    两者从形式上略有不同,但实质都是一样的。我们这里设置 FixedCols 为 2,这是因为在 DBGrid 构件最左侧有个指示列,如果你将 DBGrid 的 Options 属性的 dgIndicator 设为False,则应设置 FixedCols 为1。  
使dbgrid的某几笔资料变色 
   你可在 DBGrid 元件的 DrawDataCell 事件中依资料的条件性来改变格子或文字的颜色.
如 :
OnDrawDataCell(...)
begin
  with TDBGrid(Sender) do
  begin
    if (条件) then
      Canvas.TextOut(Rect.Left + 4
    Rect.Top + 2
\'要显示的文字如表格的资料\');
end;
    而你会看到 DBGrid 的显示资料怎麽有重叠的情况那是因为原本DBGrid要显示的资料与 TextOut 所显示的资料重叠
    解决方法 :
    在 Query 元件所加入的栏位(在元件上按右键会有 Add Fields...的选单)在不要显示资料的栏位的 OnGetText 事件中有一参数设定为 False;
procedure TForm1.Query1Detail1GetText(Sender: TField; var Text: string;
DisplayText: Boolean);
begin
  // 决定在 DBGrid 得知表格资料时要不要显示所得到的资料False -> 不显示
  // 就可避免与 TextOut 的文字重叠了
  DisplayText : = False;
end;
end;
    如果用 Delphi 3 处理很简单.例如:对表中某字段当其数值小于0时为红字其他为黑字.
在 DBGrid.OnDrawColumnCell(...) 中:
begin
  if TableField.AsInteger < 0 then
    DBGrid.Canvas.Font.Color := clRed
  else
    DBGrid.Canvas.Font.Color := clBlack;
  DBGrid.DefaultDrawColumnCell(...);
end;
这样对 Field 指定的格式仍旧生效不必重写.  
实战Delphi数据网格色彩特效 
   Delphi中的数据网格控件(TDbGrid)对于显示和编辑数据库中大量的数据起着十分重要的作用;然而,在使用数据网格控件的同时,也往往因为表格中大量的数据不易区分,而令操作者眼花缭乱。如何提高网格控件的易用性,克服它的此项不足呢?本文从改变数据网格的色彩配置角度,提出了一种解决办法。
    以下为数据网格控件的6种特殊效果的实现方法,至于数据网格控件与数据集如何连接的方法从略。
1. 纵向斑马线效果:实现网格的奇数列和偶数列分别以不同的颜色显示以区别相邻的数据列。
file://在DbGrid的DrawColumnCell事件中编写如下代码:
Case DataCol Mod 2 = 0 of
True: DbGrid1.Canvas.Brush.Color:= clBlue; file://偶数列用蓝色
False: DbGrid1.Canvas.Brush.Color:= clAqua; file://奇数列用浅绿色
End;
DbGrid1.Canvas.Pen.Mode:=pmMask;
DbGrid1.DefaultDrawColumnCell (Rect
DataCol
Column
State);
2. 纵向斑马线,同时以红色突出显示当前单元格效果:以突出显示当前选中的字段。
file://将上述代码修改为:
Case DataCol Mod 2 = 0 of
True: DbGrid1.Canvas.Brush.Color:= clBlue; file://偶数列用蓝色
False: DbGrid1.Canvas.Brush.Color:= clAqua; file://奇数列用浅绿色
End;
If ((State = [gdSelected]) or (State=[gdSelectedgdFocused])) then
If Not DbGrid1.SelectedRows.CurrentRowSelected then
DbGrid1.Canvas.Brush.Color:=clRed; file://当前选中单元格显示红色
DbGrid1.Canvas.Pen.Mode:=pmMask;
DbGrid1.DefaultDrawColumnCell (Rect 
DataCol 
Column 
State);
上述两种方法突出了列的显示效果。
3.在数据网格中以红色突出显示当前选中的行。
    设置DbGrid控件的Options属性中的dgRowSelect属性为真,Color属性为clAqua(背景色)
在DbGrid的DrawColumnCell事件中编写如下代码:
if ((State = [gdSelected]) or (State=[gdSelected gdFocused])) then
DbGrid1.Canvas.Brush.color:=clRed; file://当前行以红色显示,其它行使用背景的浅绿色
DbGrid1.Canvas.pen.mode:=pmmask;
DbGrid1.DefaultDrawColumnCell (Rect
DataCol
Column
State);
4.行突显的斑马线效果:既突出当前行,又区分不同的列(字段)。
file://其它属性设置同3,将上述代码修改为:
if ((State = [gdSelected]) or (State=[gdSelectedgdFocused])) then
begin
Case DataCol Mod 2 = 0 of
True : DbGrid1.Canvas.Brush.color:=clRed; file://当前选中行的偶数列显示红色
False: DbGrid1.Canvas.Brush.color:=clblue; file://当前选中行的奇数列显示蓝色
end;
DbGrid1.Canvas.pen.mode:=pmmask;
DbGrid1.DefaultDrawColumnCell (Rect
DataCol
Column
State);
end;
5.横向斑马线, 同时以红色突显当前行效果。
file://其它属性设置同3,将上述代码修改为:
Case Table1.RecNo mod 2 = 0 of file://根据数据集的记录号进行判断
True : DbGrid1.Canvas.Brush.color:=clAqua; file://偶数行用浅绿色显示
False: DbGrid1.Canvas.Brush.color:=clblue; file://奇数行用蓝色表示
end;
if ((State = [gdSelected]) or (State=[gdSelectedgdFocused])) then file://选中行用红色显示
DbGrid1.Canvas.Brush.color:=clRed;
DbGrid1.Canvas.pen.mode:=pmMask;
DbGrid1.DefaultDrawColumnCell (Rect
DataCol
Column
State);
6.双向斑马线效果:即行间用不同色区分,同时,选中行以纵向斑马线效果区分不同的列。
file://其它属性设置同3,将上述代码修改为:
Case Table1.RecNo mod 2 = 0 of file://根据数据集的记录号进行判断
True : DbGrid1.Canvas.Brush.color:=clAqua; file://偶数行用浅绿色显示
False: DbGrid1.Canvas.Brush.color:= clblue; file://奇数行用蓝色表示
end;
If ((State = [gdSelected]) or (State=[gdSelectedgdFocused])) then
Case DataCol mod 2 = 0 of
True : DbGrid1.Canvas.Brush.color:=clRed; file://当前选中行的偶数列用红色
False: DbGrid1.Canvas.Brush.color:= clGreen; file://当前选中行的奇数列用绿色表示
end;
DbGrid1.Canvas.pen.mode:=pmMask;
DbGrid1.DefaultDrawColumnCell (Rect
DataCol
Column
State);
    上述6种方法分别就数据网格控件的列和行的色彩进行了设置,读者可以根据自己的需要设置特效。该程序在Delphi5中测试通过。  
 
点击DBGrid的Title对查询结果排序 
关键词:DBGrid 排序  
    欲实现点击DBGrid的Title对查询结果排序,想作一个通用程序,不是一事一议,例如不能在SQL语句中增加Order by ...,因为SQL可能原来已经包含Order by ...,而且点击另一个Title时又要另外排序,目的是想作到象资源管理器那样随心所欲。
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;
  
去掉DbGrid的自动添加功能 
关键词:DbGrid  
    移动到最后一条记录时再按一下“下”就会追加一条记录,如果去掉这项功能 
    procedure TForm1.DataSource1Change(Sender: TObject; Field: TField);
    begin
      if TDataSource(Sender).DataSet.Eof then TDataSource(Sender).DataSet.Cancel;
    end;
DBGrid不支持鼠标的上下移动的解决代码 
自己捕捉WM_MOUSEWHEEL消息处理
private
  OldGridWnd : TWndMethod;
procedure NewGridWnd (var Message : TMessage);
public
procedure TForm1.NewGridWnd(var Message: TMessage);
var
  IsNeg : Boolean;
begin
  if Message.Msg = WM_MOUSEWHEEL then
  begin
    IsNeg := Short(Message.WParamHi) < 0;
    if IsNeg then
      DBGrid1.DataSource.DataSet.MoveBy(1)
    else
      DBGrid1.DataSource.DataSet.MoveBy(-1)
  end
  else
    OldGridWnd(Message);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
  OldGridWnd := DBGrid1.WindowProc ;
  DBGrid1.WindowProc := NewGridWnd;
end;      
dbgrid中移动焦点到指定的行和列 
   dbgrid是从TCustomGrid继承下来的,它有col与row属性,只不过是protected的,不能直接访问,要处理一下,可以这样:
    TDrawGrid(dbgrid1).row:=row;
    TDrawGrid(dbgrid1).col:=col;
    dbgrid1.setfocus;
就可以看到效果了。
    1 这个方法是绝对有问题的,它会引起DBGrid内部的混乱,因为DBGrid无法定位当前纪录,如果DBGrid只读也就罢了(只读还是会出向一些问题,比如原本只能单选的纪录现在可以出现多选等等,你可以自己去试试),如果DBGrid可编辑那问题就可大了,因为当前纪录的关系,你更改的数据字段很可能不是你想象中的
    2 我常用的解决办法是将上程序改为(随便设置col是安全的,没有一点问题)
    Query1.first;
    TDrawGrid(dbgrid1).col:=1;
    dbgrid1.setfocus;
    这就让焦点移到第一行第一列当中 
 
如何使DBGRID网格的颜色随此格中的数据值的变化而变化? 
   在做界面的时候,有时候为了突出显示数据的各个特性(如过大或者过小等),需要通过改变字体或者颜色,本文就是针对这个情况进行的说明。
如何使DBGRID网格的颜色随此格中的数据值的变化而变化。如<60的网格为红色?
    Delphi中数据控制构件DBGrid是用来反映数据表的最重要、也是最常用的构件。在应用程序中,如果以彩色的方式来显示DBGrid,将会增加其可视性,尤其在显示一些重要的或者是需要警示的数据时,可以改变这些数据所在的行或列的前景和背景的颜色。
  DBGrid属性DefaultDrawing是用来控制Cell(网格)的绘制。若DefaultDrawing的缺省设置为True,意思是Delphi使用DBGrid的缺省绘制方法来制作网格和其中所包含的数据,数据是按与特定列相连接的Tfield构件的DisplayFormat或EditFormat特性来绘制的;若将DBGrid的DefaultDrawing特性设置成False,Delphi就不绘制网格或其内容,必须自行在TDBGrid的OnDrawDataCell事件中提供自己的绘制例程(自画功能)。
  在这里将用到DBGrid的一个重要属性:画布Canvas,很多构件都有这一属性。Canvas代表了当前被显示DBGrid的表面,你如果把另行定义的显示内容和风格指定给DBGrid对象的Canvas,DBGrid对象会把Canvas属性值在屏幕上显示出来。具体应用时,涉及到Canvas的Brush属性和FillRect方法及TextOut方法。Brush属性规定了DBGrid.Canvas显示的图像、颜色、风格以及访问Windows GDI 对象句柄,FillRect方法使用当前Brush属性填充矩形区域,方法TextOut输出Canvas的文本内容。
  以下用一个例子来详细地说明如何显示彩色的DBGrid。在例子中首先要有一个DBGrid构件,其次有一个用来产生彩色筛选条件的SpinEdit构件,另外还有ColorGrid构件供自由选择数据单元的前景和背景的颜色。
  1.建立名为ColorDBGrid的Project,在其窗体Form1中依次放入所需构件,并设置属性为相应值,具体如下所列:
   Table1 DatabaseName: DBDEMOS
     TableName: EMPLOYEE.DB
     Active: True;
   DataSource1 DataSet: Table1
   DBGrid1 DataSource1: DataSource1
     DefaultDrawing: False
   SpinEdit1 Increment:200
     Value: 20000
   ColorGrid1 GridOrdering: go16*1
  2.为DBGrid1构件OnDrawDataCell事件编写响应程序:
//这里编写的程序是<60的网格为红色的情况,其他的可以照此类推
  procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;Field: TField; State: TGridDrawState);
  begin
   if Table1.Fieldbyname(′Salary′).value<=SpinEdit1.value then
     DBGrid1.Canvas.Brush.Color:=ColorGrid1.ForeGroundColor
   else
     DBGrid1.Canvas.Brush.Color:=ColorGrid1.BackGroundColor;
   DBGrid1.Canvas.FillRect(Rect);
   DBGrid1.Canvas.TextOut(Rect.left+2,Rect.top+2,Field.AsString);
  end;
  这个过程的作用是当SpinEdit1给定的条件得以满足时,如′salary′变量低于或等于SpinEdit1.Value时,DBGrid1记录以ColorGrid1的前景颜色来显示,否则以ColorGrid1的背景颜色来显示。然后调用DBGrid的Canvas的填充过程FillRect和文本输出过程重新绘制DBGrid的画面。
  3.为SpinEdit1构件的OnChange事件编写响应代码:
  procedure TForm1.SpinEdit1Change(Sender: TObject);
  begin
    DBGrid1.refresh;  //刷新是必须的,一定要刷新哦
  end;
  当SpinEdit1构件的值有所改变时,重新刷新DBGrid1。
  4.为ColorGrid1的OnChange事件编写响应代码:
  procedure TForm1.ColorGrid1Change(Sender: TObject);
  begin
    DBGrid1.refresh;    //刷新是必须的,一定要刷新哦
   end;
  当ColorGrid1的值有所改变时,即鼠标的右键或左键单击ColorGrid1重新刷新DBGrid1。
  5.为Form1窗体(主窗体)的OnCreate事件编写响应代码:
  procedure TForm1.FormCreate(Sender: TObject);
  begin
    ColorGrid1.ForeGroundIndex:=9;
    ColorGrid1.BackGroundIndex:=15;
   end;
  在主窗创建时,将ColorGrid1的初值设定前景为灰色,背景为白色,也即DBGrid的字体颜色为灰色,背景颜色为白色。
  6.现在,可以对ColorDBGrid程序进行编译和运行了。当用鼠标的左键或右键单击ColorGrid1时,DBGrid的字体和背景颜色将随之变化。
  在本文中,只是简单展示了以彩色方式显示DBGrid的原理,当然,还可以增加程序的复杂性,使其实用化。同样道理,也可以将这个方法扩展到其他拥有Canvas属性的构件中,让应用程序的用户界面更加友好。
判断Grid是否有滚动条? 
这是一个小技巧,如果为了风格的统一的话,还是不要用了。:)
。。。
if (GetWindowlong(Stringgrid1.Handle, GWL_STYLE) and WS_VSCROLL) <> 0 then
    ShowMessage(\'Vertical scrollbar is visible!\');
  if (GetWindowlong(Stringgrid1.Handle, GWL_STYLE) and WS_HSCROLL) <> 0 then
    ShowMessage(\'Horizontal scrollbar is visible!\');
两个Grid的同步滚动 
   在实际制作一个项目当中,有时候需要几个grid一起同步滚动以减少用户的操作量。希望下面那段代码对您有一定的参考价值。
{1.}
unit SyncStringGrid;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs, Grids;
type
  TSyncKind = (skBoth, skVScroll, skHScroll);
  TSyncStringGrid = class(TStringGrid)
private
  FInSync: Boolean;
  FsyncGrid: TSyncStringGrid;
  FSyncKind: TSyncKind;
{ Private declarations }
  procedure WMVScroll(var Msg: TMessage); message WM_VSCROLL;
  procedure WMHScroll(var Msg: TMessage); message WM_HSCROLL;
protected
{ Protected declarations }
public
{ Public declarations }
  procedure DoSync(Msg, wParam: Integer; lParam: Longint); virtual;
published
{ Published declarations }
  property SyncGrid: TSyncStringGrid read FSyncGrid write FSyncGrid;
  property SyncKind: TSyncKind read FSyncKind write FSyncKind default skBoth;
end;
procedure Register;
implementation
procedure Register;
begin
  RegisterComponents(\'Samples\', [TSyncStringGrid]);
end;
procedure TSyncStringGrid.WMVScroll(var Msg: TMessage);
begin
  if not FInSync and Assigned(FSyncGrid) and (FSyncKind in [skBoth, skVScroll]) then
    FSyncGrid.DoSync(WM_VSCROLL, Msg.wParam, Msg.lParam);
  inherited;
end;
procedure TSyncStringGrid.WMHScroll(var Msg: TMessage);
begin
  if not FInSync and Assigned(FSyncGrid) and (FSyncKind in [skBoth, skHScroll]) then
    FSyncGrid.DoSync(WM_HSCROLL, Msg.wParam, Msg.lParam);
  inherited;
end;
procedure TSyncStringGrid.DoSync(Msg, wParam: Integer; lParam: Longint);
begin
  FInSync := True;
  Perform(Msg, wParam, lParam);
  FinSync := False;
end;
end.
{****************************************}
{2.}
private
  OldGridProc1, OldGridProc2: TWndMethod;
  procedure Grid1WindowProc(var Message: TMessage);
  procedure Grid2WindowProc(var Message: TMessage);
public
{...}
procedure TForm1.Grid1WindowProc(var Message: TMessage);
begin
  OldGridProc1(Message);
  if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or Message.msg = WM_Mousewheel)) then
  begin
    OldGridProc2(Message);
  end;
end;
procedure TForm1.Grid2WindowProc(var Message: TMessage);
begin
  OldGridProc2(Message);
  if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or (Message.msg = WM_Mousewheel)) then
  begin
    OldGridProc1(Message);
  end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
  OldGridProc1 := StringGrid1.WindowProc;
  OldGridProc2 := StringGrid2.WindowProc;
  StringGrid1.WindowProc := Grid1WindowProc;
  StringGrid2.WindowProc := Grid2WindowProc;
 
在Delphi中随意控制DBGrid 每一行的颜色简易方法 
   Delphi中使用 DBGrid 控件时,每一列都能按需要随意地改变颜色,但要改变每一行的颜色却很难,那么在不重新制作新控制件的情况下,有没有好的办法让DBGrid按照用户自己要求随意改变每一行颜色的?答案是有,下面介绍一种简单的方法。 
要改变DBGrid每一行的颜色,只要在ONDrawColumnCell事件中设定要改变颜色的行的条件,
并指定DBGrid的Canvas.Brush.color属性并且把Canvas.pen.mode属性设成pmmask,再调用DBGrid 的DefaultDrawColumnCell方法即可。注意在改变这两个属性前要先保护好原来的 
Canvas.Brush.color 属性的值,调节器用完成 DefaultDrawColumnCell 方法后要把原属性值改
回,现以 Delphi\\demos\\db\\clientmd 目录下的演示程序 clintproj.dpr 为例子,做简单说明,下面是对程序中的栅格 MemberGrid 的合条件的整行进行变色,变成黑体背景黄色的,其它不合条件的行的颜色为正常字体,白色背景,只在 DrawColumnCelL 事件中设条件其它的不变,如下: 
procedure TClientForm.MemberGridDrawColumnCell(Sender: TObject; const Rect: TRect; 
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var 
  oldcolor:tcolor;
  oldpm:tpenmode;
begin
  if DM.ProjectTEAM_LEADER.Value = DM.Emp_ProjEMP_NO.Value then  {设定变色的行的条件}
     MemberGrid.Canvas.Font.Style := [fsBold];
     MemberGrid.DefaultDrawColumnCell(Rect, DataCol, Column, State);
     {上面是演示程序的原内容,以下是增加部分}
  if DM.ProjectTEAM_LEADER.Value =DM.Emp_ProjEMP_NO.Value then {设定变色的行的条件}
  begin
     oldpm:= MemberGrid.Canvas.pen.mode;
     oldcolor:= MemberGrid.Canvas.Brush.color;
     MemberGrid.Canvas.Brush.color:=clyellow;
     MemberGrid.Canvas.pen.mode:=pmmask;
     MemberGrid.DefaultDrawColumnCell(Rect, DataCol, Column, State);
     MemberGrid.Canvas.Brush.color:=oldcolor;
     MemberGrid.Canvas.pen.mode:=oldpm;
  end;
end;
感觉上这个方法和前面的几个颜色控制方法的原理是一样的,都是通过ONDrawColumnCell事件来实现变色醒目美化的功能。:) 
如何在DBGrid中能支持多项记录的选择 
   这份文档来自国外,粗略看了一下,很有用,推荐给大家学习使用。
【Question】: How to do multi-selecting records in TDBGrid?
    When you add [dgMultiSelect] to the Options property of a DBGrid, you give yourself the ability to select multiple records within the grid.
    The records you select are represented as bookmarks and are stored in the SelectedRows property.
    The SelectedRows property is an object of type TBookmarkList.  The properties and methods are described below.
// property SelectedRows: TBookmarkList read FBookmarks;
//   TBookmarkList = class
//   public
     {* The Clear method will free all the selected records within the DBGrid *}
     // procedure Clear;
     {* The Delete method will delete all the selected rows from the dataset *}
     // procedure Delete;
     {* The Find method determines whether a bookmark is in the selected list. *}
     // function  Find(const Item: TBookmarkStr;
     //      var Index: Integer): Boolean;
     {* The IndexOf method returns the index of the bookmark within the Items property. *}
     // function IndexOf(const Item: TBookmarkStr): Integer;
     {* The Refresh method returns a boolean value to notify whether any orphans were dropped (deleted) during the time the record has been selected in the grid.  The refresh method can be used to update the selected list to minimize the possibility of accessing a deleted record. *}
     // function  Refresh: Boolean;  True = orphans found
     {* The Count property returns the number of currently selected items in the DBGrid *}
     // property Count: Integer read GetCount;
     {* The CurrentRowSelected property returns a boolean value and determines whether the current row is selected or not. *}
     // property CurrentRowSelected: Boolean
     //      read GetCurrentRowSelected
     //      write SetCurrentRowSelected;
     {* The Items property is a TStringList of TBookmarkStr *}
     // property Items[Index: Integer]: TBookmarkStr
     //      read GetItem; default;
//  end;
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, DBGrids, DB, DBTables;
type
  TForm1 = class(TForm)
    Table1: TTable;
    DBGrid1: TDBGrid;
    Count: TButton;
    Selected: TButton;
    Clear: TButton;
    Delete: TButton;
    Select: TButton;
    GetBookMark: TButton;
    Find: TButton;
    FreeBookmark: TButton;
    DataSource1: TDataSource;
    procedure CountClick(Sender: TObject);
    procedure SelectedClick(Sender: TObject);
    procedure ClearClick(Sender: TObject);
    procedure DeleteClick(Sender: TObject);
    procedure SelectClick(Sender: TObject);
    procedure GetBookMarkClick(Sender: TObject);
    procedure FindClick(Sender: TObject);
    procedure FreeBookmarkClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
  Bookmark1: TBookmark;
  z: Integer;
implementation
{$R *.DFM}
//Example of the Count property
procedure TForm1.CountClick(Sender: TObject);
begin
  if DBgrid1.SelectedRows.Count > 0 then
  begin
    showmessage(inttostr(DBgrid1.SelectedRows.Count));
  end;
end;
//Example of the CurrentRowSelected property
procedure TForm1.SelectedClick(Sender: TObject);
begin
  if DBgrid1.SelectedRows.CurrentRowSelected then
    showmessage(\'Selected\');
end;
//Example of the Clear Method
procedure TForm1.ClearClick(Sender: TObject);
begin
  dbgrid1.SelectedRows.Clear;
end;
//Example of the Delete Method
procedure TForm1.DeleteClick(Sender: TObject);
begin
  DBgrid1.SelectedRows.Delete;
end;
{*
   This example iterates through the selected rows of the grid and displays the second field of the dataset.
   The Method DisableControls is used so that the DBGrid will not update when the dataset is changed. The last position of the dataset is saved as a TBookmark.
   The IndexOf method is called to check whether or not the bookmark is still existent.
   The decision of using the IndexOf method rather than the Refresh method should be determined by the specific application.
*}
procedure TForm1.SelectClick(Sender: TObject);
var
  x: word;
  TempBookmark: TBookMark;
begin
  DBGrid1.Datasource.Dataset.DisableControls;
  with DBgrid1.SelectedRows do
  if Count > 0 then
  begin
    TempBookmark:= DBGrid1.Datasource.Dataset.GetBookmark;
    for x:= 0 to Count - 1 do
    begin
      if IndexOf(Items[x]) > -1 then
      begin
        DBGrid1.Datasource.Dataset.Bookmark:= Items[x];
        showmessage(DBGrid1.Datasource.Dataset.Fields[1].AsString);
      end;
    end;
  end;
  DBGrid1.Datasource.Dataset.GotoBookmark(TempBookmark);
  DBGrid1.Datasource.Dataset.FreeBookmark(TempBookmark);
  DBGrid1.Datasource.Dataset.EnableControls;
end;
{*
This example allows you to set a bookmark and  and then search for the bookmarked record within selected a record(s) within the DBGrid.
*}
//Sets a bookmark
procedure TForm1.GetBookMarkClick(Sender: TObject);
begin
  Bookmark1:= DBGrid1.Datasource.Dataset.GetBookmark;
end;
//Frees the bookmark
procedure TForm1.FreeBookmarkClick(Sender: TObject);
begin
  if assigned(Bookmark1) then
  begin
    DBGrid1.Datasource.Dataset.FreeBookmark(Bookmark1);
    Bookmark1:= nil;
  end;
end;
//Uses the Find method to locate the position of the bookmarked record within the selected list in the DBGrid
procedure TForm1.FindClick(Sender: TObject);
begin
  if assigned(Bookmark1) then
  begin
    if DBGrid1.SelectedRows.Find(TBookMarkStr(Bookmark1),z) then
      showmessage(inttostr(z));
  end;
end;
end. 
另外一种可以在在Delphi中随意控制DBGrid 每一行颜色的方法 
   有个问题是在Delphi中使用DBGrid时,如何让DBGrid中每一行颜色按照用户自己的意愿控
制。最初看到这个问题时,我们以为非常非常简单,所以马上动手准备解决它。结果却发现不是
那么回事,传统方法根本不能发挥作用。在电脑面前一直坐到凌晨4点,不断地调试,幸运地是凭借平时积累的一点编程经验,终于找到了开门的匙钥。现将它充公,供大家享用。 
1、 数据表的建立 
   在Delphi的工具菜单中选择Database desktop,在数据库DBDemos下建立一个名为
example.db的数据表。数据表的字段和内容如下: 
Name  Age  Wage
张山  25  500
王武  57  1060
李市  30  520
刘牛  28  390
2、创建基于TDBGrid的TColoredDBGrid组件 
    在Delphi组件菜单中,选择New Component,在弹出对话框中作以下设置: 
Ancestor Type  =   TDBGrid
Class  Name   =   TColoredDBGrid
然后单击OK按钮,Delphi自动完成组件基本框架的定义。增添OnDRawColoredDBGrid事件并
使它出现在Object Inspector的Events中以便在应用程序中设定改变行颜色的条件。重载
DrawCell方法,只能自己绘制单元格。不能通过在OnDrawColumnCell来设置颜色,因为在
OnDrawColumnCell改变单元格的颜色会再次触发OnDrawColumnCell。 
    下面就是所创建组件的源程序 。 
3、建立应用程序进行验证。 
    在Delphi文件菜单中选择New建立新的应用程序工程Project1和主窗体Form1,设置Form1的
Caption属性为“控制DBGrid行颜色的示例”。在主窗体上添加Data Source、Table、Button和
ColoredDBGrid组件。设置各组件的属性如下: 
Table1.Database=’DBDemos’
Table1.Tablename=’example.db’
Datasource1.Dataset=Table1
ColoredDBGrid1.Datasource=DataSource1
Button1.Caption=’退出’
在ColoredDBGrid1的onDRawColoredDBGrid事件中输入下列代码,设定由Wage(工资)来决
定在ColoredDBGrid1各行的颜色。 
procedure TForm1.ColoredDBGrid1 DRawColoredDBGrid (Sender: TObject;  Field: TField; var Color: TColor; var Font: TFont);
Var
    p : Integer;
begin
    p := Table1.FindField(\'wage\').AsInteger;
  //取得当前记录的Wage字段的值。
    if (p < 500) then begin                 
//程序将根据wage值设置各行的颜色。
      Color := clGreen;
      Font.Style := [fsItalic];      
//不仅可以改变颜色,还可以改变字体
    end;
    if(p >= 500) And (p < 800) then
      Color := clRed;
    if(p >=800) then begin
      Color := clMaroon;
      Font.Style := [fsBold];
    end;
end;
//用‘退出’按钮结束程序运行。
procedure TForm1.Button1Click(Sender: TObject);
begin
    Close;
end; 
 
 
读完这篇文章后,您心情如何?
0
0
0
0
0
0
0
0
本文网址: