在Delphi中,DBGrid控件是一个开发数据库软件不能不使用的控件,其功能非常强大,可以配合SQL语句实现几乎所有数据报表的显示,操作也非常简单,属性、过程、事件等都非常直观,但是使用中,有时侯还是需要一些其他功能,例如打印、斑马纹显示、将DBGrid中的数据转存到Excel97中等等。这就需要我们定制DBGrid,以更好的适应我们的实际需要。本人根据使用Delphi的体会,定制了DBGrid,实现了以上列举的功能,对于打印功能则是在DBGrid的基础上联合QuickReport的功能,直接进行DBGrid的打印及预览,用户感觉不到QuickReport的存在,只需调用方法WpaperPreview即可;对于转存数据到Excel也是一样,不过这里使用的是自动化变量Excel而已。由于程序太长,不能详细列举,这里介绍一个完整的实现斑马纹显示的DBGrid,名字是NewDBGrid。根据这个小程序,读者可以添加其他更好、更多、更实用的功能。

   NewDBGrid的实现原理就是继承DBGrid的所有功能,同时添加新的属性:Wzebra,WfirstColor ,WsecondColor。当Wzebra的值为True时,显示斑马纹效果,其显示的效果是单数行颜色为WfirstColor,双数行颜色为WsecondColor。具体的见下面程序清单:

unit NewDBGrid;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
DB, Grids, DBGrids,Excel97;
type
TDrawFieldCellEvent = procedure(Sender: TObject; Field: TField;
var Color: TCOlor;Var Font: TFont;Row:Longint) of object;
//新的数据控件由 TDBGrid 继承而来
TNewDBGrid = class(TDBGrid)
private
//私有变量
FWZebra: Boolean; //是否显示斑马颜色
FWFirstColor : TColor; //单数行颜色
FWSecondColor : TCOlor; //双数行颜色
FDrawFieldCellEvent : TDrawFieldCellEvent;
procedure AutoInitialize; //自动初使化过程
procedure AutoDestroy;
function GetWFirstColor : TColor; 
//FirstColor 的读写函数及过程
procedure SetWFirstColor(Value : TColor);
function GetWSecondColor : TCOlor;
procedure SetWSecondColor(Value : TColor);
function GetWZebra : Boolean;
procedure SetWZebra(Value : Boolean);
protected
procedure Scroll(Distance: Integer); override;
//本控件的重点过程
procedure DrawCell(Acol,ARow: Longint;ARect:
TRect;AState: TGridDrawState); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property WZebra: Boolean read GetWZebra write SetWZebra;
property OnDblClick;
property OnDragDrop;
property OnKeyUp;
property OnKeyDown;
property OnKeyPress;
property OnEnter;
property OnExit;
property OnDrawDataCell;
property WFirstColor : TColor
read GetWFirstColor write SetWFirstColor ;
property WSecondColor : TColor
read GetWSecondColor write SetWSecondColor ;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents(?Data Controls?, [TNewDBGrid]);
end;
procedure TNewDBGrid.AutoInitialize;
begin
FWFirstColor := RGB(239,254,247);
FWSecondColor := RGB(249,244,245);
{可以在次添加需要的其它控件及初使化参数}
end;
procedure TNewDBGrid.AutoDestroy;
begin
{在这里释放自己添加参数等占用的系统资源}
end;

procedure TNewDBGrid.SetWZebra(Value : Boolean);
begin
FWZebra := Value;
Refresh;
end;

function TNewDBGrid.GetWZebra: Boolean;
begin
Result :=FWZebra;
end;

function TNewDBGrid.GetWFirstColor : TColor;
begin
Result := FWFirstColor;
end;
procedure TNewDBGrid.SetWFirstColor(Value : TColor);
begin
FWFirstColor := Value;
Refresh;
end;

function TNewDBGrid.GetWSecondColor : TColor;
begin
Result := FWSecondColor;
end;
procedure TNewDBGrid.SetWSecondColor(Value : TColor);
begin
FWSecondColor := Value;
Refresh;
end;

constructor TNewDBGrid.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
AutoInitialize;
end;

destructor TNewDBGrid.Destroy;
begin
AutoDestroy;
inherited Destroy;
end;

