0

私のフォームは、実装するオブジェクトにバインドされてIDataErrorInfoおり、フィールドごとに正しく検証されます。Errorのプロパティではなく、フォームのフィールドに基づいて結果を要約する何らかの方法が必要ですIDataErrorInfo。どういうわけかコントロールをループして、どのコントロールが無効かを判断する方法はありますか?

ありがとう!

4

2 に答える 2

0

これが私が提案することですが、「フォームのフィールドに基づいて結果を要約する」という意味がよくわかりません。私が提案していることは、あなたがやりたいことを何でもできるようにするべきだと思います。

特定のコントロールではなく、IDataErrorInfo を使用してオブジェクトとそのフィールドを操作することをお勧めします。すべての ViewModels (表示しているデータ) の基本クラスで、IDataErrorInfo を次のように実装します。

private Dictionary<string, string> errors = new Dictionary<string, string>();

public virtual string Error
{
    get { return String.Join(Environment.NewLine, errors); }
}

public bool HasErrors
{
    get
    {
        return errors.Count > 0;
    }
}

public string this[string propertyName]
{
    get
    {
        string result;
        errors.TryGetValue(propertyName, out result);
        return result;
    }
}

protected void SetError<T>(Expression<Func<T>> prop, String error)
{
    String propertyName = PropertySupport.ExtractPropertyName(prop);

    if (error == null)
        errors.Remove(propertyName);
    else
        errors[propertyName] = error;

    OnHasErrorsChanged();
}

protected string GetError<T>(Expression<Func<T>> prop, String error)
{
    String propertyName = PropertySupport.ExtractPropertyName(prop);

    String s;
    errors.TryGetValue(propertyName, out s);
    return s;
}

protected virtual void OnHasErrorsChanged()
{

}

次に、検証エラーを格納するデータ バインディングで使用する次のようなプロパティを実装できます。

public String ProjectName
{
    get { return projectName; }
    set
    {
        if (value != projectName)
        {
            projectName = value;
            SetError(() => ProjectName, ValidateProjectName());
            RaisePropertyChanged(() => this.ProjectName);
        }
    }
}

フィールドのエラーを取得するには

String error = GetError( () => SomeField ); // OR
String error = this["SomeField"];

または、 Errors を使用してすべてのエラーのリストを取得できます


この例では、私が実装した SetError とPrism のNotificationObjectクラスに実装されたRaisePropertyChangedを使用しています。NotificationObjectクラスは単に INotifyPropertyChanged を実装しラムダ式を渡す RaisePropertyChanged と呼ばれる PropertyChanged("PropertyName") のリファクタセーフ バージョンを提供します。

Prism を使用しない場合は、単純に SetError に 2 つの文字列 (プロパティ、エラー) を持たせることができます。または、PropertySupport.ExtractPropertyName メソッドを自分で実装して、このリファクタセーフ バージョンを利用します。

例えば

public static class PropertySupport
{
    public static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpresssion)
    {
        if (propertyExpresssion == null)
        {
            throw new ArgumentNullException("propertyExpression");
        }

        var memberExpression = propertyExpresssion.Body as MemberExpression;
        if (memberExpression == null)
        {
            throw new ArgumentException("The expression is not a member access expression.", "propertyExpression");
        }

        var property = memberExpression.Member as PropertyInfo;
        if (property == null)
        {
            throw new ArgumentException("The member access expression does not access a property.", "propertyExpression");
        }

        var getMethod = property.GetGetMethod(true);
        if (getMethod.IsStatic)
        {
            throw new ArgumentException("The referenced property is a static property.", "propertyExpression");
        }

        return memberExpression.Member.Name;
    }
}
于 2013-05-16T14:20:09.187 に答える
0

この MVVM の方法を実行するには、最初に ViewModel ですべてのエラーを収集する必要があります。つまり、どのすべてのプロパティが false として検証されているかを見つけ、そのようなすべてのプロパティのエラー テキストをコレクション/リスト/配列に追加し、このコレクション/リスト/配列を使用して、UI のエラー サマリーにエラーを表示します。

于 2013-05-16T06:26:50.390 に答える