Best Practices für WPF-Datenbindungs- und -validierungsregeln

101

Ich habe eine sehr einfache WPF-Anwendung, in der ich Datenbindung verwende, um einige benutzerdefinierte CLR-Objekte bearbeiten zu können. Ich möchte jetzt eine Eingabevalidierung vornehmen, wenn der Benutzer auf Speichern klickt. Alle WPF-Bücher, die ich gelesen habe, widmen diesem Thema jedoch keinen Platz. Ich sehe, dass Sie benutzerdefinierte Validierungsregeln erstellen können, aber ich frage mich, ob dies für meine Anforderungen übertrieben wäre.

Meine Frage lautet also: Gibt es irgendwo eine gute Beispielanwendung oder einen guten Artikel, der bewährte Methoden zur Validierung von Benutzereingaben in WPF demonstriert?

Mark Heath
quelle

Antworten:

83

Ich denke, der neue bevorzugte Weg könnte darin bestehen, IDataErrorInfo zu verwenden

Lesen Sie hier mehr

Rudigrobler
quelle
3
Ich habe auch das Cinch-Framework ( cinch.codeplex.com ) gefunden, das eine Demo der Best Practices-Validierung in WPF + MVVM enthält und IDataErrorInfo
Mark Heath
3
In .NET 4.5 können Sie INotifyErrorInfo verwenden, mit dem Sie Objekte anstelle von nur Zeichenfolgen zurückgeben können.
Peter
24

Aus der Dokumentation zu MS Patterns & Practices :

Datenvalidierung und Fehlerberichterstattung

Ihr Ansichtsmodell oder Modell muss häufig eine Datenüberprüfung durchführen und der Ansicht Datenüberprüfungsfehler melden, damit der Benutzer diese korrigieren kann.

Silverlight und WPF bieten Unterstützung für die Verwaltung von Datenüberprüfungsfehlern, die beim Ändern einzelner Eigenschaften auftreten, die an Steuerelemente in der Ansicht gebunden sind. Bei einzelnen Eigenschaften, die an ein Steuerelement gebunden sind, kann das Ansichtsmodell oder -modell einen Datenüberprüfungsfehler innerhalb des Eigenschaftssetzers signalisieren, indem ein eingehender fehlerhafter Wert zurückgewiesen und eine Ausnahme ausgelöst wird. Wenn die ValidatesOnExceptions-Eigenschaft für die Datenbindung wahr ist, behandelt die Datenbindungs-Engine in WPF und Silverlight die Ausnahme und zeigt dem Benutzer einen visuellen Hinweis an, dass ein Datenüberprüfungsfehler vorliegt.

Das Auslösen von Ausnahmen mit Eigenschaften auf diese Weise sollte jedoch nach Möglichkeit vermieden werden. Ein alternativer Ansatz besteht darin, die Schnittstellen IDataErrorInfo oder INotifyDataErrorInfo in Ihrem Ansichtsmodell oder Ihren Modellklassen zu implementieren. Über diese Schnittstellen kann Ihr Ansichtsmodell oder Modell eine Datenüberprüfung für einen oder mehrere Eigenschaftswerte durchführen und eine Fehlermeldung an die Ansicht zurückgeben, damit der Benutzer über den Fehler benachrichtigt werden kann.

In der Dokumentation wird erläutert, wie IDataErrorInfo und INotifyDataErrorInfo implementiert werden.

Klopfen
quelle
3
Ich machte mir zuerst Sorgen, als ich sah, dass der Wurf eine Ausnahmeempfehlung war. froh zu sehen, dass gefolgt von "
Auslösen
22
Es sollte auch beachtet werden, dass einige Muppets bei Microsoft beschlossen haben, INotifyDataErrorInfo nicht in .net4, sondern nur in Silverlight aufzunehmen. Es ist ein Schmerz ..
aL3891
5
@ al3891- dies wird in .NET 4.5- msdn.microsoft.com/en-us/library/…
RichardOD
@ aL3891 Gibt es eine Alternative für die fehlende INotifyDataErrorInfo?
AgentKnopf
10

