c# - ventana - Cómo omitir la validación después de hacer clic en el botón Cancelar de un formulario
formclosing c# (15)
Yo uso C #. Tengo un formulario de Windows 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?
Aquí hay un detalle importante: si la validación falla, entonces
e.Cancel = true;
impide dejar el 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?
El uso juicioso de la propiedad Control.CausesValidation
lo ayudará a lograr lo que desea.
En complemento de la respuesta de Daniel Schaffer: si la validación ocurre cuando el cuadro de edición pierde el foco, puede prohibir que el botón se active para eludir la validación local y salir de todos modos.
public class UnselectableButton : Button
{
public UnselectableButton()
{
this.SetStyle(ControlStyles.Selectable, false);
}
}
o si usa DevExpress:
this.simpleButtonCancel.AllowFocus = false;
Tenga en cuenta que al hacerlo cambiará la experiencia del teclado: la pestaña se enfocará más en el botón cancelar.
En mi caso, en la forma en que establecí la propiedad AutoValidar a EnableAllowFocusChange
Esta es una vieja pregunta, sin embargo, recientemente me encontré con este problema y lo resolvió de esta manera:
En primer lugar, estamos cargando un UserControl en un formulario ''shell'' que tiene un botón de guardar y cancelar. El UserControl hereda una interfaz (como IEditView ) que tiene funciones para Guardar , Cancelar , Validar y ToggleValidar .
En la forma del shell utilizamos el mouse enter y mouse leave así:
private void utbCancel_MouseEnter(object sender, EventArgs e)
{
((Interface.IEdit)tlpMain.Controls[1]).ToggleValidate();
}
private void utbCancel_MouseLeave(object sender, EventArgs e)
{
((Interface.IEdit)tlpMain.Controls[1]).ToggleValidate();
}
Luego, en ToggleValidate (Digamos un formulario simple con dos controles ... siempre puedes recorrer una lista si quieres) configuramos CausesValidation
public bool ToggleValidate()
{
uneCalcValue.CausesValidation = !uneCalcValue.CausesValidation;
txtDescription.CausesValidation = !txtDescription.CausesValidation;
return txtDescription.CausesValidation;
}
Espero que esto ayude.
Estaba teniendo problemas para cerrar mi formulario, ya que la validación de ciertos controles lo detenía. 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 en medio de la edición de 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 se cerraría.
Esto se solucionó con lo siguiente en el evento de clic del botón Cancelar:
private void btnCancel_Click(object sender, EventArgs e)
{
// Stop the validation of any controls so the form can close.
AutoValidate = AutoValidate.Disable;
Close();
}
Establecer CausesValidation 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 programáticamente ya que era más simple que pasar por todas las formas ...
Control control = cancelButton;
while(control != null)
{
control.CausesValidation = false;
control = control.Parent;
}
Establezca la propiedad CausesValidation
del botón Cancelar en false
.
Establezca la propiedad CausesValidation
en false
.
Este trabajo para mí.
private void btnCancelar_MouseMove(object sender, MouseEventArgs e)
{
foreach (Control item in Form.ActiveForm.Controls)
{
item.CausesValidation = false;
}
}
Justo encima del código de validación en el cuadro de edición, agregue:
if (btnCancel.focused)
{
return;
}
Deberias hacer eso.
Ninguna de estas respuestas hizo el trabajo, pero la última respuesta de este hilo sí. Básicamente, necesitas:
- Asegúrese de que el botón Cancelar (si existe) tiene .CausesValidation establecido en falso
Reemplace 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 respondí esto, solo señalé a los dos tipos que realmente lo hicieron.
Obviamente, la propiedad CausesValidation
del botón debe establecerse en falso y, a continuación, el evento de validación nunca ocurrirá al hacer 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.
Quizás desee utilizar BackgroundWorker para demorarlo un poco, 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);
}
Si la validación se produce cuando el cuadro de edición pierde el foco, nada sobre el botón cancelar impedirá que eso suceda.
Sin embargo, si la validación fallida impide que el botón cancelar haga lo suyo, establezca la propiedad CausesValidation
del botón en false
.