当用户将数据输入到应用程序中时,可以在应用程序使用它之前验证数据是否有效。 你可能要求某些文本字段长度不为零、格式为电话号码的字段或字符串不包含无效字符。 Windows 窗体提供了多种方式来验证应用程序中的输入。
MaskedTextBox 控件
如果需要要求用户以定义完善的格式(如电话号码或部件号)输入数据,则可以使用 MaskedTextBox 控件快速、最少的代码来实现此目的。 掩码是由掩码语言中的字符组成的字符串,指定可以在文本框中的任何给定位置输入哪些字符。 该控件向用户显示一组提示。 如果用户输入了不正确的条目,例如在需要输入数字时输入了字母,控件会自动拒绝该输入。
使用的 MaskedTextBox 掩码语言很灵活。 它允许指定所需的字符、可选字符、文本字符,如连字符和括号、货币字符和日期分隔符。 绑定到数据源时,该控件也有效。 数据 Format 绑定上的事件可用于重新格式化传入数据以符合掩码,事件 Parse 可用于重新格式化传出数据,以符合数据字段的规范。
事件驱动的验证
如果希望完全以编程方式控制验证,或者需要复杂的验证检查,则应使用大多数 Windows 窗体控件中内置的验证事件。 每个接受自由格式用户输入的控件都有一个Validating事件,它会在控件需要进行数据验证时触发。 在事件处理程序代码中 Validating ,可以通过多种方式验证用户输入。 例如,如果你有一个必须包含邮政编码的文本框,则可以通过以下方式进行验证:
如果邮政编码必须属于特定邮政编码组,则可以对输入执行字符串比较,以验证用户输入的数据。 例如,如果邮政编码必须位于集中
{10001, 10002, 10003}
,则可以使用字符串比较来验证数据。如果邮政编码必须采用特定格式,则可以使用正则表达式来验证用户输入的数据。 例如,若要验证窗体
#####
,#####-####
也可以使用正则表达式^(\d{5})(-\d{4})?$
。 若要验证表单A#A #A#
,可以使用正则表达式[A-Z]\d[A-Z] \d[A-Z]\d
。 有关正则表达式的详细信息,请参阅 .NET 正则表达式 和 正则表达式示例。如果邮政编码必须是有效的美国邮政编码,则可以调用邮政编码 Web 服务来验证用户输入的数据。
事件 Validating 提供了一种 CancelEventArgs 类型的对象。 如果确定控件的数据无效,可以通过将此对象的Cancel属性设置为true
来取消Validating事件。 如果未设置属性 Cancel,Windows 窗体假定该控件的验证为成功并引发该事件 Validated。
要查看在 TextBox 中验证电子邮件地址的代码示例,请参阅 Validating 事件参考。
事件驱动的验证数据绑定控件
将控件绑定到数据源(例如数据库表)时,验证非常有用。 通过使用验证,可以确保控件的数据满足数据源所需的格式,并且它不包含任何特殊字符,例如引号和可能不安全的反斜杠。
使用数据绑定时,控件中的数据在执行事件期间 Validating 会与数据源同步。 如果取消事件 Validating ,则数据不会与数据源同步。
重要
如果在 Validating 事件之后执行自定义验证,则不会影响数据绑定。 例如,如果在尝试取消数据绑定的事件中有 Validated 代码,则数据绑定仍将发生。 在这种情况下,若要在Validated事件中执行验证,请将控件的Binding.DataSourceUpdateMode
属性从DataSourceUpdateMode.OnValidation更改为DataSourceUpdateMode.Never,并将your-control.DataBindings["field-name"].WriteValue()
添加到验证代码中。
隐式验证和显式验证
那么,控件的数据何时得到验证? 这是由开发人员决定的。 可以根据应用程序的需求使用隐式验证或显式验证。
隐式验证
隐式验证方法会在用户输入数据时验证数据。 通过读取按下的键来验证数据,或者更常见的是在用户将输入焦点移开控件时进行验证。 当你希望为用户在处理数据时提供即时反馈,此方法非常有用。
如果要对控件使用隐式验证,必须将该控件 AutoValidate 的属性 EnablePreventFocusChange 设置为或 EnableAllowFocusChange。 如果取消事件 Validating ,控件的行为将取决于分配给 AutoValidate哪个值。 如果您分配了EnablePreventFocusChange,那么取消该事件将阻止Validated事件的发生。 输入焦点将保留在当前控件上,直到用户将数据更改为有效格式。 如果分配了EnableAllowFocusChange,则在取消Validated事件时不会发生该事件,但焦点仍会切换到下一个控件。
将Disable分配给AutoValidate属性会完全阻止隐式验证。 若要验证控件,请使用显式验证。
显式验证
显式验证方法一次验证数据。 可以验证数据以响应用户作,例如单击 “保存 ”按钮或 “下一步 ”链接。 发生用户作时,可以通过以下方式之一触发显式验证:
- 调用 Validate 以验证最后一个控件是否失去焦点。
- 调用 ValidateChildren 以验证窗体或容器控件中的所有子控件。
- 调用自定义方法以手动验证控件中的数据。
控件的默认隐式验证行为
Windows 窗体的不同控件有不同的默认 AutoValidate 属性值。 下表显示了最常见的控件及其默认值。
控制 | 默认验证行为 |
---|---|
ContainerControl | Inherit |
Form | EnableAllowFocusChange |
PropertyGrid | Visual Studio 中未公开的属性 |
ToolStripContainer | Visual Studio 中未公开的属性 |
SplitContainer | Inherit |
UserControl | EnableAllowFocusChange |
关闭窗体并重写验证
当控件由于包含的数据无效而保持焦点时,不可能以一种常用方式关闭父窗体:
- 单击“ 关闭 ”按钮。
- 选择 “系统>关闭 ”菜单。
- 以编程方式调用该方法 Close。
但是,在某些情况下,你可能希望让用户关闭窗体,而不考虑控件中的值是否有效。 通过为表单的FormClosing事件创建处理程序,可以覆盖验证并关闭仍包含无效数据的窗体。 在事件中,将 Cancel 属性设置为 false
. 这会强制窗体关闭。 有关详细信息和示例,请参阅 Form.FormClosing。
注释
如果强制窗体以这种方式关闭,则未保存的数据将丢失。 此外,模式窗体在关闭控件时不会验证控件的内容。 你仍然可以使用控件验证将焦点锁定到控件,但不必担心与关闭窗体相关的行为。