DBRGid右边的滚动条如何去掉(100分)

  • 主题发起人 主题发起人 李宏光
  • 开始时间 开始时间

李宏光

Unregistered / Unconfirmed
GUEST, unregistred user!
不好意思麻烦各位大侠!

另外富豪问题62508 huizhang
加* 的下一句为何不通 ?
function TForm1.GetValue(index: integer): integer;
var
Strings1: TStrings;
begin
Strings1:=TStrings.create;
//****
Strings1.CommaText:='1 9 134 0 234 34';
if (index < Strings1.Count) and (index>=0) then
result:=StrToInt(Strings1.Items[Index])
else
result:=0;
Strings1.free;
end;

 
1/ 当DBGRID的高度够的话, 滚动条自然就消失了,
即DBGRID的DATASOURCE里有的3条记录, DBGRID的高度可容纳4条记录,
右边滚动条自然就不存在了.

2/ *号下的那句可能是
Strings1.Text:='1 9 134 0 234 34';
我猜的, 你不如试一下.
 
李宏光:
>另外富豪问题62508 huizhang

是有问题, 不能直接声明TStrings对象, 因为里面有一个Abstract方法无实际程序,
在TStringList才有实质性程序代码。

var
Strings1: TStringList;
begin
Strings1:=TStringList.create;
...
 
liwei 看来还没试过, 在D4中的滚动条不象你说的那样, 竖向滚动条始终存在, 看来
是Delphi4.0的一个不足(不记得D3什么样了). 我将 D4 下 Source/vcl 路径下的
BGrids.pas 作了点修改, 问题就解决了.

procedure TCustomDBGrid.UpdateScrollBar;
var
SIOld, SINew: TScrollInfo;
begin
if FDatalink.Active and HandleAllocated then
with FDatalink.DataSet do
begin
....
//Add by huizhang
if (RecordCount+1) * DefaultRowHeight < Height then
ShowScrollBar(Self.Handle, SB_VERT, false)
else
ShowScrollBar(Self.Handle, SB_VERT, true);
//end Add by huizhang
end;
end;

修改后的DbGrids.pas必须添加到你的Project中去才能使用. 如果想让新版本的
Dbgrid自动生效,只需要将编译后的DBGrids.dcu复制到lib目录中即可.
 

用huizhang提供的方法中使用RecordCount加判别, 会出问题, 在C/S形式的TQuery中
RecordCount会下载全部数据, 那将导致大结果集的数据浏览
会很慢,
所以方法有三:
1. 在 DBgrid1所连接的Datasource的OnDataChange中
加入
ShowScrollBar(DBGrid1.Handle, SB_VERT, false);
注: 有闪烁感;

2. 基于huizhang提供的方法, 方法如下:
( 并不完善, 目前只能针对文件型数据库, 并且没有考虑标题栏的实际高度)
procedure TCustomDBGrid.UpdateScrollBar;
var
SIOld, SINew: TScrollInfo;
//!!! showvsc :boolean; //add by seasky
begin
if FDatalink.Active and HandleAllocated then
with FDatalink.DataSet do
begin
....
if IsSequenced then
begin
//!!!
Showvsc := ((RecordCount+1) * DefaultRowHeight > Height); // add by seasky

....
end
else
begin
//!!!
Showvsc := true; //add by seasky
....
end;
if (SINew.nMin <> SIOld.nMin) or (SINew.nMax <> SIOld.nMax) or
(SINew.nPage <> SIOld.nPage) or (SINew.nPos <> SIOld.nPos) then
//!!!
if not Showvsc then // add by seasky
ShowScrollBar(Self.Handle, SB_VERT, false) // add by seasky
else // add by seasky
SetScrollInfo(Self.Handle, SB_VERT, SINew, True);
end;
end;

3. 从网上下载增强的DBGrid控件, 请大家推荐一下
 
注意: Borland提供的DBGrid
在d3 在中 , 如果有一条记录, 垂直滚动条不显示, 如果
有多条, 无论行够不够显示, 都会显示垂直滚动条.
 
SeaSky,

