How to skip Validating after clicking on a Form's Cancel button
Asked Answered
C

18

50

I use C#. I have a Windows Form with an edit box and a Cancel button. The edit box has code in validating event. The code is executed every time the edit box loses focus. When I click on the Cancel button I just want to close the form. I don't want any validation for the edit box to be executed. How can this be accomplished?

Here is an important detail: if the validation fails, then

            e.Cancel = true;

prevents from leaving the control.

But when a user clicks Cancel button, then the form should be closed no matter what. how can this be implemented?

Cynic answered 10/12, 2009 at 17:16 Comment(1)
Nothing you do to the Cancel button will prevent the Validating code from executing when your textbox loses focus.Yukoyukon
K
54

If the validation occurs when the edit box loses focus, nothing about the the cancel button is going to stop that from happening.

However, if the failing validation is preventing the cancel button from doing its thing, set the CausesValidation property of the button to false.

Reference: Button.CausesValidation property

Kensell answered 10/12, 2009 at 17:19 Comment(3)
Not sure why someone down-voted this. For a winforms application, it is true. The other three answers are incorrect.Yukoyukon
@DanielSchaffer: i'm not sure if I understand the "however"-part correctly. How can i prevent the validation from taking place when the user hits the cancel button? The validation triggers a messagebox which is always shown even if the user wants to cancel editing/adding an object because the validating happens before the button-click. I've even tried to set CausesValidation=false from MouseEnter of the BtnCancel(didn't work either).Bindery
@Yukoyukon I think the first sentence is incorrect. The Validating event of a textbox by definition occurs when the textbox loses focus, and in case it is losing focus to the cancel button, setting CausesValidation to false will stop exactly this from happening. The answer would lead one to believe that the validation happens and then the cancel button works, while in reality no validation happens at all.Maurer
R
38

Obviously CausesValidation property of the button has to be set to false and then the validating event will never happen on its click. But this can fail if the parent control of the button has its CausesValidation Property set to true. Most of the time developers misses/forgets to change the CausesValidation property of the container control (like the panel control). Set that also to False. And that should do the trick.

Rohde answered 26/3, 2010 at 21:6 Comment(3)
Microsoft should set the default CausesValidation value to False for containers, since they don't take focus by themselves anyway.Samphire
If I have nested containers, do I have to set it to False all the way up for all containers, or just the immediate parent of my button?Mattins
Here again after a few months :). And I figured it out myself later on. You do not need to set it all the way up for all parent containers. Just setting the immediate parent is sufficient.Mattins
P
25

I was having problems getting my form to close, since the validation of certain controls was stopping it. I had set the control.CausesValidation = false for the cancel button and all the parents of the cancel button. But still was having problems.

It seemed that if the user was in the middle of editing a field that was using validation and just decided to give up (leaving the field with an invalid input), the cancel button event was being fired but the window would not close down.

This was fixed by the following in the cancel button click event:

private void btnCancel_Click(object sender, EventArgs e)
{
    // Stop the validation of any controls so the form can close.
    AutoValidate = AutoValidate.Disable;
    Close();
}
Phagocyte answered 27/9, 2012 at 13:13 Comment(0)
K
19

Set the CausesValidation property of the Cancel button to false.

Kinelski answered 10/12, 2009 at 17:17 Comment(0)
M
4

Set the CausesValidation property to false.

Melee answered 10/12, 2009 at 17:17 Comment(0)
V
4

None of these answers quite did the job, but the last answer from this thread does. Basically, you need to:

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

I didn't really answer this, just pointing to the two guys who actually did.

Vedic answered 20/3, 2014 at 23:21 Comment(0)
S
3

Setting CausesValidation to false is the key, however this alone is not enough. If the buttons parent has CausesValidation set to true, the validating event will still get called. In one of my cases I had a cancel button on a panel on a form, so I had to set CausesValidation = false on the panel as well as the form. In the end I did this programatically as it was simpler than going through all the forms...

Control control = cancelButton;

while(control != null)
{
   control.CausesValidation = false;
   control = control.Parent;
}
Spile answered 13/4, 2010 at 15:58 Comment(0)
E
3

In my case, in the form I set the property AutoValidate to EnableAllowFocusChange

Electrostatic answered 2/2, 2017 at 10:47 Comment(0)
Y
3

By using Visual Studio wizard you can do it like that:

enter image description here

Yoheaveho answered 8/2, 2018 at 11:5 Comment(1)
This single setting worked just fine for me, setting CausesValidation on the cancel button to "false".Morentz
U
2

Judicious use of the Control.CausesValidation property will help you achieve what you want.

Unsociable answered 10/12, 2009 at 17:18 Comment(0)
P
2

Just above the validation code on the edit box add:

if (btnCancel.focused)
  {
     return;
  }

That should do it.

Palpitate answered 28/1, 2016 at 12:31 Comment(1)
It doesn't do it for me.Teepee
U
1

In complement of the answer of Daniel Schaffer: if the validation occurs when the edit box loses focus, you can forbid the button to activate to bypass local validation and exit anyway.

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

or if you use DevExpress:

this.simpleButtonCancel.AllowFocus = false;

Note that doing so will change the keyboard experience: the tab will focus anymore on the cancel button.

Unionize answered 24/1, 2013 at 3:55 Comment(0)
A
0

Maybe you want to use BackgroundWorker to give little bit delay, so you can decide whether validation should run or not. Here's the example of avoiding validation on form closing.

    // 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);
    }
Annelid answered 25/8, 2014 at 4:24 Comment(0)
C
0

This is an old question however I recently ran into this issue and solved it this way:

1st, we are loading a UserControl into a 'shell' Form that has a save and cancel button. The UserControl inherit an interface (like IEditView) that has functions for Save, Cancel, Validate and ToggleValidate.

In the shell form we used the mouse enter and mouse leave like so:

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

Then in ToggleValidate (Say a simple form with two controls...you can always just loop through a list if you want) we set the CausesValidation

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

        return txtDescription.CausesValidation;
    }

Hope this helps.

Cade answered 10/7, 2018 at 17:22 Comment(0)
S
0

I found this thread today while investigating why my form would not close when a validation error occurred.

I tried the CausesValidation = false on the close button and on the form itself (X to close).

Nothing was working with this complex form.

While reading through the comments I spotted one that appears to work perfectly

on the form close event , not the close button (so it will fire when X is clicked also)

This did the trick.

AutoValidate = AutoValidate.Disable;
Starflower answered 8/8, 2019 at 12:24 Comment(0)
V
0

Create a bool:

bool doOnce;

Set it to false in your function and then:

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

This means it will only run once and you should be able to cancel it. This worked for me anyways.

Vehicular answered 1/11, 2020 at 18:48 Comment(0)
T
0

I found that setting the CausesValidation property of the Cancel control did not solve the problem when I pressed the Cancel button in the middle of the edit of a Textbox.

I solved the problem by checking the Form's ActiveControl property at the start of the Testbox's Validating event procedure. If the ActiveControl was the Cancel button, I aborted the validation.

Unfortunately you have to do this in the Validating event procedures of many Controls in the Form.

Tasse answered 22/8 at 6:15 Comment(0)
A
-2

This work for me.

private void btnCancelar_MouseMove(object sender, MouseEventArgs e)
{
    foreach (Control item in Form.ActiveForm.Controls)
    {
        item.CausesValidation = false;
    }
}
Abbatial answered 26/5, 2015 at 3:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.