This is a two part question I guess.

I have a form that allows a user to edit an existing record stored in a SQL database. One of the items the users can edit must have a value when the record is edited using this particular form, but it does accept null values on the server side so validation won't work there. So for this particular form a value must be validated because the SQL server will not throw an exception if it is blank since, in some instances it can be. The value is being evaluated by a custom validation event that I have written (it's nothing fancy, just 3 lines) but I have a problem...

The form contains 3 buttons:

  • Revert - Reverts the record back to the state it was when it was opened in the editor.
  • Cancel - Cancels changes and closes the editor.
  • Save - Saves the data to the server and closes the form.

The main problem I have is that my validation code uses e.Cancel = true; if validation fails which, if I understand correctly, indicates that validation failed and the events following should be canceled, including closing the form, reverting data back to it's original state or even changing to a different control.

That's great and fine, but because of that, the revert and cancel buttons don't work unless the user fixes the validation problem first, which kind of defeats the purpose of a cancel button or revert button.

Here's the question:

On the form, I have defined the AcceptButton and CancelButton properties to the corresponding "Save" and "Cancel" buttons on my form. When validating my controls, is there a way to find out if the cancel button was clicked and to "skip" validation without iterating through all of the controls and turning validation off?

More of a "if the form is closing because the user clicked this button, then just return as validated so the form can close" type of logic. Or maybe just validate the textbox under certain circumstances, like when a particular button is clicked.

I've started to dabble in ASPX deveopment to supplement my form application, and I've noticed with validation controls you can assign validation "Groups" so that if a form contains multiple buttons, if one control would fail validation when a button is clicked, you can include another button that only validates controls in a particular list...does that exist in WinForms?

A supplemental question as well...when defining a CancelButton property on a form, no code is required to actually close the form in the button's click event handler, is it permissible to just leave it that way or should I still have an event handler that is either blank, or one that still calls this.Close(); ?

Nevermind! I figured it out.

According to the MSDN documentation, controls follow this event pattern when focus is changed, thereby causing validation:

When you change the focus by using the keyboard (TAB, SHIFT+TAB, and so on), by calling the Select or SelectNextControl methods, or by setting the ContainerControl.ActiveControl property to the current form, focus events occur in the following order:

  1. Enter
  2. GotFocus
  3. Leave
  4. Validating
  5. Validated
  6. LostFocus

When you change the focus by using the mouse or by calling the Focus method, focus events occur in the following order:

  1. Enter
  2. GotFocus
  3. LostFocus
  4. Leave
  5. Validating
  6. Validated

If the CausesValidation property is set to false, the Validating and Validated events are suppressed.

If the Cancel property of the CancelEventArgs is set to true in the Validating event delegate, all events that would usually occur after the Validating event are suppressed.

Which means that regardless of how focus is transferred, the new control receives focus before the old one is validated, this allows me to use

if (this.ActiveControl == buttonCancel || this.ActiveControl == buttonReset)
            {
                return;
            }
            // Validation events

which will validate the control in any case that the cancel or reset button are not clicked. The only problem occurs when the user hits the "Esc" key, the normal behaviour when the CancelButton property of the form is set would be to close the window, but I'm guessing, since the "Esc" key does nothing with this setup, the button must not receive focus, something else must be happening.

I suppose I could capture the "Esc" key press in the validation event as well, but I'm not sure if it's really necessary...

So far, it works like a charm!

Any thoughts or gotchas anyone have?

Sources:

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.