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