看来你试过我的方法了, 改的很好, 多谢! 不过不改变也没有你所说得那么严重;
至于你的方法一就免了吧, 那是无条件的去掉Vertical Scrollbar;
增强型的DBGrid是增加了一些功能(一般用不到), 同时也增加了系统资源的浪费;
我的原则是如果无特殊需要不使用第三方控件;
 
huizhang,
我并不是试过你的方法, 是因为我原来在基于SYBASE 的
MIS中使用RecordCount得到查询出的记录数,

初期RecordCount数值小时,并不觉得, 后来发现当结果集为上千条后, 一使用RecordCount属性便会产生数十秒的停顿,

C/S型的数据库查询确是按照一定
的下载记录数进行的, 客户端一次下载的记录数是有设定的,

一次RecordCount的引用,相当于先执行 First, 再执行Last,

在SQL应用中, 大结果集的First -> Last 执行速度之慢,难以
忍受, 更何况DBGrid中各种过程, 都要更新滚动条,

参考RecordCount的Help.

后来我用了一种方法回避开这种麻烦

因为我只要得到下列几种结论:
1. 查询为空(None),
2. 只有唯一一条 (Only one)
3. 少数几条记录(Some) <50
4. 许多条(Lot)

方法:
查询结果打开后,
with Dataset do
If EOF then
result :='None'
else Begin
next;
if EOF then
result :='Only'
else Begin
MoveBy(50);
if EOF then // 移动50步距离,
result:='Some'
else
result:='Lot';
end;
First; //返回
end;

实际上可以通过上述思想, 判断记录数的多少, 当大于所能
显示的行数, 记录Boolean量中, 再在更新控制的过程中,
判别该Boolean量, 以便控制显示滚动条.

上述办法无论在控件改造中, 还是直接
应用在程序中,都不会有太大障碍.

另 : 第二个程序的问题是 :
String1应该用 TStringList类,
TString中有纯虚函数, 不单独构成实例.

其中Strings1.Items[Index]写法也有错误,
应为
Strings1[Index] 或 String1.string[Index];
 
多谢各位的指教,
 
我发送的信息这么只有这么一些,
我只好再重新接上;

(接上段)
4. 许多条记录( Lot)

具体方法:
当Query执行打开后

Fuction QueryResult(DataSet: TdataSet):String;
Begin
With Dataset do
if EOF then
Result :='None'
else Begin
Next ;
If Eof then
Result :='One'
else
begin
MoveBy(50);
if Eof then
Result::='Some'
else
Result := 'Lot';
First;
end;
end;
end;

可以利用上述思想, 判别记录数是否多于可显示的条目数,
只要先算出可显示的条目数N, 就从
First,
MoveBy(N+1) ,
在 Eof 中就能作判别.

至于TStrings的程序的原因是 :

TStrings类不可以存在实例对象, 原因是因为
TStrings中存在Add, Insert, Clear等纯虚函数, 必须在派生类中重载,
TStringList是TStrings的派生类, 可以存在实例对象,
所以Strings1.CommaText会出错, 将Tstring改为TStringList

result:=StrToInt(Strings1.Items[Index])
应写为:
Result:= StrToInt(Strings1[Index])

Result:= StrToInt(Strings1.String[Index])


 
SeaSky,佩服佩服。

我用的时候还发现有时候在oracle和sql-server,access97里返回的
Query.recordCount不正确,有时候是全0。
从此就再也不用recordCount了,
就都用判断eof的方法,单独作了一个函数.

不知道d4有没有改变。

顺便问一句,你在那里上班?
我也在南京。
 
曹哓钢:
你可以打我的BP: 127-2086596, 相互可以联系一
下, 不过星期六、日的上午8:30-11:00,下午
2:00-4:30 在上课
我家住南大



 
不好意思,想别的问题,忘了给分,
 
小李,应该结束此问题给大家加分了!
<font color="red">(记得选中上面的“接受答案”呀!!!)</font>

-- by 3h
 
各位大虾
失礼了,我已为此问题早结束了.
 
问题结束
盗此位置
 

Similar threads

后退
顶部