13

以下に示すように、IDataErrorInfoを使用してモデルクラスを検証しようとしています。

//Validators
public string this[string propertyName] {
    get {
        string error = null;

        if (propertyName == "Name") {
            error = ValidateName(); 
        }
        return error;
    }
}

ビューが最初にロードされたときにすでに検証エラーが含まれていることを除いて、これは正常に機能します。ビューが最初にロードされるときに検証エラーを無視/抑制することは可能ですか?また、ビューが読み込まれたとき、およびユーザーがモデルプロパティのデータ入力を開始する前に、エラーを表示するのが一般的な方法ですか。

よろしく、ニルヴァン。

編集: これは私がIDataErrorInfoを設定する方法です。

<TextBox Text="{Binding Name, ValidatesOnDataErrors=True}" Grid.Row="1" Grid.Column="1" />
4

4 に答える 4

3

私は次のアプローチを取りました、そしてそれはうまくいきます。基本的に、オブジェクトがインスタンス化されたばかりで、ユーザーがまだテキストを入力していない場合でも、モデルはエラーを正しく記録し、辞書にリストする必要があります。そのため、モデルコードまたはIDataErrorInfo検証コードを変更しませんでした。代わりに、最初にValidation.Error Templateプロパティを{x:Null}に設定しました。次に、Validation.Errorテンプレートを使用しているものに戻すTextBoxのLostFocusイベントを接続するコードがあります。テンプレートを交換し、LostFocusイベントハンドラーをアプリケーション内のすべてのTextBoxにアタッチするために、いくつかの依存関係プロパティを使用しました。これが私が使用したコードです。

依存関係のプロパティとLostFocusコード:

    public static DependencyProperty IsDirtyEnabledProperty = DependencyProperty.RegisterAttached("IsDirtyEnabled",
             typeof(bool), typeof(TextBoxExtensions), new PropertyMetadata(false, OnIsDirtyEnabledChanged));
    public static bool GetIsDirtyEnabled(TextBox target) {return (bool)target.GetValue(IsDirtyEnabledProperty);}
    public static void SetIsDirtyEnabled(TextBox target, bool value) {target.SetValue(IsDirtyEnabledProperty, value);}

    public static DependencyProperty ShowErrorTemplateProperty = DependencyProperty.RegisterAttached("ShowErrorTemplate",
             typeof(bool), typeof(TextBoxExtensions), new PropertyMetadata(false));
    public static bool GetShowErrorTemplate(TextBox target) { return (bool)target.GetValue(ShowErrorTemplateProperty); }
    public static void SetShowErrorTemplate(TextBox target, bool value) { target.SetValue(ShowErrorTemplateProperty, value); }

    private static void OnIsDirtyEnabledChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args) {
        TextBox textBox = (TextBox)dependencyObject;
        if (textBox != null) {
            textBox.LostFocus += (s, e) => {
                if ((bool) textBox.GetValue(ShowErrorTemplateProperty) == false) {
                    textBox.SetValue(ShowErrorTemplateProperty, true);
                }
            };
        }
    }

IsDirtyEnabled依存関係プロパティがtrueに設定されている場合、コールバックを使用してTextBoxのLostFocusイベントをハンドラーにアタッチします。ハンドラーは、ShowErrorTemplate添付プロパティをtrueに変更するだけです。これにより、TextBoxのスタイルトリガーがトリガーされ、TextBoxがフォーカスを失ったときにValidation.Errorテンプレートが表示されます。

テキストボックススタイル:

<Style TargetType="{x:Type TextBox}">
    <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ValidationErrorTemplate}"/>
    <Setter Property="gs:TextBoxExtensions.IsDirtyEnabled" Value="True" />
    <Style.Triggers>
        <Trigger Property="gs:TextBoxExtensions.ShowErrorTemplate" Value="false">
            <Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
        </Trigger>
    </Style.Triggers>
</Style>

これは単純なことにはコードが多すぎるように思えるかもしれませんが、使用しているすべてのテキストボックスに対して1回だけ実行する必要があります。

よろしく、ニルヴァン。

于 2012-04-19T12:57:47.553 に答える
2

ビューが表示された後、データコンテキストを設定してみてください。

私の場合、これは役に立ちました。

于 2012-08-06T07:30:01.163 に答える
1

ValidateName()メソッドでルールを設定します。ビューにエラーが表示されるだけです:)名前は必須フィールドであり、ユーザーが入力する必要があることをお勧めしますが、ビューが最初に読み込まれるときに赤い境界線が気に入らないのですか?

検証には2つの異なるコントロールテンプレートを使用します。errortemplate通常の1つと必須フィールドの1つ(赤*)

それが前回のやり方です。

于 2012-04-17T13:18:47.247 に答える
1

getで例外をスローしていますか?

public string Name
{
    get { return _name; }
    set
    {
        _name = value;
        if (String.IsNullOrEmpty(value))
        {
            throw new ApplicationException("Customer name is mandatory.");
        }
    }
}
于 2012-04-17T12:19:01.800 に答える