validation用户输入/给.NET控件状态OK或NOK
我正在考虑validation用户输入的最佳方法。
让我们设想一些TextBoxes,CheckBoxes或任何你喜欢的.NET控件,用户输入必须被validation为OK或NOK。 一旦用户填写了他通过按钮提交的所有必填字段。
现在我必须知道哪些字段先前已确认为OK,哪些字段为NOK。 到目前为止,我总是通过为每个控件声明一个全局bool变量来处理这种情况。 但我不喜欢那样……
我很确定必须有另一种方式! 我想要做的是使用名为status或类似的OK或NOK属性扩展这些.NET控件。 你能这样做吗? 如果是这样,你怎么做? 类似的东西已经存在吗?
感谢您的答复!
您在Windows窗体中有一些有用的function来执行validation并显示错误消息,包括:
-
IDataErrorInfo
接口 -
Validating
控件的事件 -
ErrorProvider
组件 - 表单的
ValidateChildren
方法和AutoValidate
属性
使用以上选项:
- 您可以在使用数据绑定到模型类时执行validation。
- 当您不使用数据绑定时,您可以执行validation。
- 您可以在控件附近显示错误消息和错误图标,这些图标处于无效状态。
- 您可以决定阻止无效控件的焦点更改或让焦点发生变化。
- 您可以显示表单的validation摘要。
IDataErrorInfo接口
如果您有一些模型类,最适合validation并在Windows窗体中提供错误消息的方法是实现IDataErrorInfo
。 它受数据绑定机制和一些Windows窗体控件(如DataGridView
和ErrorProvider
。
为了简单IDataErrorInfo
您可以在类中编写validation规则,并使用IDataErrorInfo
属性返回错误消息。 即使您想要应用更高级的方案(如使用validation引擎),最后也最好实现IDataErrorInfo
以获得与widows表单的最大一致性。
您将使用ErrorProvider
显示错误消息。 它足以将其绑定到您的数据源,并自动显示错误。
validation控件的事件
如果您没有模型类并且所有validation都应该针对控件完成,那么最好的选择是使用Validating
控件事件。 在那里你可以设置e.Cancel = true
来将控制状态设置为无效。 然后,您可以防止焦点更改或使用控制状态获取validation摘要。
在这种情况下,您将使用ErrorProvider
来显示错误。 以这种方式在Validating
事件中为控件设置错误就足够了: errorProvider1.SetError(control1, "Some Error")
或者您可以设置一个空错误消息来删除validation错误。
ErrorProvider组件
在这两种情况下,当您使用数据绑定或使用Validating
事件时,如上所述, ErrorProvider
显示错误图标,并带有工具提示,在控件附近显示错误消息。 ( DataGridView
使用自己的机制在行和单元格上显示错误,而不使用ErrorProvider
。)
您还可以使用该组件使用组件的GetError
方法获取表单的validation摘要,该方法返回每个控件的错误消息。
表单的ValidateChildren方法和AutoValidate属性
您可以使用表单的ValidateChildren
方法或容器控件来检查控件是否存在validation错误。
根据表单的AutoValidate
属性值,它可以防止焦点更改或让焦点从无效控件更改。
将要validation的控件的名称保存到数组中,然后循环遍历它们。 如果需要,您还可以在其上设置validationfunction。
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”属性。
这真的取决于你想深入挖掘兔子洞的深度……
-
您需要确定validation状态 – 如果它只是Yes / No的情况,那么
Boolean/bool
就足够了,否则您应该考虑创建一个枚举来保存validation状态。 -
您需要决定是否要扩展需要validation的控件,或者只使用控件的
Tag
属性来存储validation状态(我个人认为使用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
来处理简单的事情和简单的逻辑。 如果您打算拥有更多属性或者它是一个普遍的东西……要么使用其他答案中解释的validation机制,要么派生您的控件:
public class MyTextBox : System.Windows.Forms.TextBox { public bool ValidationOK { get; set; } }
并将控件更改为MyTextBox
(如果已有它们,请打开designer.cs
文件并将System.Windows.Forms.TextBox
所有实例更改为
)等。