如何在单击窗体上的X(关闭按钮)时阻止validation被触发

这是一个winform C#问题。 我有一个带有validation事件监听器的文本框来validation文本框的内容。 比如说,文本框不接受负值。 我只收听validation事件,所以默认情况下,文本框的AutoValidate属性是EnablePreventFocusChange,这对我来说完全没问题。

问题是,当我单击表单右上角的X按钮时,我不希望激活validation因为我正在关闭表单。 我怎样才能做到这一点? 无法将CauseValidation设置为false,如果有关闭按钮,我可以这样做。 非常感谢你。

嗯,我认为这样做的唯一方法是将AutoValidate上的AutoValidate设置为false并手动处理控件中的validation。 该表单具有.Validate().ValidateChildren()方法,请阅读这些方法,因为它们是您执行validation所需的内容。 要手动处理它,您需要监听控件何时失去焦点 – 如果validation失败,则需要重新关注有问题的控件。

或者,使表单ControlBox = false; 删除X按钮。

更新:或者,您可以再次使用成员变量来测试是否validation(即表单是否正在关闭)。 您无法使用FormClosing事件执行此操作,因为这会在validation后触发,但您可以通过WndProc检测表单关闭。 此post中提供了代码:

http://technoblot.wordpress.com/2006/09/08/winforms-causesvalidation-not-working-a-workaround/

稍微少一些涉及的解决方法。

我通过将窗体CausesValidation属性设置为False来解决此问题。 单击X按钮时,表单现在正常关闭。

关闭表单时,表单检查表单的AutoValidate属性是否具有与Disabled不同的值,然后提高焦点控件的Validating事件。 此外,如果存在任何validation错误(通过在validation事件中设置e.Cancel = true),它将阻止关闭表单。

为了防止在关闭表单时引发validation错误,您需要覆盖WndProc并在处理WM_CLOSE消息之前将AutoValidate设置为Disabled ,然后将其设置回原始值。 将其设置回原始值的原因是因为您可能希望阻止关闭表单,然后预期AutoValidate的值与开发人员最初设置的值相同:

 private const int WM_CLOSE = 0x0010; protected override void WndProc(ref Message m) { if (m.Msg == WM_CLOSE) { var autoValidate = this.AutoValidate; this.AutoValidate = AutoValidate.Disable; base.WndProc(ref m); this.AutoValidate = autoValidate; } else base.WndProc(ref m); } 

注意:如果您只想在单击关闭按钮后允许表单关闭,则足以覆盖OnClose方法并设置e.Cancel = false 。 但它不会阻止Validating事件。 即使聚焦控件中存在validation错误,它也只允许表单关闭。

您可以在这篇文章中阅读有关该问题的更多信息: 在关闭表单时防止提高焦点控制的validation事件 。