Question

I'm fairly new to using validation. I have a C# winform project that I want to validate a form before closing. However, I only want this validation to occur when I click a button. So I have an event that fires for that like so:

if (!this.ValidateChildren())
{
   MessageBox.Show("Validation failed");
}
else
{
   MessageBox.Show("Validation passed with flying colours. :)");
   this.Close();
}

I only want to close the form if the validation is successful. Easy enough. However, I don't want to have the validation run when the textboxes lose focus, only when the whole form is being validated.

Each control that I want to be validated, I have registered with the "validating" event. They use "e.Cancel = true;" to cancel the validation. I have been using the ErrorProvider class to support this visually.

So basic question is, what is the best approach to validate a specific set of controls only when I want to and not when focus is lost from the control?

EDIT: presently as a work around, I have a method that toggles the "CausesValidation" property on and off. I default everything to not CauseValidation, enables them all before I use the event for validating the whole form, and disables them all after again.

I really don't see this as an ideal approach. Are there any more 'elegant' solutions out there?

Était-ce utile?

La solution

Autres conseils

I think what you are looking for is the behavior you obtain when you set

form.Autovalidate = Disable

or

form.Autovalidate = EnableAllowFocusChange

I've used something along the following lines:

1) Define the controls you want validated in a collection of some sort.

2) Write a validation routine, maybe directly under the button click, that loops through the control collection, checking the value/validity of the control's content. Maybe defer to a private method per control if the validation is complex.

3) If the control's content is not valid, pass it to the ErrorProvider's SetError method along with your validation message.

4) Depending on the valid state, let the form close (DialogResult = OK) or keep the form open (DialogResult = None).

If you do this lots, you can refactor the validation into a base form with an ErrorProvider and inherit from it.

    private void TxtNama_Validating(object sender, CancelEventArgs e)
    {
        e.Cancel = string.IsNullOrEmpty(TxtNama.Text);
        this.errorProvider1.SetError(TxtNama, "Nama Barang Harus Diisi..!!");            
    }

    private void CmdSave_Click(object sender, EventArgs e)
    {
        if(this.ValidateChildren(ValidationConstraints.Enabled))
        {
            MessageBox.Show("Simpan Data Barang..?" , "SIMPAN DATA", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
        }
    }

The above examples work pretty well, but combining the errorProvider object with the button was interesting. It took a little bit to get the object.ValidateChildren() method to return false when validation failed.

The key seems to be setting the CancelEventargs.Cancel property to true; obvious in retrospect, but maybe this will save someone else time.

    Form1.Autovalide = Disabled

    private void textBox2_Validating(object sender, CancelEventArgs e)
    {
       if (textBox2.Text.Length == 0)
       {
          errorProvider1.SetError(textBox2, "Must provide an entry.");
          e.Cancel = true;
       } else {
          errorProvider1.SetError(textbox2, "");
       }
    }

    private void button1_click(object sender, EventArgs e)
    {
       if (this.ValidateChildren(ValidationConstraints.Enabled | ValidationConstraints.ImmediateChildren))
       {
          MessageBox.Show("All's well.", "Valid", MessageBoxButtons.OK);
       }  else {
          MessageBox.Show("All is ruin and woe!", "Invalid", MessageBoxButtons.OK);
       }
}

So I know I'm a bit late to this. But this issue bit me as well

What I ended up doing was using the cancel buttons MouseEnter and MouseLeave events

private void btnCancel_MouseEnter(object sender, EventArgs e)
        {
            AutoValidate = AutoValidate.Disable;
        }

private void btnCancel_MouseLeave(object sender, EventArgs e)
        {
            AutoValidate = AutoValidate.EnablePreventFocusChange;
        }

This would disable the validation when I enter the button to click, then when clicked the cancel buttons click event can be fired and I can do whatever logic that is needed in there, including clearing the errors.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top