2012-01-26 5 views
1

バインディングはWPFで非常に強力です。 Numberプロパティ(nullable int)があり、テキストボックスにバインドされていると仮定します。エラーが発生した場合にプロパティに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を実装する必要があると言いましたが、ビジネス・ルールを検証するためのインターフェースだと思います。だから私はそれをユーザーに好まれません。

UPDATE:

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

テキストボックスをバインドするために使用しているコードを表示します。 – gabsferreira

+0

@devGabrielが更新されました! –

答えて

3

あなたはユーザーの種類は、あなたの財産が"2"に等しい、2、いつでもユーザーがキーを打つ、それはたとえば、あなたのデータコンテキスト

にデータを格納していることを意味し、UpdateSourceTrigger=PropertyChangedを使用しています。ユーザータイプはbで、"2""2b"に置き換えようとすると、元のプロパティーは"2"になります。

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

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

ビジネスルールの検証だけでなく、すべての検証にIDataErrorInfoを使用してください。 WPFはそれと共に動作するように作られています。私のモデルは正しい長さ、タイプなどがあり、そのデータを確認するためにそれを使用し、私のviewmodelsは、ビジネス・ルールが

編集

私はになりだろう代替案を踏襲されていることを確認するためにそれを使用します数値フィールドではなく文字列値にバインドします。このようにして値が変更されたら、Intにキャストしてキャストできない場合はエラーを返します。

私はその動作を取得する最も簡単な方法は、 stringから int?に変換し IValueConverterを使用することであると思い
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 
} 
+0

最後のステートメントは理にかなっています。だから、コンバーターのような便利な使い方だと思いますか? –

+0

@DarfZon何のために?コンバーターはあるデータ型を別のデータ型に変換するために使用されるため、私はあなたが何を達成しようとしているのか見当たりません。 – Rachel

+0

すべての権利、1つの疑い。この場合、Numberプロパティにnull値を手動で設定すると、textBoxが更新され、不正な値が表示されるため、IDataErrorInfoをどのように使用できますか? –

0

それはまだ、より強力な取得します。おそらく、インターフェイス/バインディング自体を介して検証ルートを実行する必要があります。WPFには、これの組み込みサポートがあります。その例は、Data Binding Overview over at MSDNにあります。

次のようにこれは行くことができるの実装例:

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

リンクドキュメントが関連するセクション「データの検証」からの抜粋ですので、ここで、結合のトピックに関するかなりカバー

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

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

+0

これがどのように私を助けることができるのか分かりません。 ValidateOnExceptions = True –

1

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}" ... /> 
+0

これを行うには、あなたのロジックを 'ConvertBack'に入れる必要があります。なぜなら、それはバインディングのバッキングプロパティを更新しようとするときに実行されるものなので、検証エラーが出るとは思わないからです。 – Rachel

+0

変換方向に@Rachelの良い点、あなたは正しい:それはもはや検証エラーが存在しないので、検証エラーを表示しません - プロパティに設定されたすべての値が有効です。 OPは検証メッセージについて言及していないので、私はこれがOKであると仮定しています –

+0

バインディングに 'ValidatesOnDataErrors =" True "'が含まれているので、検証に注意していると仮定していましたが、そうでない場合、無効な値が入力されたときにTextBoxのテキストがリセットされると、これはうまく動作します。おもう。私は確かにそれをテストしたいと思います。なぜなら、 'null'はデータオブジェクトの有効な値ですが、コンバーターのためではありません。 – Rachel

関連する問題