開発記その 6 - 複数のプロパティに対応するエラーをグループ化

さて、http://d.hatena.ne.jp/k_maru/20100809/1281355604 で書いたようにバリデーションが微妙すぎたので、少し対応した。

まずは、ログインエラー時のマークを、新しい値が入力されたときに消す対応。

ViewModelBase ではエラーを Dictionary> でプロパティごとにメッセージを文字列で持ってたんやけど、以下のようなそれ用のクラスに変更。

private class ValidationErrorInfo {

  public ValidationErrorInfo(string propertyName, string message, 
      bool isPropertyValidationError, string[] groupProperties) {
    this.PropertyName = propertyName;
    this.Message = message;
    this.IsPropertyValidationError = isPropertyValidationError;
    this.GroupProperties = groupProperties;
  }

  public string PropertyName { get; private set; }

  public string Message { get; private set; }

  public bool IsPropertyValidationError { get; private set; }

  public string[] GroupProperties { get; private set; }

  public override string ToString() {
    return this.Message;
  }
}

ポイントはコンストラクタの最後の引数の groupProperties か。 AddError メソッドで自前でエラーが設定されたときに、設定するプロパティが複数指定されていたらそれをグループとみなして、保存しておく。

protected void AddError(string message, params string[] propertyNames) {
  if (propertyNames == null || propertyNames.Length == 0) {
    return;
  }
  foreach (string propertyName in propertyNames) {
    List<ValidationErrorInfo> messages = GetErrorsList(propertyName);
    if (messages.FirstOrDefault(m => m.Message == message) == null) {
      messages.Add(new ValidationErrorInfo(propertyName, message, false, propertyNames));
      this.OnErrorChanged(propertyName);
    }
  }
}

で、プロパティのバリデーション時にグリグリ回してグループに同じメッセージがあったら消すって流れです。


これで、たとえばログインエラーが出ている状態(ユーザー名とパスワードのテキストボックス両方にマークされている状態)で、ユーザー名を変更するとパスワードの方のエラー表示も削除されます。

ちょっとコードがグリグリとループ書いててもっさいので、どこかで修正しないとと思ってるんですが、いいアイデアが浮かばないので保留。

ValidationSummary は相変わらず 2 行表示されてますが、こいつも保留ですね。最終的に使わない方向に高確率でなりそうですが・・・。


※今回のチェックイン
http://moneybook.codeplex.com/SourceControl/changeset/changes/54103