//实现斑马效果
procedure TNewDBGrid.DrawCell(ACol,ARow:
Longint;ARect: TRect;AState: TGridDrawState);
var
OldActive: Integer;
Highlight: Boolean;
Value: string;
DrawColumn: Tcolumn;
cl: TColor;
fn: TFont;
begin
{如果处于控件装载状态,则直接填充颜色后退出}
if csLoading in ComponentState then
begin
Canvas.Brush.Color := Color;
Canvas.FillRect(ARect);
Exit;
end;
if (gdFixed in AState) and (ACol - IndicatorOffset 〈 0 ) then
begin
inherited DrawCell(ACol,ARow,ARect,AState);
Exit;
end;
{对于列标题,不用任何修饰}
if (dgTitles in Options) and (ARow = 0) then
begin
inherited DrawCell(ACol,ARow,ARect,AState);
Exit;
end;
if (dgTitles in Options) then Dec(ARow);
Dec(ACol,IndicatorOffset);
if (gdFixed in AState) and ([dgRowLines,dgColLines] * Options =
[dgRowLines,dgColLines]) then
begin
{缩减ARect,以便填写数据}
InflateRect(ARect,-1,-1);
end
else
with Canvas do
begin
DrawColumn := Columns[ACol];
Font := DrawColumn.Font;
Brush.Color := DrawColumn.Color;
Font.Color := DrawColumn.Font.Color;
if FWZebra then //如果属性WZebra为True则显示斑马纹
if Odd(ARow) then
Brush.Color := FWSecondColor
else
Brush.Color := FWFirstColor;
if (DataLink = nil) or not DataLink.Active then
FillRect(ARect)
else
begin
Value := ??;
OldActive := DataLink.ActiveRecord;
try
DataLink.ActiveRecord := ARow;
if Assigned(DrawColumn.Field) then
begin
Value := DrawColumn.Field.DisplayText;
if Assigned(FDrawFieldCellEvent) then
begin
cl := Brush.Color;
fn := Font;
FDrawFieldCellEvent(self,DrawColumn.Field,cl,fn,ARow);
Brush.Color := cl;
Font := fn;
end;
end;
Highlight := HighlightCell(ACol,ARow,Value,AState);
if Highlight and (not FWZebra) then
begin
Brush.Color := clHighlight;
Font.Color := clHighlightText;
end;
if DefaultDrawing then
DefaultDrawColumnCell(ARect,ACol,DrawColumn,AState);
if Columns.State = csDefault then
DrawDataCell(ARect,DrawColumn.Field,AState);
DrawColumnCell(ARect,ACol,DrawColumn,AState);
finally
DataLink.Activerecord := OldActive;
end;
if DefaultDrawing and (gdSelected in AState) and
((dgAlwaysShowSelection in Options) or Focused)
and not (csDesigning in Componentstate)
and not (dgRowSelect in Options)
and (ValidParentForm(self).ActiveControl = self) then
begin
//显示当前光标处为蓝底黄字,同时加粗显示
Windows.DrawFocusRect(Handle,ARect);
Canvas.Brush.COlor := clBlue;
Canvas.FillRect(ARect);
Canvas.Font.Color := clYellow;
Canvas.Font.Style := [fsBold];
DefaultDrawColumnCell(ARect,ACol,DrawColumn,AState);
end;
end;
end;
if (gdFixed in AState) and ([dgRowLines,dgColLines] * Options =
[dgRowLines,dgColLines]) then
begin
InflateRect(ARect,-2,-2);
DrawEdge(Canvas.Handle,ARect,BDR_RAISEDINNER,BF_BOTTOMRIGHT);
DrawEdge(Canvas.Handle,ARect,BDR_SUNKENINNER,BF_TOPLEFT);
end;
end;
//如果移动光标等,则需要刷新显示DBGrid
procedure TNewDBGrid.Scroll(Distance: Integer);
begin
inherited Scroll(Distance);
refresh;
end;
end.

   以上程序在Win98 + Delphi 5下调试通过。

