Eingabeüberprüfung für Textfelder in einem Formular

106809
CAD

In einem Win-Formular führe ich die Erstprüfung im Formular durch. Ich möchte also vor dem Speichern von Daten überprüfen, ob der Benutzer alle erforderlichen Felder (Textfelder) gefüllt hat. Es gibt ungefähr 18 solcher Textfelder in dem Formular. Momentan mache ich es wie folgt. Um den Code kurz zu machen, werden im Code nur drei Felder angezeigt.

     private void cmbSave_Click(object sender, EventArgs e)
     {
         if(IsFilled (txtApplicationNumber.Text))
         { 
             if(IsFilled (txtEmployeeID.Text))
             {
                 if (IsFilled(txtNIC.Text))
                 Save(sender, e);
             }
         }                          
    }


    private bool IsFilled(string s)
    {
        if (s != "")
        { return true; }
        else
        { return false; }
    }

Eine andere Option wäre, die Logik in cmbSave_Click wie folgt zu verwenden:

    private void cmbSave_Click(object sender, EventArgs e)
    {
        If (txtApplicationNumber.Text!="" & txtEmployeeID.Text!="" & txtNIC.Text="")
        Save(sender, e)
    }

Grundsätzlich sollte der Code lesbar und konsistent sein und die Validierung ordnungsgemäß durchführen.

Welche Option könnte als besser angesehen werden? Wenn beide nicht gut sind, schlagen Sie bitte einen Weg vor?

Antworten
5
Schauen Sie in `string.IsNullOrEmpty ()` oder `string.IsNullOrWhiteSpace ()`. Jesse C. Slicer vor 6 Jahren 6
@ JesseC.Slicer, sah deinen Kommentar gleich nachdem ich gepostet habe ... lol Malachi vor 6 Jahren 0

6 Antworten auf die Frage

10
tinstaafl

Eine weitere Option wäre, das ValidatingEreignis abzuwickeln:

private void textBox_Validating(object sender, CancelEventArgs e)
{
    TextBox currenttb = (TextBox)sender;
    if(currenttb.Text == "")
        MessageBox.Show(string.Format("Empty field {0 }",currenttb.Name.Substring(3)));
        e.Cancel = true;
    else
    {
        e.Cancel = false;
    }
}

Das Hinzufügen des Handlers zu den Textfeldern kann leicht mit einer foreach-Schleife im Formularkonstruktor erfolgen:

foreach(TextBox tb in this.Controls.OfType<TextBox>().Where(x => x.CausesValidation == true))
{
    tb.Validating += textBox_Validating;
}

Jetzt kann der Benutzer ein Textfeld nicht leer lassen. Der Handler gibt den Fokus wieder in das Textfeld zurück. Um ein Textfeld von der Überprüfung auszuschließen, setzen Sie die CausesValidationEigenschaft einfach auf false.

In Ihrer Validierung () sehe ich, dass die Bedingung falsch ist. Wenn der Text jetzt nicht leer ist, wird die Nachricht angezeigt !! CAD vor 6 Jahren 0
Auch ich habe den Zustand geändert, es fehlt noch etwas! Jetzt kann ich mich nicht auf das nächste Textfeld konzentrieren? CAD vor 6 Jahren 0
Message.show (); sollte in `If`-Block nicht in` Else` stehen. Dann ist es ja gut ;) CAD vor 6 Jahren 0
5
Mathieu Guindon
 private void cmbSave_Click(object sender, EventArgs e)
 {
     if(IsFilled (txtApplicationNumber.Text))
     { 
         if(IsFilled (txtEmployeeID.Text))
         {
             if (IsFilled(txtNIC.Text))
             Save(sender, e);
         }
     }                          
}

Wie @Malachi feststellte, ist das Verschachteln hier leicht zu vermeiden. Es ist jedoch immer noch eine gemischte Abstraktionsebene - "Speichern" ist abstrakter als " Ist einer der Werte für txtApplicationNumber.Text, txtEmployeeID.Text und txtNIC.Text leer oder leer?".

Die konsistente Abstraktionsebene macht das Lesen des Codes viel einfacher:

private void cmbSave_Click(object sender, EventArgs e)
{
    if (ValidateForm())
    {
        Save(sender, e);
    }
}

Wo ValidateForm()befindet sich auf einer niedrigeren Abstraktionsebene und muss über das Vorhandensein von Textfeldern im Formular informiert werden:

private bool ValidateForm()
{
    var textBoxes = groupBox3.Controls.Cast<Control>()
                             .OfType<TextBox>()
                             .OrderBy(control => control.TabIndex);

    foreach(var textBox in textBoxes)
    {
        if (string.IsNullOrWhiteSpace(textBox.Text))
        {
           textBox.Focus();

           // remove "txt" prefix:
           var fieldName = textBox.Name.SubString(3);
           MessageBox.Show(string.Format("Field '{0}' cannot be empty.", fieldName));

           return false;
        }
    }

    return true;
}

Nur eine Anmerkung zu diesem Ausschnitt:

