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

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

防止控件被离开。

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


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

2
明智地使用 Control.CausesValidation 属性可以帮助您实现所需的功能。

1
在补充Daniel Schaffer的回答时:如果验证发生在编辑框失去焦点时,您可以禁止按钮激活来绕过本地验证并无论如何退出。
public class UnselectableButton : Button
{
    public UnselectableButton()
    {
        this.SetStyle(ControlStyles.Selectable, false);
    }
}

或者,如果您使用DevExpress:
this.simpleButtonCancel.AllowFocus = false;

请注意,这样做将会改变键盘的使用体验:tab键将不再聚焦于取消按钮。

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);
    }

0

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

首先,我们将一个UserControl加载到一个带有保存和取消按钮的“shell”Form中。 UserControl继承了一个接口(如IEditView),该接口具有SaveCancelValidateToggleValidate函数。

在shell表单中,我们使用鼠标进入和离开来实现:

    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;
    }

希望这能帮到你。

0
创建一个布尔变量:
bool doOnce;

在你的函数中将它设置为false,然后:

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

这意味着它只会运行一次,而且您应该能够取消它。无论如何,这对我起作用了。


0

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

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

对于这个复杂的表单,没有任何作用。

在阅读评论时,我发现了一个看起来完美的解决方案

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

这就是诀窍。

AutoValidate = AutoValidate.Disable;

-2

这对我有用。

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

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