EDM: Validieren von Entitäten mit IDataErrorInfo

Wenn Sie ein Abonnement des Magazins 'DATENBANKENTWICKLER' besitzen, können Sie sich anmelden und den kompletten Artikel lesen.
Anderenfalls können Sie das Abonnement hier im Shop erwerben.

EDM: Validieren von Entitäten mit IDataErrorInfo

Die Validierung bei der Eingabe von Daten ist eines der wichtigsten Themen bei der Erstellung benutzerfreundlicher Anwendungen. Nachdem der Artikel »EDM: Ausnahmen beim Speichern behandeln« gezeigt hat, wozu Sie im Rahmen der Validierung die durch Restriktionen im Datenmodell auftretenden Exceptions nutzen können, schauen wir uns nun einen einfachen Weg an, um Validierungsregeln in Entitätsklassen zu definieren und beim Fehlschlagen der Validierung entsprechende Meldungen in der Benutzeroberfläche auszugeben. Dabei zeigen wir hier den Umgang mit der Schnittstelle »IDataErrorInfo«.

Beispielanwendung

Wie im oben genannten Artikel nutzen wir wieder die Beispielanwendung Bestellverwaltung. Bevor die im Datenmodell dieser Anwendung festgelegten Restriktionen greifen und bei Fehleingaben Exceptions auslösen, wollen wir Validierungen programmieren, um Fehleingaben des Benutzers zu vermeiden. In diesem Fall schauen wir uns die Seite Kundendetails.xaml.cs an, um die Programmierung der Validierung zu veranschaulichen. Dies soll im Ergebnis wie in Bild 1 aussehen.

Beispiel für eine einfache Validierungsmeldung

Bild 1: Beispiel für eine einfache Validierungsmeldung

Validierung

Die hier vorgestellten Techniken zur Validierung von Benutzereingaben beziehen sich auf die Untersuchung der jeweiligen Entität – ist ein Wert in einem Feld mit einem eindeutigen Index bereits vorhanden? Darf ein Feld überhaupt leer sein? Hat der Benutzer auch ein gültiges Datum eingegeben? Liegt der Zahlenwert im zulässigen Bereich?

Validierung auf Feldebene

Validierungen können Sie auf mehrere Arten durchführen. Der Artikel EDM: Ausnahmen bei Speichern behandeln zeigt, wie Sie erst beim Auftreten von Fehlern bei Speichern auf fehlerhafte Eingaben des Benutzers reagieren können. Davor gibt es noch mindestens zwei weitere Methoden:

  • Validieren direkt nach der Eingabe eines Wertes in ein Steuerelement und Hinweis auf die fehlerhafte Eingabe
  • Validieren, nachdem der Benutzer den Speichervorgang initiiert hat, aber bevor das Speichern selbst stattfindet. Hier können dann nicht nur einzelne Felder isoliert, sondern auch mehrere Felder im Zusammenhang untersucht werden. Wie dies gelingt, zeigt zum Beispiel der Artikel EDM: Validieren von Entiten mit IValidatableObject.

In diesem Artikel schauen wir uns die einfachere Validierung direkt nach der Eingabe eines Wertes an.

Für den Benutzer hat dies beispielsweise den Vorteil, dass er Fehleingaben direkt erkennt und diese direkt erkennen kann.

Einfache Validierung

In vielen Fällen reicht eine einfache Validierung der Eingaben für Steuerelemente aus. Damit meinen wir, dass nur die Werte einzelner Steuerelemente geprüft werden sollen, und zwar direkt nach der Eingabe. So können Sie beispielsweise abfragen, ob ein Wert eine bestimmte Mindestlänge erreicht und bei Nichterfüllung dieser Vorgabe einen optischen Hinweis einblenden. Dieser Artikel zeigt, wie Sie eine solche Validierung zu einer Anwendung hinzufügen können.

Beispielanwendung

Die Beispielanwendung heißt Bestellverwaltung. Die im Fenster MainWindow eingeblendete Seite Kundendetails.xaml soll zeigen, wie Sie die hier vorgestellte Art der Validierung implementieren.

Ablauf der Validierung

Die Validierung mit der hier vorgestellten Methode geschieht immer gleich nach dem Abschluss der Eingabe in ein Feld. Sie löst dann die Anzeige des Steuerelements mit der fehlerhaften Eingabe mit rotem Rahmen und mit einem Warnsymbol aus. Das Überfahren des Warnsymbols mit der Maus führt zur Anzeige eines ToolTip-Textes, der weitere Informationen zum vorliegenden Fehler liefert.

Aufbau der Validierung

Die Validierung basiert auf zwei verschiedenen Elementen. Das erste Element ist die Klasse, welche die Entität der zu validierenden Objekte beschreibt, in unserem Fall also etwa Kunde.cs. Hier legen wir in Form einer Methode die Regeln fest, nach der das soeben geänderte Steuerelement geprüft werden soll. Damit erhalten wir eine Basis, die wir für alle Zugriffe auf Objekte dieser Klasse nutzen können, was die Wiederverwendbarkeit dieser Klasse erhöht. Der zweite Teil der Validierung ist das Hinzufügen einer bestimmten Eigenschaft zum Binding des Steuerelements, im Falle eines Textfeldes also beispielsweise zum Attribut Text. Außerdem müssen wir noch definieren, wie sich das Aussehen des Textfeldes ändern soll, wenn die Validierung fehlgeschlagen ist. Immerhin wollen wir den Benutzer ja auch informieren, wenn dieser eine Fehleingabe tätigt. Dies erledigen wir durch eine entsprechende Vorlage für das TextBox-Steuerelement. Schauen wir uns nun die drei Elemente der Validierung an.

