Ich weiß, dass dieser Thread schon ziemlich alt ist, aber ich dachte, ich poste mal die Lösung, die ich gefunden habe.
Das größte Problem bei der Validierung in WinForms ist, dass die Validierung nur ausgeführt wird, wenn das Steuerelement "den Fokus verloren" hat. Der Benutzer muss also erst in ein Textfeld klicken und dann irgendwo anders klicken, damit die Validierungsroutine ausgeführt wird. Dies ist in Ordnung, wenn Sie nur darauf achten, dass die eingegebenen Daten korrekt sind. Aber das funktioniert nicht gut, wenn Sie versuchen, sicherzustellen, dass ein Benutzer ein Textfeld nicht leer gelassen hat, indem er es überspringt.
Wenn der Benutzer in meiner Lösung auf die Schaltfläche "Submit" für ein Formular klickt, überprüfe ich jedes Steuerelement auf dem Formular (oder dem angegebenen Container) und verwende Reflection, um festzustellen, ob eine Validierungsmethode für das Steuerelement definiert ist. Ist dies der Fall, wird die Validierungsmethode ausgeführt. Wenn eine der Überprüfungen fehlschlägt, gibt die Routine einen Fehler zurück und ermöglicht es, den Prozess zu beenden. Diese Lösung funktioniert besonders gut, wenn Sie mehrere Formulare zu validieren haben.
1) Kopieren Sie einfach diesen Abschnitt des Codes und fügen Sie ihn in Ihr Projekt ein. Da wir Reflection verwenden, müssen Sie System.Reflection zu Ihren using-Anweisungen hinzufügen
class Validation
{
public static bool hasValidationErrors(System.Windows.Forms.Control.ControlCollection controls)
{
bool hasError = false;
// Now we need to loop through the controls and deterime if any of them have errors
foreach (Control control in controls)
{
// check the control and see what it returns
bool validControl = IsValid(control);
// If it's not valid then set the flag and keep going. We want to get through all
// the validators so they will display on the screen if errorProviders were used.
if (!validControl)
hasError = true;
// If its a container control then it may have children that need to be checked
if (control.HasChildren)
{
if (hasValidationErrors(control.Controls))
hasError = true;
}
}
return hasError;
}
// Here, let's determine if the control has a validating method attached to it
// and if it does, let's execute it and return the result
private static bool IsValid(object eventSource)
{
string name = "EventValidating";
Type targetType = eventSource.GetType();
do
{
FieldInfo[] fields = targetType.GetFields(
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic);
foreach (FieldInfo field in fields)
{
if (field.Name == name)
{
EventHandlerList eventHandlers = ((EventHandlerList)(eventSource.GetType().GetProperty("Events",
(BindingFlags.FlattenHierarchy |
(BindingFlags.NonPublic | BindingFlags.Instance))).GetValue(eventSource, null)));
Delegate d = eventHandlers[field.GetValue(eventSource)];
if ((!(d == null)))
{
Delegate[] subscribers = d.GetInvocationList();
// ok we found the validation event, let's get the event method and call it
foreach (Delegate d1 in subscribers)
{
// create the parameters
object sender = eventSource;
CancelEventArgs eventArgs = new CancelEventArgs();
eventArgs.Cancel = false;
object[] parameters = new object[2];
parameters[0] = sender;
parameters[1] = eventArgs;
// call the method
d1.DynamicInvoke(parameters);
// if the validation failed we need to return that failure
if (eventArgs.Cancel)
return false;
else
return true;
}
}
}
}
targetType = targetType.BaseType;
} while (targetType != null);
return true;
}
}
2) Verwenden Sie das Standard-Validierungsereignis für jedes Steuerelement, das Sie validieren möchten. Achten Sie darauf, e.Cancel zu verwenden, wenn die Validierung fehlschlägt!
private void txtLastName_Validating(object sender, CancelEventArgs e)
{
if (txtLastName.Text.Trim() == String.Empty)
{
errorProvider1.SetError(txtLastName, "Last Name is Required");
e.Cancel = true;
}
else
errorProvider1.SetError(txtLastName, "");
}
3) Überspringen Sie diesen Schritt nicht! Setzen Sie die AutoValidieren Eigenschaft auf dem Formular zu EnableAllowFocusChange . Dies ermöglicht den Wechsel zu einem anderen Steuerelement, auch wenn die Validierung fehlschlägt.
4) Rufen Sie schließlich in Ihrer Submit-Button-Methode die Validation-Methode auf und geben Sie an, welchen Container Sie überprüfen möchten. Dabei kann es sich um das gesamte Formular oder nur um einen Container auf dem Formular handeln, z. B. einen Bereich oder eine Gruppe.
private void btnSubmit_Click(object sender, EventArgs e)
{
// the controls collection can be the whole form or just a panel or group
if (Validation.hasValidationErrors(frmMain.Controls))
return;
// if we get here the validation passed
this.close();
}
Viel Spaß beim Coding!