如果我忽略了一些明显的东西,请道歉。
问题背景
我有一个允许用户填写表格的应用程序,其内容将上传到数据库。当他们点击上传'按钮,表单必须经过验证。如果任何字段无效,将提醒用户。
当前解决方案
当用户点击按钮上传交易时,会调用validFormSelections()
。
if (!this.validateChildren())
{
// Display an error
return false;
}
else
{
return true;
}
对于每个组合框,调用验证方法,例如,
cmbName_Validating(object sender, CancelEventArgs e)
{
if (/* not valid for whatever reason */)
{
errorProvider.Clear();
e.Cancel = true;
errorProvider.setError((Control)sender, /* suitable error message */)
}
else
{
errorProvider.SetError((Control)sender, "");
}
}
问题
我要做的是显示所有字段旁边的errorProvider
无效,但是在单个验证中e.Cancel = true;
以来的那一刻方法,然后(如果我的理解是正确的),一旦找到第一个无效字段,它就不会继续验证其他字段。
如何制作,以便我可以拨打this.validateChildren()
并在所有无效字段旁边显示errorProvider
?
到目前为止尝试研究解决方案
据我了解,我的问题是需要设置CancelEventArgs
' Cancel
属性为true,因为它会切断'}其余的验证。因此,最好找到一种方法来避免在以后设置此属性或找到解决此问题的方法。但我不知道该怎么做。
我最初的一个想法是,如果我能从每个验证事件处理程序返回boolean
,我可以相当容易地解决这个问题(但我怀疑,并且从那时起我已经知道,我不能这样做)。我看到在事件处理程序中返回值的替代方法是传入一个可变值(例如,CancelEventArgs
本身)。这似乎可能是一个合适的解决方案,但是我不确定自己如何做到这一点......
答案 0 :(得分:3)
设置e.Cancel = true
当然是个问题。所以不要那样做。它通常是一个相当不愉快的功能,使数据输入非常模态。一种更友好的方法是让用户自由统治数据输入任务,按照您设置标签顺序时所设想的顺序输入数据。
只需编写一个简单的辅助方法即可。例如:
private Control firstInvalidControl;
private void SetValidation(object sender, bool ok, string errMsg) {
var ctl = (Control)sender;
if (ok) errorProvider1.SetError(ctl, "");
else {
if (firstInvalidControl == null) firstInvalidControl = ctl;
errorProvider1.SetError(ctl, errMsg);
}
}
在控件的Validating事件处理程序中调用SetValidation()。现在,您可以非常轻松地显示所有相应的警告,并帮助用户导航到他可能需要首先处理的控件。例如:
private void OKButton_Click(object sender, EventArgs e) {
firstInvalidControl = null;
this.ValidateChildren();
if (firstInvalidControl != null) firstInvalidControl.Focus();
else {
// Data is good, use it
// ...
}
}