SDX Privatbilanz für Windows 8.1: Eingabevalidierung

25. November 2013

Die Validierung von Benutzereingaben ist eine Standard-Anforderung vieler Business-Anwendungen. Leider ist dafür die Unterstützung in Windows Store Apps mit XAML/C# und WinRT mangelhaft. Dieser Artikel zeigt inkl. Codebeispielen, wie die Eingabevalidierung in der Privatbilanz-App für Windows 8.1 umgesetzt wurde.

Drum prüfe, wer sich bindet

In der Privatbilanz-App für Windows 8 wurde bewusst auf die Implementierung einer Eingabevalidierung verzichtet, auch wenn dies eine schmerzliche Entscheidung war. Der Grund: WinRT bzw. XAML/.NET für WinRT boten technisch nicht die aus WPF/Silverlight bekannten Mechanismen an, um eine durchgängige Eingabevalidierung zu ermöglichen. Leider hat sich auch unter Windows 8.1 nichts an dieser Situation geändert.

Dabei stellt die Validierung von Benutzereingaben häufig eine Notwendigkeit von Business-Anwendungen dar. Sie verhindert, dass inkonsistente Daten in eine Datenbank gelangen und ermöglicht das Festlegen von Qualitätsbedingungen an Daten, die u.a. ein einwandfreies Arbeiten der Business-Logik ermöglichen. Last but not least wird auch der Benutzer vor ungewollten Fehleingaben geschützt.

Die Adaption der Privatbilanz-App an Windows 8.1 wurde zum Anlass genommen, um die Validierung von Benutzereingaben exemplarisch anhand des Bilanzpostens “Immobilie” zu implementieren. So sind bei der Eingabe der Daten einer Immobilie die folgenden Regeln einzuhalten:

  • Der Name muss mindestens 3 Buchstaben haben.
  • Die Wohnungsnummer muss gesetzt sein.
  • Das Baujahr sollte nicht in der Zukunft liegen.

Die Validierung des Baujahrs wird dabei als Warnung an den Benutzer ausgegeben, um ihm die Aufnahme noch nicht fertig gestellter Immobilien in seine Vermögenswerte zu ermöglichen:

Win81_Validierung

 

Für Entwickler: Die “WinRT XAML Validation”-Bibliothek

Die Unterstützung der Eingabevalidierung unter Windows 8.1 lässt leider ebenso zu wünschen übrig wie unter Windows 8. Microsoft hat es hier versäumt, eine komfortable und durchgängige Lösung in die Entwicklerplattform zu integrieren.

Aus diesem Grund wurde auf eine mittlerweile entstandene Drittanbieter-Bibliothek zurück gegriffen: WinRT XAML Validation (frei auf Codeplex verfügbar). Diese Bibliothek wurde von meinem Kollegen Markus Demmler und mir entwickelt und stellt eine flexible sowie sehr funktionale Lösung zur Eingabevalidierung in XAML/C# Windows Store Apps bereit. Im Folgenden soll kurz beschrieben werden, wie die Validierung in der Privatbilanz-App damit umgesetzt wurde. Eine weitergehende Beschreibung gibt es in einem frei verfügbaren Artikel der dotnetpro und in der offiziellen Dokumentation der Bibliothek.

Der Standardweg zur Validierung mit der “WinRT XAML Validation”-Bibliothek besteht in der Definition von Data Annotations auf den Model-Entitäten. Da die Entitäten im Fall der Privatbilanz-App aber von einer WCF-Service-Referenz generiert wurden und somit ihre Properties nicht mit Attributen erweiterbar sind, wurde auf die Nutzung der manuellen Validierung zurückgegriffen. Dazu werden einer Instanz von BindableValidator (aus der Validierungs-Bibliothek) bei invaliden Eingaben entsprechende Validierungsmeldungen hinzugefügt:

   1: public BindableValidator Validate(Immobilie immobilie)

   2: {

   3:     var validator = new BindableValidator(immobilie);

   4:  

   5:     if (immobilie.Name == null || !Regex.IsMatch(immobilie.Name, "^.{3,50}$"))

   6:     {

   7:         validator.AddMessage(() => immobilie.Name, 

   8:             ValidationLevel.Error, "Name muss 3-50 Zeichen lang sein");

   9:     }

  10:  

  11:     if (String.IsNullOrEmpty(immobilie.Wohnungsnummer))

  12:     {

  13:         validator.AddMessage(() => immobilie.Wohnungsnummer, 

  14:             ValidationLevel.Error, "Wohnungsnummer muss gesetzt sein");

  15:     }

  16:  

  17:     if (immobilie.Baujahr > DateTime.Today.Year)

  18:     {

  19:         validator.AddMessage(() => immobilie.Baujahr, 

  20:             ValidationLevel.Warning, "Baujahr liegt in der Zukunft");

  21:     }

  22:  

  23:     return validator;

  24: }

Diese Validate()-Methode wird aufgerufen, wenn Daten einer Immobilie vom Benutzer geändert wurden und das Objekt gespeichert werden soll. Der resultierende BindableValidator kann z.B. im View Model als Property-Wert gespeichert werden und wird im XAML-Code gegen ein ValidationPanel-Control gebunden, das um das jeweilige Eingabefeld gelegt wird:

   1: <vc:ValidationPanel ValidationSource="{Binding Validator[Name]}">

   2:     <TextBox Text="{Binding Bilanzposten.Name, Mode=TwoWay}" />

   3: </vc:ValidationPanel>

Der Rest funktioniert automatisch, d.h. wenn eine Validierungsmeldung für das jeweilige Property des Datenobjekts (in diesem Fall "Name") erzeugt wird, stellt das ValidationPanel diese Meldung entsprechend dar und entfernt sie auch wieder, wenn der Fehler behoben wurde.

Dies ist eine Möglichkeit, die “WinRT XAML Validation”-Bibliothek zu verwenden. Sie bietet allerdings noch deutlich mehr Funktionen an:

  • Validierung über Validierungsattribute
  • Manuelle Validierung
  • Implizite Ausführung der Validierung
  • Explizite Ausführung der Validierung
  • UI-Controls zur Darstellung von Validierungsmeldungen

Ein Blick lohnt sich daher auf jeden Fall!