2009-12-10 19 views
36

Uso C#. Tengo un Windows Form con un cuadro de edición y un botón Cancelar. El cuadro de edición tiene código en el evento de validación. El código se ejecuta cada vez que el cuadro de edición pierde el foco. Cuando hago clic en el botón Cancelar solo quiero cerrar el formulario. No quiero ninguna validación para que se ejecute el cuadro de edición. ¿Cómo se puede lograr esto?Cómo saltear Validar después de hacer clic en el botón Cancelar de un formulario

Aquí es un detalle importante: si la validación falla, entonces

  e.Cancel = true; 

impide salir de control.

Pero cuando un usuario hace clic en el botón Cancelar, el formulario debe cerrarse sin importar qué. ¿Cómo se puede implementar esto?

+1

Nada que hacer para el botón Cancelar evitará que se ejecute el código de validación cuando su cuadro de texto pierda el foco. – Stewbob

Respuesta

15

Establezca la propiedad CausesValidation del botón Cancelar en false.

2

Establezca la propiedad CausesValidation en false.

1

El uso legítimo de la propiedad Control.CausesValidation lo ayudará a lograr lo que desea.

39

Si la validación se produce cuando el cuadro de edición pierde el foco, nada sobre el botón cancelar evitará que esto suceda.

Sin embargo, si la validación fallida impide que el botón cancelar lo haga, configure la propiedad CausesValidation del botón en false.

Reference: Button.CausesValidation property

+0

No estoy seguro de por qué alguien votó negativamente esto. Para una aplicación winforms, es cierto. Las otras tres respuestas son incorrectas. – Stewbob

+0

No fui yo: D –

+1

@DanielSchaffer: no estoy seguro de si entiendo correctamente la parte "de todos modos". ¿Cómo puedo evitar que la validación tenga lugar cuando el usuario pulsa el botón Cancelar? La validación desencadena un cuadro de mensaje que siempre se muestra incluso si el usuario desea cancelar la edición/adición de un objeto porque la validación ocurre antes de hacer clic con el botón. Incluso he intentado establecer 'CausesValidation = false' de' MouseEnter' del 'BtnCancel' (tampoco funcionó). –

27

Obviamente CausesValidation propiedad del botón tiene que ser establecido en false y luego validar el evento nunca va a pasar en su clic. Pero esto puede fallar si el control principal del botón tiene su propiedad CausesValidation establecida en verdadero. La mayoría de las veces, los desarrolladores omiten/olvidan cambiar la propiedad CausesValidation del control del contenedor (como el control del panel). Ponlo también en False. Y eso debería hacer el truco.

+4

Microsoft debe establecer el valor predeterminado 'CausesValidation' en' False' para los contenedores, ya que de todos modos no toman el foco. –

+0

Si tengo contenedores anidados, ¿tengo que configurarlo como 'False' para todos los contenedores, o simplemente como el elemento primario inmediato de mi botón? – dotNET

+0

Aquí de nuevo después de unos meses :). Y lo descubrí más tarde. No necesita configurarlo para todos los contenedores principales. Solo establecer el padre inmediato es suficiente. – dotNET

2

Configuración Causas La validación en falso es la clave, sin embargo, esto por sí solo no es suficiente. Si los botones padre tienen CausesValidation establecido en verdadero, el evento de validación todavía se llamará. En uno de mis casos, tenía un botón cancelar en un panel en un formulario, así que tuve que establecer CausesValidation = false en el panel, así como el formulario. Al final hice esto mediante programación, ya que era más simple que pasar por todas las formas ...

Control control = cancelButton; 

while(control != null) 
{ 
    control.CausesValidation = false; 
    control = control.Parent; 
} 
19

que estaba teniendo problemas para conseguir mi forma de cerrar, ya que la validación de ciertos controles era detenerlo. Establecí el control.CausesValidation = false para el botón Cancelar y todos los padres del botón Cancelar. Pero aún estaba teniendo problemas.

Parecía que si el usuario estaba editando un campo que estaba usando la validación y simplemente decidió abandonar (dejando el campo con una entrada no válida), el evento cancelar botón se estaba disparando pero la ventana no lo haría cerrar.

Esto fue corregido por el siguiente en el evento cancelar botón de clic:

private void btnCancel_Click(object sender, EventArgs e) 
{ 
    // Stop the validation of any controls so the form can close. 
    AutoValidate = AutoValidate.Disable; 
    Close(); 
} 
+2

+1 por simplicidad. – Randy

0

Como complemento de la respuesta de Daniel Schaffer: Si se produce la validación cuando el cuadro de edición pierde el foco, puede forbid the button to activate para eludir locales validación y salida de todos modos.

public class UnselectableButton : Button 
{ 
    public UnselectableButton() 
    { 
     this.SetStyle(ControlStyles.Selectable, false); 
    } 
} 

o si utiliza DevExpress:

this.simpleButtonCancel.AllowFocus = false; 

Tenga en cuenta que al hacerlo, cambiar la experiencia del teclado: la pestaña se centrará más en el botón cancelar.

3

Ninguna de estas respuestas funcionó, pero la última respuesta de this thread sí lo hace. Básicamente, es necesario:

  1. asegurar que el botón Cancelar (si lo hay) tiene .CausesValidation establecido en false
  2. reemplazar este método virtual.

    protected override bool ProcessDialogKey(Keys keyData) { 
        if (keyData == Keys.Escape) { 
         this.AutoValidate = AutoValidate.Disable; 
         CancelButton.PerformClick(); 
         this.AutoValidate = AutoValidate.Inherit; 
         return true; 
        } 
        return base.ProcessDialogKey(keyData); 
    } 
    

realmente no responder a esto, simplemente señalando a los dos tipos que realmente hizo.

0

Quizás desee utilizar BackgroundWorker para dar un poco de retraso, para que pueda decidir si la validación debe ejecutarse o no. Aquí está el ejemplo de evitar la validación en el cierre del formulario.

// The flag 
    private bool _isClosing = false; 

    // Action that avoids validation 
    protected override void OnClosing(CancelEventArgs e) { 
     _isClosing = true; 
     base.OnClosing(e); 
    } 

    // Validated event handler 
    private void txtControlToValidate_Validated(object sender, EventArgs e) {   
     _isClosing = false; 
     var worker = new BackgroundWorker(); 
     worker.DoWork += worker_DoWork; 
     worker.RunWorkerAsync(); 
     worker.RunWorkerCompleted += worker_RunWorkerCompleted; 
    } 

    // Do validation on complete so you'll remain on same thread 
    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { 
     if (!_isClosing) 
      DoValidationHere(); 
    } 

    // Give a delay, I'm not sure this is necessary cause I tried to remove the Thread.Sleep and it was still working fine. 
    void worker_DoWork(object sender, DoWorkEventArgs e) { 
     Thread.Sleep(100); 
    } 
-1

Esto funciona para mí.

private void btnCancelar_MouseMove(object sender, MouseEventArgs e) 
{ 
    foreach (Control item in Form.ActiveForm.Controls) 
    { 
     item.CausesValidation = false; 
    } 
} 
+3

¿Por qué y cómo funciona esto para usted? – Unheilig

0

Justo por encima del código de validación en el cuadro de edición complemento:

if (btnCancel.focused) 
    { 
    return; 
    } 

Eso debería hacerlo.

+0

No lo hace por mí. –

0

En mi caso, en la forma que establezca la propiedad AutoValidate a EnableAllowFocusChange

0

Mediante el uso de Visual Studio Wizzard puede hacerlo así:

enter image description here

Cuestiones relacionadas