Anpassen der Klasse Kunde.cs

Unser Entity Data Model, dass wir auf Basis der SQL Server-Datenbank Bestellverwaltung erstellt haben, enthält auch eine Klasse namens Kunde.cs, welche die Eigenschaften eines Kunden abbildet. Diese erweitern wir nun um die Schnittstelle IDataErrorInfo. Da diese in der Bibliothek System.ComponentModel beschrieben wird, fügen wir zunächst einen Verweis auf diese Schnittstelle per using-Schlüsselwort hinzu:

using System.ComponentModel;

Danach legen wir in der Kopfzeile der Klasse fest, dass diese die Schnittstelle IDataErrorInfo implementieren soll. Die Zeile sieht dann so aus:

public partial class Kunde : IDataErrorInfo {
...

Um die Member dieser Schnittstelle schnell zu implementieren, wählen Sie den Kontextmenü-Eintrag Schnellaktionen und Refactorings von IDataErrorInfo aus. Im nun erscheinenden Popup wählen Sie Schnittstelle implementieren aus und erstellen so die beiden Methoden dieser Schnittstelle. Diese sehen zunächst wie folgt aus:

public string Error {
     get {
         throw new NotImplementedException();
     }
}
public string this[string columnName] {
     get {
         throw new NotImplementedException();
     }
}

Hier fügen wir nun für die Methode this eine erste Validierung ein. Diese soll sicherstellen, dass die Eingabe in das Feld Vorname nicht leer ist.

Die Methode this nimmt mit dem Parameter columnName immer den Namen des Feldes entgegen, dass untersucht werden soll – in diesem Fall Vorname. Im get-Teil der Methode deklarieren wir die Variable result als string und prüfen in einer if-Bedingung, ob columnName den Wert Vorname enthält. Falls ja, prüfen wir, ob Vorname den Wert null enthält oder leer ist (IsNullOrEmpty). Ist das der Fall, stellen wir den Rückgabewert mit der Variablen errorMessage auf den Text Bitte geben Sie einen Vornamen ein. ein (siehe Listing 1).

public string this[string columnName] {
     get {
         string errorMessage = "";
         switch (columnName) {
             case "Vorname":
                 {
                     if (String.IsNullOrEmpty(Vorname)) {
                         errorMessage = "Bitte geben Sie einen Vornamen ein.";
                     }
                     break;
                 }
         }
         return errorMessage;
     }
}

Listing 1: Implementierung der Schnittstelle IDataErrorInfo in der Klasse Kunde.cs

.xaml-Code erweitern

Wenn Sie das Projekt nun starten, einen neuen Kunden anlegen und einen Vornamen mit maximal drei Zeichen angeben, tut sich jedoch erst einmal nichts. Das ist auch kein Wunder, denn wir haben ja im .xaml-Code auch noch nicht angegeben, dass es eine Validierung gibt.

Damit die Methode this der Klasse Kunde.cs überhaupt aufgerufen wird, müssen wir der Bindung des Textfeldes Vorname das Attribut ValidatesOnDataErrors hinzufügen und dafür den Wert true festlegen:

<TextBox x:Name="txtVorname" Grid.Column="1" Grid.Row="3" HorizontalAlignment="Stretch" Text="{Binding kunde.Vorname, Mode=TwoWay, ValidatesOnDataErrors=True}" />

Ein erneuter Start der Anwendung und die Eingabe eines ungültigen Ausdrucks zeigt nun Wirkung: Das fehlerhafte Feld wird mit einem roten Rahmen versehen (siehe Bild 2).

Eine fehlerhafte Eingabe wird durch einen roten Rahmen markiert.

Bild 2: Eine fehlerhafte Eingabe wird durch einen roten Rahmen markiert.

Validierungshinweis anbringen

Nun fehlt noch der Hinweis für den Benutzer, damit er weiß, was er bei der Eingabe falsch gemacht hat. Dazu wollen wir rechts vom Textfeld ein Warnsymbol anzeigen, dass beim Überfahren mit der Maus einen ToolTip-Text einblendet. Dazu ist nicht mehr nötig als die Änderung einiger Eigenschaften des TextBox-Elements. Da wir diese nicht nur für eine TextBox benötigen, sondern für alle, definieren wir direkt ein entsprechendes Style-Element in den Ressourcen des übergeordneten Elements, hier also für ein Page-Element.

Also fügen Sie, soweit noch nicht vorhanden, direkt unterhalb des Page-Elements ein Page.Resources-Element wie das aus Listing 2 hinzu (wenn Sie ein Window zur Anzeige der zu validierenden Daten nutzen, handelt es sich um das Element Window.Resources).

<Page.Resources>
     ...
     <Style TargetType="{x:Type TextBox}">
         <Setter Property="Height" Value="23" />
         <Setter Property="Margin" Value="3,3,27,0" />
         <Setter Property="VerticalAlignment" Value="Center" />
         <Setter Property="Validation.ErrorTemplate">
             <Setter.Value>
                 <ControlTemplate>
                     <DockPanel>
                         <Border Background="Red" DockPanel.Dock="right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10" 
                 ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">

Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.

Bitte geben Sie die Zeichenfolge in das nachfolgende Textfeld ein

Die mit einem * markierten Felder sind Pflichtfelder.

Ich habe die Datenschutzbestimmungen zur Kenntnis genommen.