Problem:
This works fine when a user leaves the field except when they click on a button that causes a FormClose event to fire, such as invoke self::Close or clicking on the Windows Close "X" box.
The problem is that the Validating event occurs before the FormClosing event so the validation code will be executed when it really should be bypassed so that error messages are not displayed etc.
How can this be programmed so that the validation code is bypassed if the form is closed?
Resolution:
If WmClose is found then the logic will be bypassed and the validation will suceed so that the form will close.
Here is the sample code:
*----------------------------------------------------------------------------
* Test Validate
*
* This example program demonstrates how to circumvent the problem that occurs
* when a Windows Form is closed and implicit validation of controls is being
* used on the Form. The problem is that the Validating event for the controls
* actually occurs before the FormClosed event so the Validating logic is in
* effect even when the Form is closed.
*
* This example shows you how this can be bypassed by adding a method call in
* the Validating event handler which will check the stack for the WmClose
* method and if it exists the validation code will be bypassed and the form
* will be closed without displaying error message box.
*
* Run this application and type an invalid entry into the textbox (not Yes or
* No) and then click the Close button or the Close "X" on the window.
* The Validation logic will be bypassed and the form will close.
*----------------------------------------------------------------------------
inherits type System.Windows.Forms.Form.
working-storage section.
method-id NEW.
procedure division.
invoke self::InitializeComponent
invoke textBox1::Focus
goback.
end method.
method-id IsFormClosing public.
local-storage section.
78 WMCLOSE value "WmClose".
01 stackTrace type System.Diagnostics.StackTrace.
01 stframes type System.Diagnostics.StackFrame occurs any.
01 MethodName type System.Reflection.MethodBase.
procedure division returning FormIsClosing as condition-value.
set FormIsClosing to false
set stackTrace to new System.Diagnostics.StackTrace
set stframes to stackTrace::GetFrames
perform varying sf as type System.Diagnostics.StackFrame thru stframes
set MethodName to sf::GetMethod
if MethodName::Name = WMCLOSE
set FormIsClosing to true
exit perform
end-if
end-perform
goback.
end method.
method-id textBox1_Validating final private.
procedure division using by value sender as object e as type System.ComponentModel.CancelEventArgs.
if self::IsFormClosing = false
if textBox1::Text = "Yes" or "No"
continue
else
invoke type MessageBox::Show("Must be Yes or No")
set e::Cancel to true
end-if
end-if.
end method.
method-id buttonCancel_Click final private.
procedure division using by value sender as object e as type System.EventArgs.
invoke self::Close
end method.
end class.