2

WPFではバインディングは非常に強力です。Numberプロパティ(null許容整数)があり、テキストボックスにバインドされているとします。

エラーがスローされたときに、プロパティに最後の正しい値があることに気付きました。

つまり、これらはプロセスです。

TEXTBOX: ""     PROPERTY: null
TEXTBOX: "2"    PROPERTY: 2
TEXTBOX: "2b"   PROPERTY: 2   <-- here is the problem, should be null instead 2(by the error)

エラーが発生したときにバインディングがnull値を設定する方法はありますか?

IDataErrorInfoを実装する必要があると言う人もいますが、インターフェイスはビジネスルールを検証するためのものだと思います。だから私はそれを使用することを好まないでしょう。

アップデート:

    <TextBox Text="{Binding Number, UpdateSourceTrigger=PropertyChanged,
        ValidatesOnExceptions=True, ValidatesOnDataErrors=True,
        NotifyOnValidationError=True, TargetNullValue={x:Static sys:String.Empty}}"
4

3 に答える 3

4

を使用してUpdateSourceTrigger=PropertyChangedいます。これは、ユーザーがキーを押すたびに、データがデータコンテキストに保存されることを意味します。

たとえば、ユーザーがを入力2すると、プロパティはに等しくなり"2"ます。ユーザーが入力するとb、に置き換えようとしますが、失敗するため、の元のプロパティは残ります。"2""2b""2"

を削除するUpdateSourceTriggerと、デフォルトの。に戻りますLostFocus。つまり、TextBoxがフォーカスを失ったときにのみプロパティが更新されます。

エラーが発生したときにプロパティを設定することもできますがnull、ユーザーが誤って間違ったキーを押した場合、TextBoxがクリアされるため、これを行うことはお勧めしません。

補足として、IDataErrorInfoビジネスルールの検証だけでなく、すべての検証に使用してください。WPFは、それと連携するように構築されています。私のモデルはそれを使用してデータが正しい長さやタイプなどであることを確認し、私のViewModelsはそれを使用してビジネスルールが守られていることを確認します

編集

私が持っている別の提案は、数値フィールドではなく、文字列値にバインドすることです。このようにして、値が変更されたときに、その値をIntにキャストして、キャストできない場合はエラーを返すことができます。

public class SomeObject : IDataErrorInfo
{
    public string SomeString { get; set; }
    public Int32? SomeNumber { get; set; }

    #region IDataErrorInfo Members

    public string Error
    {
        get { throw new NotImplementedException(); }
    }

    public string this[string columnName]
    {
        get
        {
            if (columnName == "SomeString")
            {
                int i;
                if (int.TryParse(SomeString, i))
                {
                    SomeNumber = i;
                }
                else
                {
                    SomeNumber = null;
                    return "Value is not a valid number";
                }
            }
            return null;
        }
    }

    #endregion
}
于 2012-01-26T16:43:21.653 に答える
1

その動作を取得する最も簡単な方法は、を使用してからにIValueConverter変換することだと思います。stringint?

public class NullableIntConverter : IValueConverter
{
    public static NullableIntConverter Instance = new NullableIntConverter();
    public void ConvertBack(object value, ...)
    {
        int intValue = 0;
        if (int.TryParse((string)value, out intValue))
            return intValue;

        return null;
    }

    public void Convert(object value, ...)
    {
        return value.ToString();
    }
}

次に、以下のようにバインディングでこれを指定できます(localコンバーターの名前空間にマップされます)。

<TextBox Text="{Binding Number, Converter="{x:Static local:NullableIntConverter.Instance}" ... />
于 2012-01-26T16:53:34.253 に答える
0

それはさらに強力になります。おそらく、インターフェイス/バインディング自体を介して検証のルートをたどる必要があります-WPFにはこれに対する組み込みのサポートがあり、その例は、MSDNのデータバインディングの概要にあります。

これを実装する例は次のようになります。

<...>
  <Binding.ValidationRules>
    <ExceptionValidationRule />
  </Binding.ValidationRules>
</...>

リンクされたドキュメントはバインディングのトピックについてかなりカバーしているので、関連するセクション「データ検証」からの抜粋を次に示します。

オブジェクトは、プロパティのValidationRule値が有効かどうかをチェックします。

ExceptionValidationRuleバインディングソースプロパティの更新中にスローされた例外をチェックします。前の例では、StartPriceは整数型です。ユーザーが整数に変換できない値を入力すると、例外がスローされ、バインディングが無効としてマークされます。ExceptionValidationRule明示的 に設定する代わりの構文 は、または オブジェクトのValidatesOnExceptionsプロパティをtrueに設定することです。BindingMultiBinding

于 2012-01-26T16:39:03.927 に答える