如何验证用户输入的概述

当用户将数据输入到应用程序中时,可以在应用程序使用它之前验证数据是否有效。 你可能要求某些文本字段长度不为零、格式为电话号码的字段或字符串不包含无效字符。 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

注释

如果强制窗体以这种方式关闭,则未保存的数据将丢失。 此外,模式窗体在关闭控件时不会验证控件的内容。 你仍然可以使用控件验证将焦点锁定到控件,但不必担心与关闭窗体相关的行为。

另请参阅