2

绑定在 WPF 中非常强大。假设我们有一个 Number 属性(可为 null 的 int)并绑定到一个文本框。

我意识到当它引发错误时,该属性具有最后一个正确的值。

我的意思是这些是过程:

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

有没有办法在绑定产生错误时设置空值?

有人告诉我我需要实现 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 是为使用它而构建的。我的模型使用它来验证他们的数据是正确的长度、类型等,我的视图模型使用它来验证是否遵循了业务规则

编辑

我的替代建议是绑定到字符串值,而不是数字字段。这样,当值发生变化时,您可以尝试将其强制转换为 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

我认为获得该行为的最简单方法是使用 anIValueConverter转换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值是否有效。

AExceptionValidationRule检查绑定源属性更新期间引发的异常。在前面的示例中,StartPrice 是整数类型。当用户输入一个无法转换为整数的值时,会抛出异常,导致绑定被标记为无效。ExceptionValidationRule显式 设置的另一种语法 是将您的或 对象ValidatesOnExceptions上的属性设置为 true 。BindingMultiBinding

于 2012-01-26T16:39:03.927 回答