If (txtApplicationNumber.Text!="" & txtEmployeeID.Text!="" & txtNIC.Text="")

&macht ein bitweises AND, was ich wirklich bezweifle, dass Sie hier vorhaben. Wie @Malachi wies darauf hin, verwenden &&auszuführen logische UND .

"" funktioniert . string.Emptyfunktioniert genauso gut und teilt explizit Ihre Absicht mit, eine leere Zeichenfolge zu überprüfen. Jedoch, wenn Sie anfangen zu schreiben someString != ""oder someString != string.Empty, würde ich stattdessen die Verwendung empfehlen IsNullOrEmpty(someString). Wenn Sie dies zur Gewohnheit machen, wird verhindert, dass Sie NullReferenceExceptionspäter unter verschiedenen Umständen unerwartete Fehler beheben müssen: Denken Sie daran, dass a stringein Referenztyp ist, was bedeutet, dass dies zulässig istnull .

Ich habe auf Sie gewartet, um eine Antwort zu posten, nachdem ich all diese wunderbaren Kommentare gelesen hatte Malachi vor 6 Jahren 0
Was halten Sie von @ tinstaafl's Antwort? Ich denke, die Implementierung und Wartung wäre auf diese Weise sehr einfach, da wir für alle `TextBoxen 'einen' Handler 'verwenden. Wir könnten also separate "Handler" für "ComboBoxes", "MaskedTextBoxes" usw. haben. Ist das eine gute Praxis? Wenn wir zwei Methoden vergleichen, was wäre die geeignetste Option? CAD vor 6 Jahren 0
4
Malachi

Sie haben hier einige Extras, die Sie nicht brauchen.

wie 3 if-Anweisungen zum Schachteln. Reduziere es so

     private void cmbSave_Click(object sender, EventArgs e)
     {
         if(IsFilled (txtApplicationNumber.Text) && IsFilled (txtEmployeeID.Text) && IsFilled(txtNIC.Text))
         { 
             Save(sender, e);
         }                       
    }

Das macht den Code lesbarer, direkt auf den Punkt. Ich denke nicht, dass es Ihnen irgendeine Leistung geben wird, da es wahrscheinlich genau das ist, was Sie haben.

Übrigens: Normal: Sie sollten &&Ihre Konditionen haben und nicht&


Und dieser Code kann auch etwas geändert werden

private bool IsFilled(string s)
{
    if (s != "")
    { return true; }
    else
    { return false; }
}

zu so etwas

private bool IsFilled(string s)
{
    if (s.isNullOrEmpty())
    {
         return false;
    }
    return true;
}

Die extra else-Anweisung muss nicht geschrieben werden. Wenn die Zeichenfolge leer oder null ist, wird false zurückgegeben und der Rest des Codes wird trotzdem nicht ausgeführt.


Ich habe auch Ihre Antwort angeschaut, und ich denke, Sie können auch ein paar Schachteln loswerden.

private void cmbSave_Click(object sender, EventArgs e)
{
    foreach (Control c in groupBox3.Controls.Cast<Control>().OrderBy(c => c.TabIndex))
    {
        if (c is TextBox && string.IsNullOrWhiteSpace(c.Text))
        {
            MessageBox.Show(string.Format("Empty field {0}",c.Name.Substring(3)));
            c.Focus();
            return;                
        }
    }
    Save(sender, e);
}

nur ein bisschen sauberer ...

1
arpitbakshi

Ich würde mich lieber für einen einfachen Ansatz entscheiden, der Ihren Code sauberer, lesbarer und wartbarer macht:

private void cmbSave_Click(object sender, EventArgs e)
    {
        var controls = new[] { txtApplicationNumber.Text, txtEmployeeID.Text, txtNIC.Text };
        if (controls.All(x => string.IsNullOrEmpty(x)))
            Save(sender, e);
    }

Ich habe alle Werte in einem String - Array gehalten, für die ich für überprüfen nulloder empty, und verwenden, um eine einfache Erweiterung Methode Allzurückzukehren truenur, wenn alle Mitglieder des String - Array die Bedingung erfüllt.

1
RAB

Ich würde eher eine generische Funktion verwenden, die jedes Steuerelement im Formular übergeben würde und basierend auf dem Typ des Steuerelements eine separate Validierungslogik geschrieben würde. Falls eine zusätzliche Validierung, wie das Beschränken der Validierung auf nur einige Steuerelemente, gilt, wird dies auf der Funktionsaufrufebene entschieden.

-1
Ramesh P

In meinen Windows-Formularprojekten habe ich die Felder mit der booleschen Methode überprüft.

Suchen Sie nach dem folgenden Beispielbild, um die Felder zu überprüfen, bevor Sie die Daten speichern

Bild 3: Validierungsmethode

Hier habe ich die Felder mit der booleschen Methode validiert. Wenn alle Feldwerte richtig eingegeben wurden, wird true zurückgegeben. Andernfalls wird false zurückgegeben und eine Fehlernachricht angezeigt.