WPF中的参数验证规则

时间:2009-11-18 16:37:04

标签: wpf validation

我只是在WPF中删除了验证的表面并且遇到了一个可能相当常见的场景:我有一个TextBox,其值需要针对可变数据类型进行验证,具体取决于上下文。例如,如果上下文的数据类型是“int”,则TextBox只需要接受可以转换为Int32的输入。

我的第一个想法是继承ValidationRule类并包含上下文并在重写的Validate函数中使用切换,但我无法绑定任何内容,因为它不是FrameworkElement。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您可以公开IDataErrorInfo。这使您可以使用复杂的逻辑进行数据验证。

答案 1 :(得分:1)

就我个人而言,我不喜欢将IDataErrorInfo用于这么简单的事情,因为它需要无偿创建一个ViewModel和许多额外的代码,而这些代码都不需要。应该这么简单:

我有一个标记扩展,允许我使用指定为C#表达式的自定义验证代码创建绑定。除了C#解析器之外,这非常简单:只需通过构造一个使用转换器并构建适当验证结构的MultiBinding来实现ProvideValue()。这允许验证表达式除了要验证的值之外还接收包含DataContext和用户指定的Binding对象。

使用此解决方案编码,您可以执行以下操作:

BoundProperty="{my:ValidatedBinding
  Path=SomeProperty,
  ValidationExpression = context is TextBox ? (int)value>3 : (int)value<7,
  Mode=TwoWay,
  Converter=...

通过在代码隐藏中创建表达式作为lambda并使用x引用它,您可以轻松地在没有C#解析器的情况下调整我的解决方案:静态:

public static reaonly Expression myValidatorExpression =
  (object value, object context, BindingBase binding) =>
    context is TextBox ? (int)value>3 : (int)value<7;

...
  ValidationExpression={x:Static local:MyClass.myValidatorExpression}

总的来说,我发现这种技术比使用ViewModel更容易,更清晰。当需要进行复杂的转换时,我仍然使用ViewModels,否则只需将纯XAML直接转换为业务对象层。

请注意,此方法假定您的业务对象层不依赖于任何特定的后端存储布局(例如SQL表结构)。如果是这样,更改后端存储将需要更改我的UI,这也是不可取的,因此从这个角度来看,ViewModel是可取的。但如果没有,我总是喜欢保持简单,只使用直接的XAML。