Delphi中的DBGrid控件的更多相关文章

  1. Delphi中使用TXMLDocument控件应注意的问题 转

    Delphi中使用TXMLDocument控件应注意的问题 delphiconstructorxmlclass今天写了一个类,其中用到了TXMLDocument控件.这个控件我是要动态生成的. 但是却 ...

  2. Delphi中,indy控件实现收发邮件的几点学习记录( 可以考虑加入多线程,用多个邮箱做一个邮箱群发器) 转

    关于用Delphi中的Indy控件实现收发邮件的几点学习记录             这几天心里颇不宁静,不是因为项目延期,而是因为自己几个月前做的邮件发送程序至今无任何进展,虽然一向谦虚的人在网上发 ...

  3. Delphi中代替WebBrowser控件的第三方控件

    这几天,接触到在delphi中内嵌网页,用delphi7自带的TWebBrowser控件,显示的内容与本机IE8显示的不一样,但是跟装IE8之前的IE6显示一个效果.现在赶脚是下面两个原因中的一个: ...

  4. delphi中通过http控件上载文件的问题(紧急) 整理的CSDN 帖子

    http控件能不能实现post文件?要求效果就像普通的html中通过表单(form中<INPUT TYPE="FILE" NAME="FILE1" SIZ ...

  5. Delphi中使用TXMLDocument控件应注意的问题

    今天写了一个类,其中用到了TXMLDocument控件.这个控件我是要动态生成的. 但是却遇到了非常奇怪的问题,下面分享一下 procedure TMainForm.Button1Click(Send ...

  6. 在DELPHI中动态创建控件以及控件的事件

    在DELPHI中我们经常要动态的创建控件以及控件的事件.例如,我们可能想根据程序需要动态的创建一些Tshape组件来创建某个图形,并使得在鼠标移动上去之后可以完成某些操作.这一般需要需要三步: 生成一 ...

  7. delphi中的Label控件背景透明

    Label1.Transparent:=true;你在它的属性窗口把它的Transparent属性改成TRUE就行了 来自为知笔记(Wiz)

  8. delphi中使用mediaplayer控件播放音乐

    新建一个名字为media的文件夹,把要播放的音乐文件放在这个文件夹里. ExtractFilePath是用来获得产生的可执行程式所在的路径,因为我们把要播放的音乐文件放在了可执行程式的那个根目录下. ...

  9. delphi如何按照控件的左右顺序来遍历窗体中的每个控件 [问题点数:20 http://bbs.csdn.net/topics/380216822

    delphi如何按照控件的左右顺序来遍历窗体中的每个控件delphi默认是按照控件添加进窗体的顺序来遍历的,有没有哪个属性能控制这个/?? 更多0分享到:   对我有用[0] 丢个板砖[0] 引用 | ...

随机推荐

  1. Linux入门进阶第五天——用户管理(帐号管理 )下

    一.身份切换 为了避免 rm -rf /* 的悲剧发生,平时使用时,尽量使用一般帐号!需要环境设置等必要时才使用root 1.su命令 一般地,推荐使用su - / su - username的形式来 ...

  2. echarts 拐点添加图片

    series : [ { name:'搜索引擎', type:'line', symbol:'emptyCircle', symbolSize: 5, itemStyle: { normal: { l ...

  3. WPF 带刻度的滑动条实现

    原文:WPF 带刻度的滑动条实现 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/BYH371256/article/details/83507170 ...

  4. 分块算法&BZOJ2002

    题目传送门 第一次接触分块...... 分块查找是折半查找和顺序查找的一种改进方法,分块查找由于只要求索引表是有序的,对块内节点没有排序要求,因此特别适合于节点动态变化的情况. 分块修改理论复杂度为O ...

  5. gdb调试带参数程序

    一般来说GDB主要调试的是C/C++的程序.要调试C/C++的程序,首先在编译时,我们必须要 把调试信息加到可执行文件中.使用编译 器(cc/gcc/g++)的 -g 参数可以做到这一点.如: > ...

  6. Docker入门篇(一)之docker基础

    1.Docker 架构 http://blog.csdn.net/u012562943/article/category/6048991/1Docker 使用客户端-服务器 (C/S) 架构模式,使用 ...

  7. LUA中点号和冒号的区别

    Student = {}; Student.__index = Student; function Student:new(name, age) local temp = {}; setmetatab ...

  8. Python数据分析开发环境

    准备工作 下载并安装最新版本的Anaconda 下载并安装最新版本的Visual Studio Code 编辑器 Tips: 可以选择自己喜欢并且熟悉的编辑器或IDE.如:VIM.Emacs.Note ...

  9. symfony注册Twig模板中使用自定义PHP方法

    // 注:只是在此做下记录,有兴趣的可以参考,不做实际教程文档// 官方文档,https://symfony.com/doc/2.8/templating/twig_extension.html// ...

  10. JavaScript查找元素的方法

    1.根据id获取元素 document.getElementById("id属性的值"); 2.根据标签名字获取元素 document.getElementsByTagName(& ...