Why can not I close the window when I validate TextBox with ErrorProvider in C #?

11

I'm doing validations in C # with ErrorProvider.

Validations are about TextBox .

 //Llama al método valida para decidir si el TextBox está vacío.
 private void textBox1_Validating(object sender, CancelEventArgs e)
 {
     valida(sender, e, textBox1, errorProvider1);
 }

 //Método que recibe un textbox y un Error provider para validar si el textBox esta vacio.
 private void valida(object sender, CancelEventArgs e, TextBox tb, ErrorProvider error)
  {
      if (string.IsNullOrEmpty(tb.Text))
      {
          e.Cancel = true;
          error.SetError(tb, "Campos Vacios");
      }
  }

 //valida cuando el TextBox pierde el foco y quita el ErrorProvider si no está vacío
 private void textBox1_Validated(object sender, EventArgs e)
 {
      errorProvider1.SetError(textBox1, "");
 }

 //Cerrar ventana
 private void btnCerrar(object sender, EventArgs e)
 {
     this.Close();
 }

The problem I have when the ErrorProvider is activated so to speak. If the TextBox that I'm validating this empty shows the ErrorProvider , and the cursor stays in that TextBox empty waiting to be validated again.

But:

  

Why can not I close the window when ErrorProvider is active?

     

Why can not I give Tab or change the cursor while ErrorProvider is active?

It's a desktop application made in C #.

When the form has that error sign, I can not change the cursor, let alone close the window.

EDIT:

If I remove the e.cancel = true; it does not show me the ErrorProvider

EDIT2 In the event Form1_FormClosing of the form I did what @JLPrieto e.cancel = false; said, which works only when the X of the form is pressed and the form closes. But if I do it from the button1 this.close() it does not close the window when I press the button.

    
asked by Luis Fernando 21.02.2018 в 15:31
source

1 answer

5

Well, the problem here is that the property Cancel of CancelEventArgs when set to true , will always block any event that occurs after the Validating event.

In this case, the conflicting events are Form.FormClosing , Button.Click and KeyPress that prevents you from seselccione the next control with Tab , since I was testing with your code and effectively, the event Click of your cancel button is never executed (I tried with a MessageBox), nor the event% co_of%.

The solution?

Use the Control.CausesValidation property , is a Boolean that obtains or sets a value that indicates whether the control causes validation of all controls that require validation when they receive the focus.

Then in your case it would be like this:

textBox1.CausesValidation = false;

And if the property FormClosing is set to CausesValidation , the events false and Validating are deleted.

    protected override void OnShown(EventArgs e)
    {
        base.OnShown(e);

        //Llamo a esta propiedad aquí porque este evento se ejecuta antes de Validating
        textBox1.CausesValidation = false;
    }

    private void textBox1_Validating(object sender, CancelEventArgs e)
    {
        Valida(sender, e, errorProvider1);
    }

    private void textBox1_Validated(object sender, EventArgs e)
    {
        //Borra todos los valores de configuración asociados con ErrorProvider
        errorProvider1.Clear();
    }

    private void Valida(object sender, CancelEventArgs e, ErrorProvider error)
    {
        // El objeto sender, hace referencia al control que llama al evento;
        // en resumen, puedes convertir implicitamente el objeto sender en Control (TextBox en este caso)
        var tb = ((TextBox)sender);

        if (string.IsNullOrEmpty(tb.Text))
        {
            error.SetError(tb, "Campos Vacios");
            e.Cancel = true;
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.Close();
    }

Well, I have developed a block of code that can be useful to you, remove the events Validated and Validating and put this in your Validated :

private void Form1_Load(object sender, EventArgs ev)
{
    //Se produce cuando el control pierde el foco
    textBox1.LostFocus += (s, e) =>
    {
         if (string.IsNullOrEmpty(textBox1.Text)) errorProvider1.SetError(textBox1, "Campos vacios");
         else errorProvider1.Clear();
    };

    //Se produce cuando el control recibe el foco
    textBox1.GotFocus += (s, e) =>
    {

    };
}

Yes, the events Form_Load and GotFocus are deprecated (discontinued), but there are still cases in which they can be used; if what you want is something modern, then you need the events LostFocus and Enter

private void Form1_Load(object sender, EventArgs ev)
{
     //Se produce cuando el control pierde el foco
     textBox1.Leave += (s, e) =>
     {
          if (string.IsNullOrEmpty(textBox1.Text)) errorProvider1.SetError(textBox1, "Campos vacios");
          else errorProvider1.Clear();
     };

     //Se produce cuando el control recibe el foco
     textBox1.Enter += (s, e) =>
     {

     };
 }
    
answered by 20.04.2018 / 07:18
source