2

我试图找到一种优雅的方法来验证 WPF 中两个相关的 TextBox 值。

每个文本框的 Text 属性都绑定到我的类上的公共十进制属性,该类实现了用于 TwoWay 绑定的 INotifyPropertyChanged。

我想验证这两个值: BiggerValue >= SmallerValue >= 0

我已经使用 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

好吧,一个简单的hackish方法是为更大的值触发属性更改(这将导致刷新更大值的验证):

 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 回答