Persönlich verwende ich Ausnahmen, um die Validierung zu handhaben. Es erfordert folgende Schritte:

  1. In Ihrem Datenbindungsausdruck müssen Sie "ValidatesOnException = True" hinzufügen.
  2. In Ihrem Datenobjekt, an das Sie gebunden sind, müssen Sie den DependencyPropertyChanged-Handler hinzufügen, mit dem Sie überprüfen, ob der neue Wert Ihre Bedingungen erfüllt. Wenn nicht, stellen Sie den alten Wert des Objekts wieder her (falls erforderlich) und lösen eine Ausnahme aus.
  3. In Ihrer Steuerelementvorlage, die Sie zum Anzeigen eines ungültigen Werts im Steuerelement verwenden, können Sie auf die Fehlersammlung zugreifen und eine Ausnahmemeldung anzeigen.

Der Trick dabei ist, nur an Objekte zu binden, die von DependencyObject abgeleitet sind. Eine einfache Implementierung von INotifyPropertyChanged würde nicht funktionieren - es gibt einen Fehler im Framework, der Sie daran hindert, auf die Fehlersammlung zuzugreifen.

Greg
quelle
3

Überprüfen Sie auch diesen Artikel . Angeblich hat Microsoft seine Enterprise Library (v4.0) aus ihren Mustern und Praktiken veröffentlicht, in denen sie das Thema Validierung behandeln, aber Gott weiß, warum sie keine Validierung für WPF aufgenommen haben. In dem Blog-Beitrag, auf den ich Sie verweise, wird der Autor erklärt tat es anzupassen. Hoffe das hilft!

Murki
quelle
2

Möglicherweise interessieren Sie sich für die BookLibrary- Beispielanwendung des WPF Application Framework (WAF) . Es wird gezeigt, wie die Validierung in WPF verwendet wird und wie die Schaltfläche Speichern gesteuert wird, wenn Validierungsfehler vorliegen.

jbe
quelle
0

Wenn Ihre Business Class direkt von Ihrer Benutzeroberfläche verwendet wird, ist die Verwendung von IDataErrorInfo vorzuziehen, da dadurch die Logik näher an ihrem Eigentümer liegt.

Wenn Ihre Geschäftsklasse eine Stub-Klasse ist, die durch einen Verweis auf einen WCF / XmlWeb-Dienst erstellt wurde, können / dürfen Sie weder IDataErrorInfo verwenden noch eine Ausnahme für die Verwendung mit ExceptionValidationRule auslösen. Stattdessen können Sie:

  • Verwenden Sie eine benutzerdefinierte Validierungsregel.
  • Definieren Sie eine Teilklasse in Ihrem WPF-UI-Projekt und implementieren Sie IDataErrorInfo.
Alex Pollan
quelle
1
Ich weiß, dass dies alt ist, aber ich hoffe, dass Alex antworten kann. Dies ist die Schlussfolgerung, zu der ich auch gekommen bin, aber das Problem ist, dass Sie eine Validierung für (zum Beispiel) eine "Age" -Eigenschaft schreiben müssen, die in der ValidationRule nicht größer als 100 sein kann, und dann dieselbe Logik in der IDataErrorInfo-Schnittstelle wiederholen müssen , die die Logik dupliziert. Gibt es einen Weg daran vorbei?
JFTxJ
Wo duplizierst du die Logik? in einer Art Server-Validierung? Ich vermute durch Ihren Kommentar, dass Sie mit IDataErrorInfo in der Benutzeroberfläche validieren und die Validierung im Geschäftsobjekt duplizieren, nicht wahr? Wenn ja, dann ist es richtig, auf beiden Seiten zu validieren. Die Geschäftsobjekte können den Benutzeroberflächen nicht vertrauen und müssen ihre eigene Validierung durchführen (obwohl es sich um eine Duplizierung handelt)
Alex Pollan,
Nein, die Duplizierung der Validierungslogik befindet sich in IDataErrorInfo und in der benutzerdefinierten Validierungsregel ... Da die benutzerdefinierte Validierungsregel die einzige Möglichkeit ist, die Daten zu validieren, bevor sie tatsächlich auf ein gebundenes Objekt aktualisiert werden, muss diese Validierung (Alter muss niedriger sein) dann muss 100) in der IDataErrorInfo definiert werden, um eine "pro Feld" -Nachricht zurückzugeben, muss aber auch in der benutzerdefinierten Validierungsregel implementiert werden. Macht Sinn?
JFTxJ