关于如何才能让DBGrid平滑刷新的问题的讨论。。。

littlefat 2004-05-10 05:52:54
(明明已经发送成功怎么不见了?!)

例子描述:
新建立一个Form,在上面放置ADOConnection1、ADOTable1、DataSource1、DBGrid1并分别设置连接字符串和各控件的连接关系,使DBGrid1中显示数据(这是很典型的List)。

DBGrid1设置其Options中dgRowSelect=True(点击Grid时选择一行以反白显示而不是一个单元格)。

我是比较注重用户对界面的感觉(心理模型)和习惯的。我认为,按照用户的心里模型(习惯),在DBGrid1选中一条记录,然后对其进行(更新)操作后,应该:
①立即在DBGrid1中看到更新后的结果(用户心理:我的更新到底有没有成功,我要看一下);
②在更新后DBGrid1应该没有滚动条的滚动(用户心理:这条记录仍应该在原来的位置);
③更新操作前的选择的记录(即反白显示的那一行记录)仍应保持选中状态(选中的记录仍以反白显示让用户很容易一眼就看到)。

考虑以下的代码:
ADOTable1.Edit;
ADOTable1.FieldByName('Fee').Value:=1.1;
ADOTable1.Post;
这段代码是很典型的利用数据库控件来更新数据的过程,在Post后,DBGrid1的表现实现了前面要求的①(DBGrid1中的显示立即更新了)和②(滚动条没有滚动,屏幕没有闪动和刷新,即被更新的记录在屏幕上的绝对位置没有变化),但是没有实现③(当前记录仍是该被修改的记录,但是它失去了焦点,即不再处于被选中的状态,也即不以反白显示了)。

再考虑以下的代码:
Var RecordPosition:Integer;
begin
//采用ADOCommand控件来执行SQL进行更新操作。
ADOCommand1.CommandText:='update accflow set fee=1 where accid=154';
ADOCommand1.Execute;

RecordPosition:=DataSource1.DataSet.RecNo;//记录当前记录号
DataSource1.DataSet.Close;
DataSource1.DataSet.Open;//刷新数据集;
DataSource1.DataSet.MoveBy(RecordPosition-1);//移动当前记录到刷新前的记录号
end;
这段代码只实现了要求①,没有实现②(DataSource1.DataSet.Open执行后当前记录号变成第一条,再执行DataSource1.DataSet.MoveBy(RecordPosition-1)时DBGrid1的滚动条有滚动,并且当前记录的在屏幕上的绝对位置变化了,这样用户在查看该记录的时候,就需要用眼睛寻找)和③(更新后当前记录不以反白显示了)。

对比以上两种更新数据和DBGrid1的不同表现行为,可以知道应该有方法在第二段代码执行的时候让DBGrid1的表现实现要求②(我猜测很可能是DBGrid1的内部的某个方法,但我不知道)。

至于要求③,我就不知道如何才能实现了。

事实上,以上两段代码我只是拿来举例说明,我在我的项目中,早已不用以上的两种方式来更新数据了(我早已放弃使用数据库控件来更新数据,只是用它们来显示数据而已,我的项目中的所有DataSource的AutoEdit属性都是设定为False的;另外我的代码中也不使用任何SQL语句),也不用DBGrid1而是使用DevExpress的dxDBGrid。

说了半天,总结一下:
在不使用数据库控件的Edit/Post方法来更新数据的时候,如何才能让Grid控件立即显示更新后的数据而不发生滚动条的滚动(即被更新的记录在屏幕上的绝对位置不变化),并且在更新后,该记录仍保持被选中(反白显示)的状态?

先给出50分,如能实现,另开贴送分!
...全文
111 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
littlefat 2004-05-11
  • 打赏
  • 举报
回复
多谢几位!别的论坛有兄弟告诉我DBGrid控件中有一个Option叫做AlwaysShowSelection选项的,将其设定为True是可以实现效果③的。但是dxDBGrid控件却没有这个Option。。。

DisableControl和EnableControl对于第一段代码其实没有什么用处,不用照样不会发生滚动;但是对第二段代码,即使是用了,仍会发生滚动。。。。

其实,第一段代码使用数据控件的Edit、Post功能来更新数据时,因为数据库控件已经“知道”了更新,并且更新正是通过它们来提交的,所以,数据库控件在将更新提交到数据库中时会同时它们自己的本地缓存(显示)中的相应记录;但是第二段代码(或者使用存储过程等另外的方法)来更新数据,没有通过“它们”,所以它们不知道后台已经更新了,它们的缓存中仍保存着更新前的数据,所以必须使用Close、Open方法来强迫“它们”刷新自己的缓存,这时就发生屏幕滚动了。。。。

所以,有没有什么方法和机制,可以在我们使用其他方法更新数据时,通知“它们”某(些)记录已经更新了,请刷新,并且让“它们”刷新的时候不要傻乎乎地将所有记录全部重新读取,而只读取被更新的记录,在更新显示的时候不要滚动屏幕。。。
qizhanfeng 2004-05-11
  • 打赏
  • 举报
回复
disablecontrol
enablecontrol
web700 2004-05-11
  • 打赏
  • 举报
