【问题标题】:Errors during value conversion值转换过程中的错误
【发布时间】:2010-02-25 23:46:25
【问题描述】:

为用户可编辑字段创建自定义 IValueConverter 时,Convert 实现通常相当简单。

ConvertBack 实现不是,因为(在没有明确的验证规则的情况下)它必须处理错误的用户输入(例如,在数字输入字段中键入“hi”)。

如果在转换过程中发生错误,似乎没有任何方法可以传达特定错误:

  • ConvertBack 不允许抛出异常(如果是,程序终止)。
  • 返回 ValidationError 没有任何作用。
  • 返回 DependencyProperty.UnsetValue(文档建议)会导致静默失败(即使您设置了错误模板,也不会向用户显示错误 UI)。
  • 返回未转换的原始值确实会导致显示错误 UI,但带有误导性的错误文本。

有谁知道处理这种事情的更好方法吗?

(注意:虽然定义自定义 ValidationRule 可以工作,但我认为这不是一个好的答案,因为它基本上必须复制转换逻辑才能发现错误。)

【问题讨论】:

    标签: wpf data-binding ivalueconverter


    【解决方案1】:

    您可以通过让验证规则的第一步是调用值转换器来确定它正在验证的值是否甚至可用,从而避免重复逻辑。

    当然,这会将您的验证规则与值转换器结合起来,除非您创建一个验证规则来搜索绑定以找出正在使用的值转换器。但是,如果您开始走这条路,那么您可能很快就会想到,就像许多人一样,“等等,如果我使用的是 MVVM,我在搞什么价值转换器?”

    编辑:

    如果您的 ViewModel 实现 IDataErrorInfo,这确实是唯一的生存方式,那么将值转换器挂钩到属性设置器相对简单,无需编写大量特定于属性的验证逻辑。

    在您的 ViewModel 类中,创建两个私有字段:

    Dictionary<string, string> Errors;
    Dictionary<string, IValueConverter>;
    

    在构造函数中创建它们(并填充第二个)。另外,对于IDataErrorInfo

    public string this[string columnName]
    {
        return Errors.ContainsKey(columnName)
           ? Errors[columnName]
           : null;
    }
    

    现在实现这样的方法:

    private bool ValidateProperty(string propertyName, Type targetType, object value)
    {
       Errors[propertyName] = null;
       if (!Converters.ContainsKey(propertyName))
       {
          return true;
       }
       try
       {
          object result = Converters[propertyName].ConvertBack(value, targetType, null, null)
          return true;
       }
       catch (Exception e)
       {
          Errors[propertyName] = e.Message;
          return false;
       }
    }
    

    现在你的属性设置器看起来像这样:

    public SomeType SomeProperty
    {
       set
       {
          if (ValidateProperty("SomeProperty", typeof(SomeType), value))
          {
             _SomeProperty = value;
          }
       }
    }
    

    【讨论】:

    • 我说的是我根本不想定义验证规则的情况。但是,是的,你是对的,你可以通过例如来避免这个问题。将 ViewModel 中所有面向用户的属性定义为字符串。但这似乎也有点极端,并且 also 无助于显示错误 UI,至少对于内置机制没有帮助。
    • 避免问题?一点也不。请参阅我的编辑。我概述的方法唯一搞砸的是在绑定对象上设置值转换器的能力。如果您使用的是 ViewModel,我想不出任何将值转换器附加到绑定的充分理由。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多