如何在同一窗体的TButton中调用OnCloseQuery事件?
嘿,我来帮你搞定这个问题!首先咱们得先搞清楚FormCloseQuery事件的两个参数分别是什么意思,这样你就知道该传啥了:
参数说明
Sender: 触发这个事件的对象,你可以传当前点击的TButton,或者直接传窗体本身(Self)——你的代码里没用到这个参数,所以两种传法都没问题。var CanClose: 这是个引用类型的参数,用来告诉调用者是否允许关闭窗体。你需要先声明一个布尔变量,初始值可以设为True,然后把它传进去,事件里的逻辑会根据交互修改这个值。
正确的调用方式
在你的TButton的OnClick事件里,写这样的代码:
procedure TfrmAllowance.btnCloseFormClick(Sender: TObject); var CanClose: Boolean; begin // 先默认允许关闭,FormCloseQuery里会根据逻辑修改这个值 CanClose := True; // 调用FormCloseQuery事件处理过程 FormCloseQuery(Self, CanClose); // 如果事件里允许关闭,就执行窗体关闭操作 if CanClose then Close; end;
顺便优化下原代码的小问题
看了你写的FormCloseQuery代码,有两个地方可以调整得更规范:
- 尽量避免使用
with语句,虽然看起来简洁,但很容易因为变量名冲突导致难以排查的bug,直接写出完整的对象路径更清晰。 - 你的
ApplyUpdates调用有点重复,正确的提交更新流程应该是这样的:
procedure TfrmAllowance.FormCloseQuery(Sender: TObject; var CanClose: Boolean); var UpdateErrors: Integer; begin // 确认是否要关闭窗体 if MessageDlg('Are you sure you want to close Setup Allowance?', mtConfirmation, [mbYes, mbCancel], 0) <> mrYes then begin CanClose := False; Exit; // 直接退出,不用执行后面的逻辑 end; // 检查数据集是否处于编辑/插入状态 if dm_u.dmPayroll.cdsAllowance.State in [dsEdit, dsInsert] then begin manpower_u.frmManpower.btnAllowances.Enabled := true; if MessageDlg('Do you wish to save the Setup Allowance changes?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then begin UpdateErrors := dm_u.dmPayroll.cdsAllowance.ApplyUpdates(0); if UpdateErrors = 0 then begin dm_u.dmPayroll.cdsAllowance.CommitUpdates; // 确认提交,清除更新缓存 dm_u.dmPayroll.cdsAllowance.Refresh; end else begin MessageDlg('Failed to save changes. Please check your data.', mtError, [mbOK], 0); dm_u.dmPayroll.cdsAllowance.CancelUpdates; // 取消更新,恢复到修改前的状态 CanClose := False; // 保存失败则不允许关闭 end; end; end; dm_u.dmPayroll.cdsAllowance.Active := False; end;
这样调整后,代码逻辑更清晰,也能处理更新失败的情况,避免出现意外问题。
内容的提问来源于stack exchange,提问作者Juke
相关产品推荐
相关产品推荐

