Skr*_*rud 2 delphi validation focus delphi-5
在我正在处理的应用程序的一部分中,有一个表单控件在接收CMExit消息时进行验证,这正是Delphi文档所说的(这段代码示例来自Delphi帮助文件):
procedure TDBCalendar.CMExit(var Message: TWMNoParams);
begin
try
FDataLink.UpdateRecord; { tell data link to update database }
except
on Exception do SetFocus; { if it failed, don't let focus leave }
end;
inherited;
end;
Run Code Online (Sandbox Code Playgroud)
这样做的目的是在控件失去焦点时立即执行验证.因此,例如,如果我单击"确定"按钮,表单控件将失去焦点,此方法将运行,并且异常会将焦点设置回该表单控件.(因此,OK按钮上的"click"事件永远不会通过,对话框永远不会关闭).
我遇到的问题是这个表单控件在一个模态对话框窗口内.单击确实确实发送CMExit消息并导致记录更新(并进行验证).但是,在窗体控件中按Enter键会导致模式对话框关闭而不发送CMExit消息.好像表单控件从不"失去焦点".这意味着不仅在没有实际验证数据的表单的情况下关闭对话框,而且数据集也不会更新.
鉴于此问题,我放置数据集更新/验证代码的最佳位置在哪里?我可以将它移动到对话框表单本身并在OnCloseQuery处理程序中实现它,但这意味着逻辑在表单控件和表单本身都是重复的.(表单控件在其他地方使用,我想避免改变它的行为).
(我推测,CM退出不会被触发,因为控制从未实际上不失去焦点.窗体关闭,但形式仍然控制"有焦点"的封闭形式.)
关闭表单不一定会触发TControl的退出事件.例如,用户可以按Alt-F4.
我建议将验证移到单独的proc中,并从出口和关闭事件中调用单独的proc .
以下代码应该无需太多修改即可运行:
function TDBCalendar.UpdateSuccessful: boolean;
begin
{ tell data link to update database }
{ if successful, return True, else return False }
{ this function must be Public if a form is gonna check this value }
Result := True;
try
FDataLink.UpdateRecord;
except on Exception do
Result := False;
end;
inherited;
end;
procedure TDBCalendar.CMExit(var Message: TWMNoParams);
begin
//if not valid, then don't let them leave
if not(UpdateSuccessful) then begin
SetFocus;
end;
end;
///////////////////////////////////////////
//on the form that contains your control...
///////////////////////////////////////////
procedure TMyForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//if not valid, then don't let them close the form
if not(dbcal.ControlIsValid) then begin
Action := caNone;
end
else begin
inherited;
end;
end;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1843 次 |
最近记录: |