点击表单取消按钮后如何跳过验证

49
我使用C#。 我有一个带有编辑框和取消按钮的Windows表单。编辑框在验证事件中有代码。每当编辑框失去焦点时,该代码都会被执行。当我点击取消按钮时,我只想关闭表单,而不想执行任何对编辑框的验证。如何实现这一点?
这里有一个重要的细节:如果验证失败,则
            e.Cancel = true;

防止控件被离开。

但是当用户点击取消按钮时,无论如何都应该关闭表单。如何实现?


1
无论您对“取消”按钮进行何种操作,当文本框失去焦点时,验证代码仍将执行。 - Stewbob
17个回答

53
如果在编辑框失去焦点时进行验证,那么取消按钮无法阻止验证的发生。但是,如果验证失败会阻止取消按钮的功能,可以将按钮的“CausesValidation”属性设置为“false”。 参考:Button.CausesValidation 属性

不确定为什么有人踩了这个。对于一个WinForms应用程序,这是正确的。其他三个答案都是错误的。 - Stewbob
1
@DanielSchaffer:我不确定我是否正确理解了“however”部分。当用户点击取消按钮时,我该如何防止验证过程的进行?验证会触发一个消息框,即使用户想要取消编辑/添加对象,也会始终显示,因为验证是在按钮单击之前发生的。我甚至尝试从BtnCancelMouseEnter设置CausesValidation=false(也没有起作用)。 - Tim Schmelter
1
@Stewbob 我认为第一句话是不正确的。文本框的验证事件在定义上发生在文本框失去焦点时,如果它失去焦点到取消按钮,将CausesValidation设置为false将阻止这种情况发生。答案会让人误以为先进行验证,然后取消按钮才起作用,而实际上根本没有进行任何验证。 - Imperishable Night

37

显然,必须将按钮的CausesValidation属性设置为false,这样在点击它时验证事件就不会发生。但是,如果按钮的父控件的CausesValidation属性设置为true,则此方法可能失败。大多数情况下,开发人员会忘记更改容器控件(例如面板控件)的CausesValidation属性。也要将其设置为False。这样应该就可以解决问题了。


7
由于容器本身无法获得焦点,因此 Microsoft 应将默认值 CausesValidation 设置为 False - Mark Ransom
如果我有嵌套的容器,我是需要将所有容器都设置为False,还是只需要设置我的按钮的直接父容器? - dotNET
2
又过了几个月,我又回来了 :). 后来我自己弄明白了。你不需要为所有父容器都设置它。只需设置直接父级即可。 - dotNET

25

我的表单一直关闭不了,因为某些控件的验证会阻止表单关闭。我已经为取消按钮及其所有父级设置了control.CausesValidation = false,但问题仍然存在。

似乎如果用户正在编辑一个使用验证功能的字段,并决定放弃(使该字段的输入无效),则取消按钮事件将被触发,但窗口不会关闭。

以下是在取消按钮点击事件中解决此问题的方法:

private void btnCancel_Click(object sender, EventArgs e)
{
    // Stop the validation of any controls so the form can close.
    AutoValidate = AutoValidate.Disable;
    Close();
}

19

将“CausesValidation”属性设置为“false”,以取消按钮的验证功能。


4

这些答案都不完全解决问题,但此帖子中的最后一个答案可以。基本上,您需要:

  1. Insure that the Cancel button (if any) has .CausesValidation set to false
  2. Override this virtual method.

    protected override bool ProcessDialogKey(Keys keyData) {
        if (keyData == Keys.Escape) {
            this.AutoValidate = AutoValidate.Disable;
            CancelButton.PerformClick();
            this.AutoValidate = AutoValidate.Inherit;
            return true;
        }
        return base.ProcessDialogKey(keyData);
    }
    
我没有真正回答这个问题,只是指向实际回答的两个人。

4

CausesValidation属性设置为false


3

将CausesValidation设置为false是关键,但仅此还不够。如果按钮的父级已将CausesValidation设置为true,则仍会调用验证事件。在我的一个案例中,我在表单上的面板上放置了一个取消按钮,因此我必须在面板和表单上都将CausesValidation设置为false。最终,我以编程方式执行此操作,因为这比浏览所有表单更简单...

Control control = cancelButton;

while(control != null)
{
   control.CausesValidation = false;
   control = control.Parent;
}

3
在我的情况下,我设置了表单的属性AutoValidateEnableAllowFocusChange

3
通过使用Visual Studio向导,您可以像这样完成:

enter image description here


这个单一的设置对我来说非常有效,将取消按钮的 CausesValidation 设置为“false”。 - Jamesckel

2
在编辑框上方的验证代码之上添加以下内容:
if (btnCancel.focused)
  {
     return;
  }

那应该就可以了。

它对我来说不起作用。 - Kevin S. Miller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接