WPFデータバインディングと検証ルールのベストプラクティス


101

一部のカスタムCLRオブジェクトの編集を可能にするデータバインディングを使用している非常に単純なWPFアプリケーションがあります。ここで、ユーザーが[保存]をクリックしたときに入力検証を実行したいと考えています。ただし、私が読んだすべてのWPFの本は、この問題に実際に取り組んでいるわけではありません。カスタムのValidationRulesを作成できると思いますが、これが私のニーズに対して過剰であるかどうか疑問に思っています。

だから私の質問はこれです:WPFでユーザー入力を検証するためのベストプラクティスを示す良いサンプルアプリケーションまたは記事がどこかにありますか?

回答:


83

新しい推奨方法はIDataErrorInfoを使用することかもしれません

詳細はこちら


3
また、WPF + MVVMでのベストプラクティス検証のデモを含み、IDataErrorInfoを使用するCinchフレームワーク(cinch.codeplex.com)を見つけました
Mark Heath

3
.NET 4.5では、文字列だけでなくオブジェクトを返すことができるINotifyErrorInfoを使用できます。
Peter

24

MSのパターンと実践のドキュメントから

データ検証とエラー報告

多くの場合、ビューモデルまたはモデルは、データ検証を実行し、ユーザーが修正できるようにビューにデータ検証エラーを通知する必要があります。

SilverlightとWPFは、ビューのコントロールにバインドされている個々のプロパティを変更するときに発生するデータ検証エラーの管理をサポートします。コントロールにデータバインドされている単一のプロパティの場合、ビューモデルまたはモデルは、着信する不正な値を拒否して例外をスローすることにより、プロパティセッター内でデータ検証エラーを通知できます。データバインディングのValidatesOnExceptionsプロパティがtrueの場合、WPFおよびSilverlightのデータバインディングエンジンが例外を処理し、データ検証エラーがあることをユーザーに視覚的に通知します。

ただし、この方法でプロパティを持つ例外をスローすることは、可能な限り回避する必要があります。別のアプローチは、ビューモデルまたはモデルクラスにIDataErrorInfoまたはINotifyDataErrorInfoインターフェイスを実装することです。これらのインターフェイスを使用すると、ビューモデルまたはモデルは、1つ以上のプロパティ値のデータ検証を実行し、ビューにエラーメッセージを返し、ユーザーにエラーを通知できます。

ドキュメントでは、IDataErrorInfoとINotifyDataErrorInfoの実装方法について説明しています。


3
例外の推奨をスローするのを見たとき、私は最初に心配しました。「この方法でプロパティを使用して例外をスローすることは、可能な限り回避する必要があります」
kenwarner

22
また、Microsoftの一部のマペットは、INotifyDataErrorInfoを.net4に含めず、silverlightのみに含めることを決定したことにも注意してください。その痛み..
aL3891

5
@これは、.NET -4,5-にソートされますal3891- msdn.microsoft.com/en-us/library/...
RichardOD

@ aL3891欠落しているINotifyDataErrorInfoの代替手段はありますか?
AgentKnopf 2013年

10

個人的には、検証を処理するために例外を使用しています。次の手順が必要です。

  1. データバインディング式で、「ValidatesOnException = True」を追加する必要があります
  2. バインドしているデータオブジェクトで、DependencyPropertyChangedハンドラーを追加する必要があります。ここで、新しい値が条件を満たしているかどうかをチェックします-満たさない場合-オブジェクトの古い値に復元し(必要な場合)、例外をスローします。
  3. コントロールに無効な値を表示するために使用するコントロールテンプレートで、Errorコレクションにアクセスして例外メッセージを表示できます。

ここでの秘訣は、DependencyObjectから派生したオブジェクトにのみバインドすることです。INotifyPropertyChangedの単純な実装は機能しません-フレームワークにバグがあり、エラーコレクションにアクセスできません。




0

ビジネスクラスがUIで直接使用されている場合は、ロジックを所有者の近くに配置するため、IDataErrorInfoを使用することをお勧めします。

ビジネスクラスがWCF / XmlWebサービスへの参照によって作成されたスタブクラスである場合、IDataErrorInfoを使用したり、ExceptionValidationRuleで使用するためにExceptionをスローしたりすることはできません。代わりに次のことができます。

  • カスタムのValidationRuleを使用します。
  • WPF UIプロジェクトで部分クラスを定義し、IDataErrorInfoを実装します。

1
これは古いことはわかっていますが、アレックスが応答できることを期待しています。これも私がたどった結論ですが、問題は、ValidationRuleで100を超えることができない "Age"プロパティ(たとえば)の検証を記述し、IDataErrorInfoインターフェイスで同じロジックを繰り返す必要があることです。 、ロジックを複製します。それを回避する方法はありますか?
JFTxJ 2013

ロジックをどこに複製しますか?ある種のサーバー検証では?あなたのコメントでは、UIでIDataErrorInfoを使用して検証し、ビジネスオブジェクトで検証を複製していると思いませんか。その場合は、両方で検証するのが正しいです。ビジネスオブジェクトはUIを信頼できず、独自の検証を実行する必要があります(重複のように見えます)
Alex Pollan

いいえ、検証ロジックの重複はIDataErrorInfoとカスタム検証ルールにあります...カスタム検証ルールは、バインドされたオブジェクトに実際に更新される前にデータを検証する唯一の方法であるため、その検証(年齢は低くなければなりません)次に100)は、「フィールドごと」のメッセージを返すためにIDataErrorInfoで定義する必要がありますが、カスタム検証ルールでも実装する必要があります。理にかなっていますか?
JFTxJ 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.