When you have an event handler for Validating event of a control, if the value of AutoValidate property of the form is set to anything different from Disabled, then Validating event will fire when you try to close the form. In Validating event, when facing with a validation error, you should set e.Cancel = true; to inform the containers and the control which there is a validation error.
In these cases, when there is a validation error, when you try to close the form, the validating even of the focused control will be raised and if there is a validation error, the form will not close!
Example
For example let’s suppose we have a textBox1 which should have value:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.AutoValidate = AutoValidate.EnableAllowFocusChange;
this.textBox1.Validating += textBox1_Validating;
}
private void textBox1_Validating(object sender, CancelEventArgs e)
{
if (string.IsNullOrEmpty(textBox1.Text))
{
e.Cancel = true;
MessageBox.Show("Enter Value");
}
}
Note 1: We set AutoValidate to EnableAllowFocusChange to let us to click close button of the form, otherwise we cannot click on the close button of the form.
Note 2: While showing a MessageBox is not good idea, but the example is just to show how we are going to stop raising the Validating event.
Solution
When you try to close the form, the form checks if AutoValidate property of the form is set to anything different from Disabled, then it first validates the current control which has the focus and if there’s a validation error for that control, then it cancels closing the form.
To prevent raising Validating event of the focused control, you can override WndProc and prevent raising Validating event of the focused control.
Also if the raising of the Validating event is not a problem for you and you just want to prevent interruption of closing, you can override OnClosing method of the form and Setting e.Cancel = false
Overriding WndProc
This solution will prevent raising of Validating event of the focused control when closing the form.
As I described above, the form will raise Validating event of the control when you try to close the form, just in case that the AutoValidate property of the form is a value different from Disable. So as a solution, you can override WndProc and check set AutoValidate to Disabled before handling WM_CLOSE message and reset it back to original after handling it. It will prevent raising Validating event during the closing of form. The reason thatr we reset it back to original value is because you may stop closing the form based on some other criteria and it’s expected to keep the original value:
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);
}
Overriding OnClosing
This solution will allow closing of the form when the focused control has a validation error while trying to close the form.
As I described above, when the form figures out there is a validation error for the focused control, it prevents closing the form by setting e.Cancel to true before calling OnClosing. So as an option you can override the method and set e.Cancel = false. This way, the form will continue closing.
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
}