如何在dbgrid中显示行号 ( 积分: 100 )

我的思路也是在画dbgrid网格中时把其中的首行,最好是左边灰色栏中添加。
如果用DBGrid1.Canvas.TextOut(),好象无法控制绘出指定列中。
另一思路是笨方法:就是建一临时表记录表中记录序号,数据变更再更新读取临时表,这种方法也能实现,但太麻烦,而且大加重程序代码?
 
这个方法同内存表或StringGrid显示数据原理近似,创建一个没有界面的数据
控件,并在内存建一个比数据库还大10的缓冲区,数据被放到里面闲置,只为
取序号,也太浪费了,数据库大的时候,带有图片的几百兆的数据库,就难吃
消,如果这是一个方法的话,老外早就搞出来。

我的控件也可以显示行号,方法是:凡是引起表格滚行和行数变化的地方,都
写了维护行号的代码,除了鼠标键盘这些例行公事之外,还有一些想不到的地
方,比如某列的宽度改变,滚动条出现导致表格行数变化,还有数据集临时脱
开又重新挂上。内部和外部触发的正常模式下的浏览、编辑、插入、添加、删
除状态,过滤模式下的浏览、编辑、插入、添加、删除状态的变化,标题、过
滤行隐现,表脚的行数变化,备注行的高度变化,表格大小变化,这些地方太
多了,原来有些程序段会影响正确计算,也作了整段的重写,这是针对我的表
格而定的,换了DBGrid或DBGridEh计算方法有很大的不同,不能直接套用。

在2.4万的代码里面,它占的不多,但为了写好它,要分析整个程序,并作了无
数次调试,控件改动一处,都要评估对行号计算的影响,并尽量避免或者修复,
费了那么大的劲,换来的极少的开销,维护行号的代码不是同时执行的,有些
地方有数十行,有的地方只有几行,执行起来不影响表格速度,除了几个变量
之外,没有占用其它内存,对数据集没有任何影响,并扩展出其他功能,这种
辛苦是值得的,

我的控件如果值10元的话,那么行号计算值3元是最贵的部分。
 
swns:
DBGrid1.Canvas.TextOut(),好象无法控制绘出指定列中, 可以的
kinneng:
你的控件没有源代码
 
你的什么控件,没有原代码有什么实际意义? 你的目的是留给你自己用的? 还是分享?

buffer 不一定要大于Recordcount, 仅仅是DbGrid 的 行数也可以,要看你怎么修改啦。
 
Delphi本身很多文件也是没有源码的,例如制作字段编辑窗,只能用它的Bpl,它的甚至声明了版权,分发这些文件时非法的,如果没有源码就没有意义,那么你最好什么不要用,按你的方法,buffer当然不一定要大于Recordcount,但至少要等于,如果少于的话,那肯定会出错,其实就是由于+10的原因,你的方法存在一个Bug,当数据很多时候,在表格底部添加一行,然后撤销,本来应该消失的,却没有消失,这行只存在于那个缓冲区里面,未反映过来,很可能导致一些混乱,所以浏览或者编辑状态下,buffer最好设为等于Recordcount,在插入或者添加状态下,就设buffer等于Recordcount+1,我已经做过功课了。
 
xuxiaohao
DBGrid1.Canvas.TextOut()怎样控制输出在指定列,你知道就说出来,不要说能又不说,这么点小东西还要遮遮藏藏的?

老实说,我接触过用delphi的商业软件,它那里的dbgrid中的序号就处理得非常好,可我一直不知道它是用别的控件还是怎么编的。所以希望来网上找找答案。可是,现在看来
 
如果显示序号真的那么好做,老外的表格控件早就做上了,商业软件有序号的几乎都是
StringGrid,有些个人软件使用DBGrid用增加计算字段的方法,像上面那个方法,只能
用在很小的数据库。
DBGrid1.Canvas.TextOut()
修改DBGrid.pas
在SetColumnAttributes过程里面,先判断是否显示指示列,
if dgIndicator in Options then
ColWidth(0):=14 + Canvas.TextWidth(IntToStr(最大的序号值));
在DrawCell过程里面,先判断是否显示指示列,
if dgIndicator in Options and (ACol=0) then
Canvas.TextRect(ARect,1,1,IntToStr(序号值));
 
这么说来,没有一种好方法在DbGRID中显示序号了?
 
了解DBGrid的原理之后,就发现没有简单方法,因为数据库相当于一卷电影胶片,DBGrid相当于放映机的窗口,可以影像前进倒退,但却无法直接取得当前是哪一格,因为不是所有数据库都提供序号的,所以只能监视前进倒退来间接计算当前是哪一格。
 
增加一个C0lumn, 不设置字段(等于是空的),放在第一列;
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
s: string;
begin
在这里判断,字段是否为空
if Column.Field = nil then
begin
s:=inttostr(self.Fdatalink.ActiveRecord);
self.DBGrid1.Canvas.TextOut(Rect.Left, Rect.Top, s);
end;
end;
 
你 给出Emai, 我传个Demo 和 源码 给你, 不像有些人,只会在这里吹牛,又不给出源码。说了等于没说。
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2960059
 
你在连接dbgrid的组件里,譬如是query,增加一个自动计算的字段如no
然后在query组件的afteropen事件里,判断如果query.recno=-1,就让这个新的字段no值赋为query.recordcount;其他情况no=query.recno
ok啦
我以前用过,可以得
问题解决,马上给分啊
 
我的邮箱地址是:swns@21cn.com
 
sundata,
如何在query中增加字段,你能说具体点吗?
 
sundata, 的 不能实现。
 
我也有同感,以前好像有试过
 
以前也找过各种办法(自己画或加计算字段等),都不理想,论坛里讨论这个问题已经很多了,不过也都是老调重谈。总之,这个问题要解决好看来不容易呀!期待大富翁的元老们指点迷津……
 
xuxiaohan,
你的程序我试过了,实现是能实现,不过加了序号后,我连接一个用1355多条数据的表,程序运行慢了许多,特别是我把表拉到最后一行再用向下方向键添加一行时就特别明显。
另外,你传给我的demo也不能找开。
 
1355 不会慢的, 我试过2000条记录以下,速度变化不大。
 

Similar threads

S
回复
0
查看
639
swish
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
顶部