J'utilise C # . J'ai un Windows Form avec une zone d'édition et un bouton Annuler. La boîte d'édition a un code dans l'événement de validation. Le code est exécuté chaque fois que la zone d'édition perd le focus. Lorsque je clique sur le bouton Annuler, je souhaite simplement fermer le formulaire. Je ne veux aucune validation pour que la boîte d'édition soit exécutée. Comment cela peut-il être accompli?
Voici un détail important: si la validation échoue, alors
e.Cancel = true;
empêche de quitter le contrôle.
Mais lorsqu'un utilisateur clique sur le bouton Annuler, le formulaire doit être fermé quoi qu'il arrive. comment cela peut-il être mis en œuvre?
Si la validation se produit lorsque la zone d'édition perd le focus, rien sur le bouton d'annulation ne va empêcher cela de se produire.
Toutefois, si la validation qui échoue empêche le bouton d'annulation de fonctionner, définissez la propriété CausesValidation
du bouton sur false
.
De toute évidence, la propriété CausesValidation
du bouton doit être définie sur false et l'événement de validation ne se produira jamais par un clic. Mais cela peut échouer si le contrôle parent du bouton a sa propriété CausesValidation
définie sur true. La plupart du temps, les développeurs oublient ou oublient de modifier la propriété CausesValidation
du contrôle conteneur (comme le contrôle du panneau). Définissez-le également sur False. Et cela devrait faire l'affaire.
J'avais de la difficulté à fermer mon formulaire, car la validation de certains contrôles l’arrêtait. J'avais défini le control.CausesValidation = false
pour le bouton d'annulation et tous les parents du bouton d'annulation. Mais avait toujours des problèmes.
Il semblait que si l'utilisateur était en train de modifier un champ utilisant la validation et décidait d'abandonner (laissant le champ avec une entrée non valide), l'événement du bouton d'annulation était en cours de déclenchement, mais la fenêtre ne se fermait pas.
Ce problème a été résolu de la manière suivante dans l'événement de clic du bouton d'annulation:
private void btnCancel_Click(object sender, EventArgs e)
{
// Stop the validation of any controls so the form can close.
AutoValidate = AutoValidate.Disable;
Close();
}
Définissez la propriété CausesValidation
du bouton Annuler sur false
.
Aucune de ces réponses n'a vraiment fait le travail, mais la dernière réponse de ce fil fait. Fondamentalement, vous devez:
Remplacez cette méthode virtuelle.
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);
}
Je n'ai pas vraiment répondu à cela, je me suis contenté de mentionner les deux types qui l'ont fait.
Définissez la propriété CausesValidation
sur false
.
Définir CausesValidation sur false est la clé, mais cela ne suffit pas. Si CausesValidation est défini sur true sur le parent des boutons, l'événement de validation sera toujours appelé. Dans l'un de mes cas, j'avais un bouton d'annulation sur un panneau d'un formulaire; je devais donc définir CausesValidation = false sur le panneau ainsi que sur le formulaire. En fin de compte, je l'ai fait par programme, car c'était plus simple que de passer par toutes les formes ...
Control control = cancelButton;
while(control != null)
{
control.CausesValidation = false;
control = control.Parent;
}
Une utilisation judicieuse de la propriété Control.CausesValidation
vous aidera à atteindre vos objectifs.
Dans mon cas, sous la forme, je définis la propriété AutoValidate to EnableAllowFocusChange
Juste au-dessus du code de validation dans la zone d'édition, ajoutez:
if (btnCancel.focused)
{
return;
}
Ça devrait le faire.
En complément de la réponse de Daniel Schaffer: si la validation a lieu lorsque la boîte de saisie perd le focus, vous pouvez interdire au bouton d'activer de contourner la validation locale et de quitter quand même.
public class UnselectableButton : Button
{
public UnselectableButton()
{
this.SetStyle(ControlStyles.Selectable, false);
}
}
ou si vous utilisez DevExpress:
this.simpleButtonCancel.AllowFocus = false;
Notez que cela changera l'expérience du clavier: l'onglet sera plus centré sur le bouton d'annulation.
Peut-être souhaitez-vous utiliser BackgroundWorker pour donner un peu de retard afin de décider si la validation doit être exécutée ou non. Voici l'exemple d'éviter la validation lors de la fermeture du formulaire.
// 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);
}
C'est une vieille question, mais j'ai récemment rencontré ce problème et l'ai résolu de cette façon:
Premièrement, nous chargeons un UserControl dans un 'Shell' Form qui a un bouton de sauvegarde et d’annulation. Le UserControl hérite d'une interface (comme IEditView ) dotée de fonctions pour Enregistrer , Annuler , Valider et ToggleValidate .
Dans la forme Shell, nous avons utilisé la souris entrer et laisser la souris comme suit:
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();
}
Puis dans ToggleValidate (Dites un formulaire simple avec deux contrôles ... vous pouvez toujours parcourir une liste si vous le souhaitez), nous définissons le paramètre CausesValidation.
public bool ToggleValidate()
{
uneCalcValue.CausesValidation = !uneCalcValue.CausesValidation;
txtDescription.CausesValidation = !txtDescription.CausesValidation;
return txtDescription.CausesValidation;
}
J'espère que cela t'aides.