在 OnOK 中保存对话框数据时出现问题
Problems saving dialog data in OnOK
有没有人在CMyDialog::OnOK
中找到将对话数据保存到数据库的好方法?
void CMyDialog::OnOK()
{
// If I save my data here, I don't know if DoDataExchange()
// found validation errors.
CDialog::OnOK();
// If I save my data here, EndDialog() has already been called
}
寻找关于如何最好地构建它的想法。我知道通常是让调用者根据需要保存数据,但我不希望在将数据保存到数据库时遇到错误时关闭对话框。
如果 CDialog::UpdateData()
是虚拟的,这似乎是一个很好的解决方案,但事实并非如此。
因此,很明显 MFC 并非设计为以这种方式工作。
但我找到的最简单的解决方案是修改DoDataExchange()
如下:
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
// DDX and DDV calls go here
if (pDX->m_bSaveAndValidate)
{
if (!SaveData())
pDX->Fail();
}
}
上面的代码依赖于 SaveData()
显示错误消息并在遇到任何错误时返回 false。
结果是在我尝试保存数据之前执行了常规验证。而且,如果保存数据的代码失败,我仍然可以通过 MFC 验证方法使用的相同技术来阻止对话框关闭。 (即,通过调用 pDX->Fail()
)。
在你的评论中你是这样说的:
// If I save my data here, EndDialog() has already been called
这意味着名为 m_hWnd
的 HWND
已关闭,所有子控件都已关闭。 window 已死,但您的 CVehicleDlg
实例未死。与数据交换相关联的成员变量将从控件传输到它们的值。你应该好好去存钱。
另一种方法是在 class 中捕获 OnDestroy
而不是 OnOK
。这样,您将获得 OnOk
的默认处理来进行数据验证。除非数据验证失败,否则 window 不会被销毁。当你的对话框被销毁时,你必须特殊情况 OnCancel
将一些标志设置为 "not save"。
为什么不直接使用 UpdateData
?
return值:
Nonzero if the operation is successful; otherwise 0. If bSaveAndValidate
is TRUE
, then a return value of nonzero means that the data is successfully validated.
所以:
void CMyDialog::OnOK()
{
if(!UpdateData(TRUE))
{
// There was some error with the validation procedure so don't end the dialog.
return; // Suppress closing dialog
}
// OK to save data
if(!SaveDataToDatabase())
{
// Some error
return;
}
// Data validated Ok and was saved to DB OK, so close
EndDialog(IDOK);
}
除非我想不明白你的问题。
有没有人在CMyDialog::OnOK
中找到将对话数据保存到数据库的好方法?
void CMyDialog::OnOK()
{
// If I save my data here, I don't know if DoDataExchange()
// found validation errors.
CDialog::OnOK();
// If I save my data here, EndDialog() has already been called
}
寻找关于如何最好地构建它的想法。我知道通常是让调用者根据需要保存数据,但我不希望在将数据保存到数据库时遇到错误时关闭对话框。
如果 CDialog::UpdateData()
是虚拟的,这似乎是一个很好的解决方案,但事实并非如此。
因此,很明显 MFC 并非设计为以这种方式工作。
但我找到的最简单的解决方案是修改DoDataExchange()
如下:
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
// DDX and DDV calls go here
if (pDX->m_bSaveAndValidate)
{
if (!SaveData())
pDX->Fail();
}
}
上面的代码依赖于 SaveData()
显示错误消息并在遇到任何错误时返回 false。
结果是在我尝试保存数据之前执行了常规验证。而且,如果保存数据的代码失败,我仍然可以通过 MFC 验证方法使用的相同技术来阻止对话框关闭。 (即,通过调用 pDX->Fail()
)。
在你的评论中你是这样说的:
// If I save my data here, EndDialog() has already been called
这意味着名为 m_hWnd
的 HWND
已关闭,所有子控件都已关闭。 window 已死,但您的 CVehicleDlg
实例未死。与数据交换相关联的成员变量将从控件传输到它们的值。你应该好好去存钱。
另一种方法是在 class 中捕获 OnDestroy
而不是 OnOK
。这样,您将获得 OnOk
的默认处理来进行数据验证。除非数据验证失败,否则 window 不会被销毁。当你的对话框被销毁时,你必须特殊情况 OnCancel
将一些标志设置为 "not save"。
为什么不直接使用 UpdateData
?
return值:
Nonzero if the operation is successful; otherwise 0. If
bSaveAndValidate
isTRUE
, then a return value of nonzero means that the data is successfully validated.
所以:
void CMyDialog::OnOK()
{
if(!UpdateData(TRUE))
{
// There was some error with the validation procedure so don't end the dialog.
return; // Suppress closing dialog
}
// OK to save data
if(!SaveDataToDatabase())
{
// Some error
return;
}
// Data validated Ok and was saved to DB OK, so close
EndDialog(IDOK);
}
除非我想不明白你的问题。