我正在考虑验证用户输入的最佳方法。
让我们设想一些TextBoxes,CheckBoxes或任何你喜欢的.NET控件,其中用户输入必须被验证为OK或NOK。一旦用户填写了他通过按钮提交的所有必填字段。
现在我必须知道哪些字段先前已确认为OK,哪些字段为NOK。到目前为止,我总是通过为每个控件声明一个全局bool变量来处理这种情况。但我不喜欢那样......
我很确定必须有另一种方式!我想要做的是使用名为status或类似的OK或NOK属性扩展这些.NET控件。你能做到吗?如果是这样,你怎么做?这样的东西已经存在吗?
感谢您的答复!
您在Windows窗体中有一些有用的工具来执行验证并显示错误消息,包括:
IDataErrorInfo
界面Validating
控制事件ErrorProvider
组件ValidateChildren
方法和形式的AutoValidate
属性使用以上选项:
IDataErrorInfo接口
如果您有一些模型类,最适合验证并在Windows窗体中提供错误消息正在实现IDataErrorInfo
。它受到数据绑定机制和一些窗口控件的支持,如DataGridView
和ErrorProvider
。
为了简单起见,您可以在类中编写验证规则,并使用IDataErrorInfo
属性返回错误消息。即使你想应用更高级的场景,比如使用验证引擎,最后最好实现IDataErrorInfo
以获得与寡妇表单最一致的内容。
您将使用ErrorProvider
来显示错误消息。它足以将其绑定到您的数据源,并自动显示错误。
验证控件的事件
如果您没有模型类并且所有验证都应该针对控件完成,那么最好的选择是使用控件的Validating
事件。在那里你可以设置e.Cancel = true
来将控制状态设置为无效。然后,您可以防止焦点更改或使用控制状态获取验证摘要。
在这种情况下,您将使用ErrorProvider
来显示错误。以这种方式为Validating
事件中的控件设置错误就足够了:errorProvider1.SetError(control1, "Some Error")
或者您可以设置一个空的错误消息来删除验证错误。
ErrorProvider组件
在这两种情况下,当您使用数据绑定或使用Validating
事件时,如上所述,ErrorProvider
显示错误图标并带有工具提示,在控件附近显示错误消息。 (DataGridView
使用自己的机制在行和单元格上显示错误,而不使用ErrorProvider
。)
您还可以使用该组件使用组件的GetError
方法获取表单的验证摘要,该方法返回每个控件的错误消息。
ValidateChildren方法和Form的AutoValidate属性
您可以使用ValidateChildren
表单方法或容器控件来检查控件是否存在验证错误。
根据表单的AutoValidate
属性值,它可以防止焦点更改或让焦点从无效控件更改。
将要验证的控件的名称保存到数组中,然后循环遍历它们。如果需要,您还可以在其上设置验证功能。
var elements = new[] {
new { Control = textBox1 },
new { Control = textBox2 }
};
foreach (var elem in elements)
{
elem.Control.BackColor = string.IsNullOrWhiteSpace(elem.Control.Text) ? Color.Yellow : Color.White;
}
将Elem数组包装到类对象中以添加“ok”属性。
这真的取决于你想深入钻洞的深度......
Boolean/bool
就足够了,否则你应该考虑创建一个枚举来保存你的验证状态。Tag
属性来存储验证状态(我个人认为使用Tag
执行此操作是可怕的)。一个例子:
// Provides your validation statuses.
public enum ControlValidation
{
Ok,
NotOk
}
// Provides a contract whereby your controls implement a validation property, indicating their status.
public interface IValidationControl
{
ControlValidation ValidationStatus { get; private set; }
}
// An example of the interface implementation...
public class TextBox : System.Windows.Forms.TextBox, IValidationControl
{
public ControlValidation ValidationStatus { get; private set; }
...
protected override void OnTextChanged(EventArgs e)
{
ValidationStatus = ControlValidation.Ok;
}
}
所有winforms组件都有一个“备用”属性,您可以使用:Tag
。它是一个object
,你可以为它指定任何东西:它不被框架用于任何东西,它对这样的情况很有用。
如果这将被推广,你可以只导出你的控件并添加你的属性,但对于一次性的单一属性,Tag
可以完美地工作。
// OK
myTextBox.Tag = true;
// NOK
myTextBox.Tag = false;
// Undefined
myTextBox.Tag = null;
去检查:
if(myTextBox.Tag is bool)
{
var isOk = (bool)myTextBox.Tag;
if(isOk)
{
// It's OK
} else {
// It's NOK
}
} else {
// It's undefined
}
总而言之,我使用Tag
来处理简单的事情和简单的逻辑。如果您打算拥有更多属性或者它是一个普遍的东西......要么使用其他答案中解释的验证机制,要么派生您的控件:
public class MyTextBox : System.Windows.Forms.TextBox
{
public bool ValidationOK { get; set; }
}
并将控件更改为MyTextBox
(如果您已经拥有它们,打开designer.cs
文件并将所有System.Windows.Forms.TextBox
实例更改为<yourNamespace>.MyTextBox
)等。