这样一次也不闪(先定位后再打开datasource): var SavePlace: TBook; begin SavePlace := ADOQuery1.GetBook; ADOQuery1.DisableControls; ADOQuery1.Requery; //与先Close再Open等效 ADOQuery1.GotoBook(SavePlace); ADOQuery1.FreeBook(SavePlace); ADOQuery1.EnableControls; end;
提出这种问题的一看就是没有经过用户实战的新手。Refresh是绝对不行的,速度慢的要命,至于为什么上面也说了。Close/Open模式是最好的方法,剩下的定位问题就根据实际情况来了,至于那么罗嗦吗? A. Open后通过Locate定位 B. Open后通过RecNo定位当然,多用户情况下会出现很多中情况,譬如你刚刚输入的可能被其它用户删除了,这样你Locate就找不到了;当你保存的是最后一条记录,Open后别人又删除了上面某一条,这样RecNo就得进行额外处理。当然无论采用那种方式都有好处坏处,尤其是多用户的时候,在多用户情况下做到不闪是不可能的,因为数据已经变化了。当然,不管用什么办法,解决用户的问题是最好的办法。
这种方法是又不闪,又能定位的 var SavePlace: TBook; begin SavePlace := ADOQuery1.GetBook; ADOQuery1.DisableControls; ADOQuery1.Requery; //与先Close再Open等效 ADOQuery1.GotoBook(SavePlace); ADOQuery1.FreeBook(SavePlace); ADOQuery1.EnableControls; end;
我只有Refresh的方法了
var
SavePlace: TBook;
begin
SavePlace := ADOQuery1.GetBook;
ADOQuery1.DisableControls;
ADOQuery1.Requery; //与先Close再Open等效
ADOQuery1.EnableControls;
ADOQuery1.GotoBook(SavePlace);
ADOQuery1.FreeBook(SavePlace);
end;//如果数据集有可唯一定位的关键字,如id,这样做:
var
id: Integer;
begin
id := ADOQuery1.FieldByName('id').AsInteger;
ADOQuery1.DisableControls;
ADOQuery1.Requery;
ADOQuery1.EnableControls;
ADOQuery1.Locate('id', id, []);
end;
这样改动太大了,我用的是DBGridEh
谢谢你解释了Refresh,不过你的方法我也想到过,但是应该还是会闪动一次?
var
SavePlace: TBook;
begin
SavePlace := ADOQuery1.GetBook;
ADOQuery1.DisableControls;
ADOQuery1.Requery; //与先Close再Open等效
ADOQuery1.GotoBook(SavePlace);
ADOQuery1.FreeBook(SavePlace);
ADOQuery1.EnableControls;
end;
A. Open后通过Locate定位
B. Open后通过RecNo定位当然,多用户情况下会出现很多中情况,譬如你刚刚输入的可能被其它用户删除了,这样你Locate就找不到了;当你保存的是最后一条记录,Open后别人又删除了上面某一条,这样RecNo就得进行额外处理。当然无论采用那种方式都有好处坏处,尤其是多用户的时候,在多用户情况下做到不闪是不可能的,因为数据已经变化了。当然,不管用什么办法,解决用户的问题是最好的办法。
var
SavePlace: TBook;
begin
SavePlace := ADOQuery1.GetBook;
ADOQuery1.DisableControls;
ADOQuery1.Requery; //与先Close再Open等效
ADOQuery1.GotoBook(SavePlace);
ADOQuery1.FreeBook(SavePlace);
ADOQuery1.EnableControls;
end;
但是Hank(星星农场)提出的多用户问题也值得担忧 “当然,多用户情况下会出现很多中情况,譬如你刚刚输入的可能被其它用户删除了,这样你Locate就找不到了;当你保存的是最后一条记录,Open后别人又删除了上面某一条,这样RecNo就得进行额外处理。”对于这种情况,可不可以比对刷新前和刷新后的记录条数来判断是否进行定位?因为上述的情况只有在极少数的情况下才发生,在绝大多数的时候都可以完美的实现Refresh效果。
int count;
count = ADOQuery1->RecordCount;
SavePlace = ADOQuery1->GetBook();
ADOQuery1->DisableControls();
ADOQuery1->Requery(); //与先Close再Open等效
if(count == ADOQuery1->RecordCount)
{
ADOQuery1->GotoBook(SavePlace);
}
ADOQuery1->FreeBook(SavePlace);
ADOQuery1->EnableControls();实验了,可以的,明天来结贴