我的应用程序有一个TQuery组件,我需要在它的AfterScroll()事件中做一些事情:
void __fastcall TFormMain::Query1AfterScroll(TDataSet *DataSet)
{
// do stuff here...
}
问题在于,当我执行以下操作时,AfterScroll事件显然被触发了两次:
Query1->Active = true; // first call to AfterScroll
Query1->Locate( /* some arguments here */ ); // second call
注意:修改SQL查询而不是Locate()是NO选项
AfterScroll的第一个调用是我不想处理的,因此我正在寻找一种优雅的方法来仅处理第二个。
我的第一个想法是使用AfterOpen()事件即时连接AfterScroll事件处理程序:
__fastcall TFormMain::TFormMain(TComponent* Owner)
: TForm(Owner)
{
Query1->AfterScroll = 0;
}
void __fastcall TFormMain::Query1AfterOpen(TDataSet *DataSet)
{
Query1->AfterScroll = Query1AfterScroll;
}
此解决方案看起来不错,但不起作用,因为在AfterAfter离开时会立即调用AfterScroll。
编辑:
我知道我可以设置一些标志来禁止AfterScroll中的代码从Executing执行(这是我现在所做的(以及:下面第一个答案的描述方式)),但是我在那儿应该是更优雅,更不易出错的方法。
但是经过一些研究,我担心周围没有更好的解决方案。
我的问题是:
捕获正确的AfterScroll调用的正确方法是什么? (在Locate(...)之后调用的那个)
答案 0 :(得分:2)
下面的Delphi代码覆盖了TAdoQuery的标准行为(但应该可以使用)
与支持Locate()
的任何其他TDataSet后代,以便仅仅调用AfterScroll
事件
致电TAdoQuery.Locate
之后。
基本上,它会覆盖TAdoQuery DoAfterScroll
,以便仅在设置了布尔标志FHandleScrollAfterLocate
时才调用继承的方法。 DoAfterScroll
是TDataSet方法,用于调用已设置的任何AfterScroll
处理程序。该标志在覆盖的Locate
函数中设置为True,并在每次调用DoAfterScroll
时清除。
如果您要更改调用AfterScroll
的条件,我相信您会明白的。
type
TAdoQuery = class(ADODB.TAdoQuery)
private
FHandleScrollAfterLocate: Boolean;
protected
property HandleScrollAfterLocate : Boolean read FHandleScrollAfterLocate;
function Locate(const KeyFields: string; const KeyValues: Variant;
Options: TLocateOptions): Boolean; override;
procedure DoAfterScroll; override;
public
end;
TForm1 = class(TForm)
DataSource1: TDataSource;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
ADOConnection1: TADOConnection;
AdoQuery1: TADOQuery;
AdoQuery1ID: TIntegerField;
AdoQuery1name: TStringField;
btnLocate: TButton;
[etc]
[...]
{ TAdoQuery }
procedure TAdoQuery.DoAfterScroll;
begin
try
if FHandleScrollAfterLocate then
inherited;
finally
FHandleScrollAfterLocate := False;
end;
end;
function TAdoQuery.Locate(const KeyFields: string;
const KeyValues: Variant; Options: TLocateOptions): Boolean;
begin
FHandleScrollAfterLocate := True;
Result := inherited Locate(KeyFields, KeyValues, Options);
end;
procedure TForm1.AdoQuery1AfterScroll(DataSet: TDataSet);
begin
Caption := 'Scrolled';
end;
procedure TForm1.btnLocateClick(Sender: TObject);
begin
AdoQuery1.Locate('ID', 5, []);
end;