如何在单击“表单”的“取消”按钮后跳过“验证”

时间:2009-12-10 17:16:15

标签: c# winforms validating

我使用C#。 我有一个带有编辑框和取消按钮的Windows窗体。编辑框包含验证事件的代码。每次编辑框失去焦点时都会执行代码。当我点击取消按钮时,我只想关闭表单。我不想要对编辑框进行任何验证。如何实现这一目标?

以下是一个重要细节:如果验证失败,那么

            e.Cancel = true;

阻止离开控件。

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

17 个答案:

答案 0 :(得分:45)

如果在编辑框失去焦点时进行验证,则取消按钮的任何内容都不会阻止它发生。

但是,如果验证失败阻止取消按钮执行此操作,请将按钮的CausesValidation属性设置为false

Reference: Button.CausesValidation property

答案 1 :(得分:31)

显然,按钮的CausesValidation属性必须设置为false,然后验证事件将永远不会发生在其单击上。但是,如果按钮的父控件的CausesValidation属性设置为true,则此操作可能会失败。大多数情况下,开发人员错过/忘记更改容器控件的CausesValidation属性(如面板控件)。将其设置为False。这应该可以解决问题。

答案 2 :(得分:21)

我在让表单关闭时遇到问题,因为某些控件的验证正在停止它。我为取消按钮和取消按钮的所有父母设置了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();
}

答案 3 :(得分:18)

将“取消”按钮的CausesValidation属性设置为false

答案 4 :(得分:4)

CausesValidation属性设置为false

答案 5 :(得分:4)

这些答案都没有完成这项工作,但this thread的最后答案确实如此。基本上,你需要:

  1. 确保取消按钮(如果有)将.CausesValidation设置为false
  2. 覆盖此虚拟方法。

    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);
    }
    
  3. 我没有真正回答这个问题,只是指着那两个真正做过的人。

答案 6 :(得分:2)

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

Control control = cancelButton;

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

答案 7 :(得分:2)

明智地使用Control.CausesValidation属性将帮助您实现您想要的目标。

答案 8 :(得分:1)

作为Daniel Schaffer答案的补充:如果在编辑框失去焦点时进行验证,您可以forbid the button to activate绕过本地验证并退出。

public class UnselectableButton : Button
{
    public UnselectableButton()
    {
        this.SetStyle(ControlStyles.Selectable, false);
    }
}

或者如果你使用DevExpress:

this.simpleButtonCancel.AllowFocus = false;

请注意,这样做会改变键盘体验:选项卡将再次关注取消按钮。

答案 9 :(得分:1)

在编辑框的验证码上方添加:

if (btnCancel.focused)
  {
     return;
  }

应该这样做。

答案 10 :(得分:1)

就我而言,我在表单中将属性 AutoValidate 设置为 EnableAllowFocusChange

答案 11 :(得分:1)

通过使用Visual Studio向导,您可以这样做:

enter image description here

答案 12 :(得分:0)

也许您希望使用BackgroundWorker来提供一点延迟,因此您可以决定是否应该运行验证。以下是避免表单关闭验证的示例。

    // The flag
    private bool _isClosing = false;

    // Action that avoids validation
    protected override void OnClosing(CancelEventArgs e) {
        _isClosing = true;
        base.OnClosing(e);
    }

    // Validated event handler
    private void txtControlToValidate_Validated(object sender, EventArgs e) {           
        _isClosing = false;
        var worker = new BackgroundWorker();
        worker.DoWork += worker_DoWork;
        worker.RunWorkerAsync();
        worker.RunWorkerCompleted += worker_RunWorkerCompleted;
    }

    // Do validation on complete so you'll remain on same thread
    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
        if (!_isClosing)
            DoValidationHere();
    }

    // Give a delay, I'm not sure this is necessary cause I tried to remove the Thread.Sleep and it was still working fine. 
    void worker_DoWork(object sender, DoWorkEventArgs e) {
        Thread.Sleep(100);
    }

答案 13 :(得分:0)

这是一个老问题,但是我最近遇到了这个问题并以这种方式解决了这个问题:

首先,我们正在将 UserControl 加载到具有“保存”和“取消”按钮的“外壳” 表单中。 UserControl 继承一个界面(如 IEditView ),该界面具有保存取消验证< / strong>和 ToggleValidate

在外壳形式中,我们使用鼠标进入和鼠标离开,如下所示:

    private void utbCancel_MouseEnter(object sender, EventArgs e)
    {
        ((Interface.IEdit)tlpMain.Controls[1]).ToggleValidate();
    }

    private void utbCancel_MouseLeave(object sender, EventArgs e)
    {
        ((Interface.IEdit)tlpMain.Controls[1]).ToggleValidate();
    }

然后在ToggleValidate中(说一个具有两个控件的简单表单...如果需要,您始终可以循环浏览列表),我们设置了CausesValidation

    public bool ToggleValidate()
    {
        uneCalcValue.CausesValidation = !uneCalcValue.CausesValidation;
        txtDescription.CausesValidation = !txtDescription.CausesValidation;

        return txtDescription.CausesValidation;
    }

希望这会有所帮助。

答案 14 :(得分:0)

我今天在调查为什么发生验证错误时为什么我的表单无法关闭的时候发现了这个线程。

我在关闭按钮和表单本身上尝试了CausesValidation = false(X表示关闭)。

使用这种复杂形式没有任何帮助。

在阅读所有评论的同时,我发现其中的一条似乎很有效

在表单关闭事件上,而不是关闭按钮上(因此也会在单击X时触发)

这成功了。

AutoValidate = AutoValidate.Disable;

答案 15 :(得分:0)

创建bool:

bool doOnce;

在您的函数中将其设置为false,然后:

if (doOnce == false)
{
    e.cancel = true;
    doOnce = true;
}

这意味着它将仅运行一次,您应该可以取消它。无论如何,这对我有用。

答案 16 :(得分:-1)

这项工作适合我。

private void btnCancelar_MouseMove(object sender, MouseEventArgs e)
{
    foreach (Control item in Form.ActiveForm.Controls)
    {
        item.CausesValidation = false;
    }
}