2

WPFで2つの関連するTextBox値を検証するための洗練された方法を見つけようとしています。

各テキストボックスのTextプロパティは、TwoWayバインディングのINotifyPropertyChangedを実装するクラスのパブリックdecimalプロパティにバインドされます。

BiggerValue> = SmallerValue>=0のように2つの値を検証したい

IDataErrorInfoと文字列インデクサーを使用して、これらの条件に対して個別に検証する各値を取得することに成功しました。

私の問題は次のとおりです。ユーザーは両方の値を減らすことを意図しており、BiggerValueで開始するため、現在はSmallerValueよりも小さくなっています。BiggerValue TextBoxの検証は失敗します(値は保存されますが)。次に、ユーザーはSmallerValueに移動し、新しいBiggerValueよりも小さく設定します。これで両方の値が再び有効になりますが、BiggerValueテキストボックスにその(変更されていない)値が有効になったことを自動的に反映させるにはどうすればよいですか?

テキストボックスでLostFocus()のようなイベントハンドラーを確認する必要がありますか、それともプロパティセッターにこのようなものを追加して強制的に更新する必要がありますか?

biggerValueTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
smallerValueTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();

私の完全なコードは以下の通りです。どういうわけか、この単純な問題では、すべてがかなり不格好で複雑すぎるように感じます。WPFの初心者(これは2日目です)として、私のアプローチについてのコメントは、どんなに過激であっても、ありがたいことに受け取られます。

XAML:

<TextBox x:Name="biggerValueTextBox"
         Text="{Binding Path=BiggerValue,
                        Mode=TwoWay,
                        ValidatesOnDataErrors=True,
                        ValidatesOnExceptions=True}" />
<TextBox x:Name="smallerValueTextBox"
         Text="{Binding Path=SmallerValue,
                        Mode=TwoWay,
                        ValidatesOnDataErrors=True,
                        ValidatesOnExceptions=True}" />

C#:

public partial class MyClass : UserControl,
    INotifyPropertyChanged, IDataErrorInfo
{
    // properties
    private decimal biggerValue = 100;
    public decimal BiggerValue
    {
        get
        {
            return biggerValue;
        }
        set
        {
            biggerValue = value;
            OnPropertyChanged("BiggerValue");
        }
    }
    private decimal smallerValue = 80;
    public decimal SmallerValue
    {
        get
        {
            return smallerValue;
        }
        set
        {
            smallerValue = value;
            OnPropertyChanged("SmallerValue");
        }
    }

    // error handling
    public string this[string propertyName]
    {
        get
        {
            if (propertyName == "BiggerValue")
            {
                if (BiggerValue < SmallerValue)
                    return "BiggerValue is less than SmallerValue.";
                if (BiggerValue < 0)
                    return "BiggerValue is less than zero.";
            }
            if (propertyName == "SmallerValue")
            {
                if (BiggerValue < SmallerValue)
                    return "BiggerValue is less than SmallerValue.";
                if (SmallerValue < 0)
                    return "SmallerValue is less than zero.";
            }
            return null;
        }
    }
    // WPF doesn't use this property.
    public string Error { get { return null; } }

    // event handler for data binding
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
4

1 に答える 1

1

まあ、簡単なハックの方法は、biggerValueに対しても変更されたプロパティを起動することです(これにより、より大きな値の検証が更新されます):

 public decimal SmallerValue
    {
        get
        {
            return smallerValue;
        }
        set
        {
            bool fireForBigger = smallerValue > biggerValue && smallerValue < value;
            smallerValue = value;
            OnPropertyChanged("SmallerValue");
            if (fireForBigger)
            {
                OnPropertyChanged("BiggerValue");
            }
        }
    }

ただし、より確実な解決策は、カスタム検証ルールを作成し、それをすべて独自に設定することです:http: //msdn.microsoft.com/en-us/library/system.windows.data.binding.validationrules.aspx

于 2010-01-15T04:33:32.270 に答える