4
votes

I have created a dialog box in my WinForms application. This has many text boxes and ok/cancel buttons. When the user clicks ok, I only want the dialog box to close if all entries are valid. I can see how to do this with the "Validating" events for each control separately. That is fine. But these only seem to fire when a control loses focus. However, empty text boxes in my dialog are also invalid input which means the user may never have focused on that control. I would prefer to just validate all controls on clicking OK.

I can't work out how to do this though. Overriding the onclick of the OK button doesn't seem to have an option for stopping the window from closing. The Form IsClosing event does by setting Cancel = true. But this doesn't seem to be able to distinguish between whether the OK or Cancel button is clicked. Obviously if the cancel button is clicked I don't care about validation and want to allow the form to close regardless.

What is the best approach for doing this?]

Update: I already had CausesValidation set to true on both my form and ok button but my validation event does not get fired when I click the ok button. I mention this as it was suggested as a solution below.

3
Why can't you call your validation (I'd suggest looking at databinding and validating your bound object by the way) method on the onclick for the ok button and then not close the form of validation fails? Your form should not be magically closing when ok is clicked.David Hall

3 Answers

5
votes

Please select the form > Set the property CausesValidation to true

Select OK button and again set property CausesValidation to true

and then it will take care of all the validations.

Important points: 1) You must mention e.Cancel=true in all the validating eventhandlers

2) If your buttons are in panels then you must set panels (or any parent control's) CausesValidation property to true

Edit:

3) Validate fires just before loss of focus. While pressing Enter will cause the default button to Click, it doesn't move the focus to that button, hence no validation event will be fired if you have set forms AcceptButton Property to OK button

3
votes

First make sure to cancel the validation when any of the textboxes have validation errors. For example:

private void nameTextBox_Validating(object sender, CancelEventArgs e) {
    if (nameTextBox.Text.Length == 0)
    {
        e.Cancel = true;
        return;
    }
}

Now add the following code to the beginning of the ok button action:

if (!ValidateChildren())
    return;

This will trigger the validation event for all controls on the form,

1
votes

You can also use this simple code. just introducing a simple Boolean variable named hasError can do the job.

    public partial class Form1 : Form
    {
        private bool hasError;
        public Form1()
        {
            InitializeComponent();
        }

        private void OkBtn_Click(object sender, EventArgs e)
        {
            errorProvider1.Clear(); hasError=false;
            if (ValidateTxt.Text.Length == 0)
            {
                errorProvider1.SetError(ValidateTxt, "must have a value");
                hasError=true;
            }
            if (!hasError)
            {
                //Do what you want to do and close your application
                Close();
            }

        }

        private void CancelBtn_Click(object sender, EventArgs e)
        {
            Close();
        }
    }