WinForms-Validating-Ereignis wird verhindert, dass der Escape-Taste schließen der form
Ich habe ein einfaches Formular mit einem einzelnen Textfeld, plus Schaltflächen OK und Abbrechen. Die Form ist AcceptButton und CancelButton korrekt eingestellt sind, und die Schaltflächen OK und Abbrechen haben Ihre DialogResult gesetzt auf 'OK' und 'Abbrechen'.
Möchte ich hinzufügen, dass die überprüfung der TextBox, die verhindern, dass Nutzer von OK-ing-form, wenn die Validierung fehlschlägt, aber das wird auch Ihnen erlauben, zu kündigen, als üblich.
Die CausesValidation-Eigenschaft True ist standardmäßig auf allen Reglern, aber ich habe dies geändert auf False, auf die Schaltfläche Abbrechen.
Sicher genug, klicken auf OK oder drücken die Enter-Taste führen Sie das Validating-Ereignis ich verdrahtet, um das Textfeld. Drücken Sie die Abbrechen-Taste umgeht die Validierung, das ist perfekt.
Jedoch das drücken von Escape zum Abbrechen des Formulars wird nicht führen Sie die gleiche wie das drücken der Schaltfläche Abbrechen - es stellt sich die Validating-Ereignis und verhindert, dass der Benutzer Sie verlässt.
Gibt es eine Möglichkeit, dass die Escape-Taste durchführen soll, d.h. nicht zu erhöhen das Validating-Ereignis aus, als ob der Abbrechen button gedrückt wurde?
Eine komplette Lösung gearbeitet wird:
Erstellen Sie eine neue Windows Forms-Anwendung. Fügen Sie ein zweites Formular auf das Projekt.
Fügen Sie diesen code in Form1-Konstruktor nach InitializeComponent():
MessageBox.Show((new Form2()).ShowDialog().ToString());
Dies zeigt die DialogResult zurück von unserer zweiten form.
Fügen Sie diesen code in Form2 Konstruktor nach InitializeComponent():
TextBox txtName = new TextBox();
txtName.Validating +=
new CancelEventHandler((sender, e) =>
{
if (txtName.Text.Length == 3)
{
MessageBox.Show("Validation failed.");
e.Cancel = true;
}
});
Button btnOk = new Button
{
Text = "OK",
DialogResult = DialogResult.OK
};
Button btnCancel = new Button
{
Text = "Cancel",
CausesValidation = false,
DialogResult = DialogResult.Cancel
};
FlowLayoutPanel panel = new FlowLayoutPanel();
panel.Controls.AddRange(new Control[]
{
txtName, btnOk, btnCancel
});
this.AcceptButton = btnOk;
this.CancelButton = btnCancel;
this.Controls.Add(panel);
In diesem vereinfachten Beispiel das Textfeld wird nicht lassen Sie gehen, wenn 3 Zeichen Eingabe. Sie können drücken Sie die Schaltfläche "Abbrechen" oder schließen Sie das Formular direkt, auch wenn es 3 Zeichen vorhanden; jedoch drücken der ESC-Taste wird nicht das gleiche tun - es feuert das Validating-Ereignis in der Erwägung, dass es sollte die gleiche wie das drücken einer Taste Abbrechen.
- "WinForms-Validierung verhindert escape-Taste schließen Sie das Formular" ich habe das gleiche problem.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ja, dies ist eine unangenehme Eigenart des ValidateChildren Methode. Er weiß nicht, dass der Abbruch beabsichtigt war. Fügen Sie diesen code um das problem zu beheben:
Um zu vermeiden, dass eine Validate-Ereignisprozedur ausgeführt, die bewirkt, dass Nebenwirkungen, wie eine message-box, fügen Sie die folgende Anweisung am Anfang der Methode:
Fügen Sie diesen code in dein Formular aus, um die DialogResult gesetzt, bevor es zu validieren versucht, die form:
ProcessDialogKey
Methode; es gibt keine Notwendigkeit zu ändern, alle anderen Feld-Validating-Ereignis-Handler.OnFormClosing
überschreiben, aber die anderen beiden snippets erforderlich waren.Sah ich gerade dieses problem, wie ich war Jagd eine Lösung für die gleichen, und das überschreiben von ProcessdialogKey ist die MS-zugelassene-Lösung, bis Sie den Fehler beheben (Flucht sollte das gleiche tun wie das klicken auf Abbrechen). Eine Diskussion zu diesem bug findet sich auch hier (gerade auch die Arbeit mit Visual Basic statt C#. Fehler ist über 5 Jahre alt und offenbar immer noch nicht behoben): Bug oder Feature? Abbrechentaste vs ESC-Taste ich bin versuchen zu arbeiten, die C++ - Lösung.
Bearbeiten, um hinzuzufügen:
Die Lösung aus dem link in C#:
Eigentlich, dass verursacht neue Probleme, denn es fängt die Flucht, die andere Steuerelemente verwenden sollten, wenn Sie z.B. eine combobox gelöscht, drücken von escape schließen sollte die combobox nicht verlassen Sie den dialog, mit dem obigen code zu tun.
Wäre es möglich, ausgenommen bestimmte Arten der Kontrolle über die escape-Taste Ereignis, aber das ist keine gute Lösung, es ist nur eine Frage der Zeit, bis ein anderes Steuerelement, das verwendet entkommen intern wird eingeführt in der form, z.B. eine Ausbreitung Steuern, wo der edit-Modus zu verlassen auf der Flucht.
IMO ist es ziemlich Debil, dass Sie ausgeführt wird überprüfen auf der Flucht. Weiß jemand, was die Idee dahinter ist, denn es ist kein bug... aber es IST ein bug.
Wenn in diesem code rufen base.ProcessDialogKey(keyData) statt abbrechentaste.PerformClick dann wären Sie näher an einer Lösung, da es sein würde, um jemand anderes zu bestimmen, was zu tun ist mit der escape-Taste. Aber die Einstellung AutoValidate, um hier Deaktiviert und dann wieder auf den ursprünglichen Wert nicht verhindern, dass die Validierung, da es wahrscheinlich zu einfach das senden von Ereignissen und Orten, eine Nachricht auf der queue, nicht verwenden Sie diesen Wert, bis, nachdem es gesetzt wurde, wieder auf den ursprünglichen Wert.
Nur durch die Einstellung Deaktiviert ist und sich nicht wieder auf den ursprünglichen Wert, wird es funktionieren, aber wenn der escape-Taste wird dann abgefangen wird, z.B. durch das oben erwähnte fiel combobox, dann sind Sie alle plötzlich deaktiviert die Validierung auch auf OK.
Touché!
Jemand eine andere leuchtende Ideen auf, wie man diese zu arbeiten, ohne Angabe alle möglichen Arten von Steuerelementen, die tun und was die Bedingungen sind, wenn Sie benötigen, zu entkommen, z.B. Steuerelement ComboBox und prüfen, ob es gefallen und wenn dem so ist-bail-out.
Weder die ProcessDialogKeys noch Überprüfen handler Antworten, die für mich gearbeitet, vielleicht, weil ich bin mit einer errorProvider-statt einer MessageBox. Die einfachste Antwort, die ich habe zu arbeiten, ist, zu vergessen, zu Validieren und verwenden Sie einfach die folgende:-