回复
③更新操作前的选择的记录(即反白显示的那一行记录)仍应保持选中状态(选中的记录仍以反白显示让用户很容易一眼就看到)。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 加个书鉴就可以搞定.

  • 打赏
  • 举报
回复
例子描述:
新建立一个Form,在上面放置ADOConnection1、ADOTable1、DataSource1、DBGrid1并分别设置连接字符串和各控件的连接关系,使DBGrid1中显示数据(这是很典型的List)。

DBGrid1设置其Options中dgRowSelect=True(点击Grid时选择一行以反白显示而不是一个单元格)。

我是比较注重用户对界面的感觉(心理模型)和习惯的。我认为,按照用户的心里模型(习惯),在DBGrid1选中一条记录,然后对其进行(更新)操作后,应该:
①立即在DBGrid1中看到更新后的结果(用户心理:我的更新到底有没有成功,我要看一下);
②在更新后DBGrid1应该没有滚动条的滚动(用户心理:这条记录仍应该在原来的位置);
③更新操作前的选择的记录(即反白显示的那一行记录)仍应保持选中状态(选中的记录仍以反白显示让用户很容易一眼就看到)。

考虑以下的代码:
ADOTable1.Edit;
ADOTable1.FieldByName('Fee').Value:=1.1;
ADOTable1.Post;
这段代码是很典型的利用数据库控件来更新数据的过程,在Post后,DBGrid1的表现实现了前面要求的①(DBGrid1中的显示立即更新了)和②(滚动条没有滚动,屏幕没有闪动和刷新,即被更新的记录在屏幕上的绝对位置没有变化),但是没有实现③(当前记录仍是该被修改的记录,但是它失去了焦点,即不再处于被选中的状态,也即不以反白显示了)。

////////////
我按照上面要求试了一下,满足第三个要求,即更新后还是呈选中的状态,即满足第三个条件,连接数据库为SQL SERVER!!~~~
////////////
  • 打赏
  • 举报
回复
--------友情提示:--------

本问题使用的控件是dxDBGrid,不是DBGrid !!!!~~~~

--------提示结束:--------

up ^_^
littlefat 2004-05-11
  • 打赏
  • 举报
回复
Up!
楚人无衣 2004-05-11
  • 打赏
  • 举报
回复
我的代码只能使右边滚动条不动,却无法使其相对位置不动,我没办法了,盼高手……
littlefat 2004-05-11
  • 打赏
  • 举报
回复
谢谢weizi2000(秋风啊) !你的代码运行时仍发生滚动。

楚人无衣 2004-05-11
  • 打赏
  • 举报
回复
已有人说过了,呵呵,你试试行不:
sKey:=ADOTable1.FieldByName('AccID').AsInteger;
ADOTable1.DisableControls;
ADOTable1.Requery();
ADOTable1.Locate('AccID',IntToStr(sKey),[loCaseInsensitive, loPartialKey]);
ADOTable1.EnableControls;
littlefat 2004-05-10
  • 打赏
  • 举报
回复
谢谢 soaringsouth(栈桥捉鳖) 兄:

以下代码确实可以在刷新数据集后保持原来的行处于选中状态:

var key:Integer;
begin
key:=ADOTable1.FieldByName('AccID').AsInteger;
ADOTable1.Close;
ADOTable1.Open;
ADOTable1.Locate('AccID',IntToStr(key),[loCaseInsensitive, loPartialKey]);
end;

但是滚动条仍发生滚动,即被选中更新的记录在刷新后在屏幕上的绝对位置发生了变化(每次该记录都是显示在Grid窗口的中间部分)。

不管怎样,这比我的第二段代码有进步。。。

谢谢!
soaringsouth 2004-05-10
  • 打赏
  • 举报
回复
更新前记住主键的值,更新完毕后
ADOTable1.locate();//参数自己写,不明白看帮助
内容概要:本文档是2025年全国广播电视技术能手竞赛IPTV专业的竞赛内容大纲,旨在指导参赛选手准备比赛。竞赛分为理论和实操两大部分。理论部分涵盖基本知识、基础理论和专业知识,包括法律法规、技术标准、IPTV技术基础、信号传输与分发、网络和数据安全等。实操部分则涉及IPTV系统设备、仪器设备的操作使用和指标测量。具体内容包括IPTV系统架构、传输技术与指标、设备配置及维护、专业技能如测量工具使用、视音频指标测量、直播点播协议分析、播出网络性能测量、网络安全数据分析以及系统故障排查等。 适合人群:从事或有意从事IPTV相关工作的技术人员,尤其是有志于参加全国广播电视技术能手竞赛的专业人士。 使用场景及目标:①帮助参赛选手全面了解并掌握IPTV相关的法规文件和技术标准;②提升选手对IPTV系统架构、传输技术和设备配置的理解;③增强选手在实际操作中的测量、分析和故障排查能力;④确保选手能够熟练运用各种测量工具和分析软件进行视音频指标测量和网络安全数据分析。 阅读建议:由于文档内容详尽且专业性强,建议读者在学习过程中结合实际案例和操作练习,同时参考相关技术文献,以便更好地理解和掌握竞赛所需的知识和技能。

2,507

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