Introduction
This Tip shows ways of allowing Users to cancel out of a form when Validation events would have them enter valid data before proceeding
.
Background
After testing an solution to a Quick Answers question on DataGridView cell validation, I couldn't close the form I had been working with...
The Scenario
I had put some code in a CellValidating
event, deliberately entered incorrect data and proven that the validation was working.
However, the Cell still had incorrect data in it when I attempted to close the Form. So the CellValidating
code was fired before the click event on the Close[X] and set the focus back to the offending control.
In other words, I was stuck on that control until I entered valid data. Forcing users to do something (like enter valid data) when all they want to do is get out of there, is going to annoy them pretty quickly so I tried to find a solution.
Ways Around the problem
Disable AutoValidate method
Most of my research pointed me in the direction of turning off AutoValidate
all together. This does work, but you must remember to validate all the controls when the User was finished data entry and had not tried to just cancel (Note you can do this by calling the ValidateChildren method of the Form).
WndProc method
The principle with this method is to disable AutoValidate
only when trying to close the form via Close[X]...
C# Example:
private const int WM_CLOSE = 0x0010;
...
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_CLOSE) AutoValidate = AutoValidate.Disable;
base.WndProc(ref m); }
VB.NET Example:
Private Const WM_CLOSE As Integer = &H10
...
Protected Overrides Sub WndProc(ByRef m As Message)
If m.Msg = WM_CLOSE Then
AutoValidate = AutoValidate.Disable
End If
MyBase.WndProc(m)
End Sub
Cancel button method
The solution above worked well until I added a "Cancel" button to the form. Again, the CellValidating
event is fired before the Button_Click
event so I was back to square-one.
After fiddling around trying to find an appropriate Message to capture, I realised that it was as easy as setting the CausesValidation
property on the Cancel button to false.
Form_Closing event method
After playing around with all the above I finally came across this article User Input Validation in Windows Forms. Tucked away at the bottom of the article were these wise words...
Quote:
However, in some cases, you might want to let the user close the form regardless of whether the values in the controls are valid. You can override validation and close a form that still contains invalid data by creating a handler for the form's Closing event. In the event, set the Cancel property to false. This forces the form to close
In other words it was a simple as
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = false;
}
or in VB.NET
Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
e.Cancel = False
End Sub
Note with this approach you will still need the CausesValidation
property set to false
if you use a Cancel button.
History
24 May 2014 - First Version