あなたは間違った道を歩いています。
MVVM で検証を処理する良い方法は、バインディングを実装IDataErrorInfo
して設定ValidatesOnDataErrors
することです。true
また、ほぼ確実にValidatesOnExceptions
、完全を期すために有効にして、プロパティをバインドしたコントロールでNotifyOnValidationError
バインド エンジンが添付イベントをトリガーするようにすることもできます。Validation.Error
詳細については、WPFでのデータ バインディングに関する MSDN ドキュメントの「検証」セクションを参照してください。
いくつかのヒント:
- .NET 4.5 では、と比較して強化された検証機能を提供する
INotifyDataErrorInfo
対応するバインディング プロパティが導入されています。あなたはそれを調べたいかもしれません。ValidatesOnNotifyDataErrors
IDataErrorInfo
IDataErrorInfo.Error
これは Windows フォーム インフラストラクチャによって使用され、WPF では無視されるため、実際に内部で意味のあることを行う必要はありません。getter throw を使用することもできますNotImplementedException
。
- このアプローチを説明する優れた読み物があり、例とコードが完備されています。
更新: 説明とサンプルコード
ValidationRule
この検証モデルには、自分自身の実装はまったく含まれていません。モデル (つまり、バインディング ソース) は、2 つのインターフェイスのいずれかを実装するだけで済みます。インターフェイスの実装方法は完全にあなた次第です。過去のプロジェクトで、基本的な非同期検証を実装しました
public interface IDelegatedValidation : IDataErrorInfo
{
/// <summary>
/// Occurs when validation is to be performed.
/// </summary>
event EventHandler<DelegatedValidationEventArgs> ValidationRequested;
}
public class DelegatedValidationEventArgs : EventArgs
{
public DelegatedValidationEventArgs(string propertyName)
{
this.PropertyName = propertyName;
}
public string PropertyName { get; private set; }
public bool Handled { get; set; }
public string ValidationError { get; set; }
}
モデルはIDelegatedValidation
、イベントを公開することによって実装され、
string IDataErrorInfo.this[string columnName]
{
get { return this.GetValidationError(columnName); }
}
private string GetValidationError(string propertyName)
{
var args = new DelegatedValidationEventArgs(propertyName);
this.OnValidationRequested(args);
return args.ValidationError;
}
protected virtual void OnValidationRequested(DelegatedValidationEventArgs args)
{
var handler = this.ValidationRequested;
if (handler == null) {
return;
}
foreach (EventHandler<DelegatedValidationEventArgs> target in handler.GetInvocationList()) {
target.Invoke(this, args);
if (args.Handled) {
break;
}
}
}
したがって、ワークフローは次のようになります。
- モデルがビューモデルによってラップされようとしているとき、検証を実行できる適切なエンティティがその
ValidationRequested
イベントにサブスクライブします。
- ビューはモデルにバインドされます。ある時点で検証がトリガーされます。
- モデルは を呼び出します
GetValidationError
。
- イベント ハンドラーは 1 つずつ呼び出されます。チェーンが停止するように、検証エラーを生成する最初のハンドラーが
args.ValidationError
とを設定します。args.Handled
true
- 検証エラーがビューに返されます。
ビューモデルがそのモデルが有効かどうかを知る必要がある場合 (たとえば、「保存」コマンドを有効/無効にするため)、このプロセスも利用する必要があるという点で、追加のひねりがあります。
/でできないことは本当にありません。なぜなら、それらをどのように実装するかは完全にあなた次第だからです。他の例については、後者のドキュメントのSilverlight バージョンを必ず確認してください。インターネット上には、このような役立つ資料もたくさんあります。IDataErrorInfo
INotifyDataErrorInfo