关于如何才能让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分,如能实现,另开贴送分!
...全文
109 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();//参数自己写,不明白看帮助
在Windows 10或Windows 11操作系统中,用户经常会遇到共享打印机时出现的一系列错误代码,这些错误代码可能会阻碍打印机共享功能的正常使用。常见的错误代码包括0x00000057、0x00000709和0x0000011b,这些代码通常指出了不同的问题,比如权限不足、服务未运行或配置错误等。除此之外,还有一些故障提示如“连接失败”或“内存不足”,这些都可能影响到打印机共享的稳定性。 要解决这些故障,首先要确保打印机已经正确地连接到网络,并且在需要共享的电脑上进行了设置。确保打印机驱动程序是最新的,并且在共享设置中没有错误配置。对于权限问题,需要检查网络上的用户账户是否具有足够的权限来访问共享打印机。同时,也要确保打印机服务正在运行,特别是“Print Spooler”服务,因为这是打印机共享服务的核心组件。 在某些情况下,问题可能与操作系统的更新有关,如升级到最新版的Windows 10或Windows 11后可能出现的兼容性问题。这时,可能需要查看微软的官方支持文档来获取特定的解决方案或更新。 对于错误代码0x00000057,这通常是由于没有足够的权限来访问网络打印机或其共享资源,解决方法是确保网络打印机的权限设置正确,包括在组策略中设置相应的访问权限。而0x00000709错误可能是由于打印机驱动问题或打印机端口配置错误,可以尝试重新安装或更新打印机驱动来解决。至于0x0000011b错误,这往往是因为打印机队列服务的问题,检查并重启“Print Spooler”服务通常是解决这类问题的常见手段。 至于“连接失败”或“内存不足”这类故障,通常与客户端和打印机之间的网络连接以及打印机本地资源的使用情况有关。检查网络连接,确保打印机所在的网络段没有故障或中断。同时,如果打印机的打印队列长时间得不到处理,可能会导致内存不足的情况,这时可能需要清理打印队列或增加打印机的内存配置。 为了帮助用户更快速地解决这些问题,市面上出现了各种打印机共享错误修复工具。这些工具往往通过预设的修复程序来自动检测和修正打印机共享中常见的问题。它们可以快速检查打印机驱动、网络连接以及共享设置,并且能够提供一键修复功能,大幅减少了用户自行排查和解决问题的难度。 然而,在使用这些修复工具之前,用户应确保这些工具的来源是安全可靠的,避免因使用不当的修复工具而引发其他系统安全或隐私问题。用户可以到官方平台或者信誉良好的软件提供商处下载这些工具。通过细心检查打印机的共享设置,及时更新驱动程序和服务,以及合理使用修复工具,大多数共享打印机的问题都可以得到有效的解决。

2,507

社区成员

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

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