代码之家  ›  专栏  ›  技术社区  ›  egoodberry

在wpf中参数化validationrule

  •  1
  • egoodberry  · 技术社区  · 16 年前

    我只在WPF中刮掉了验证的表面,遇到了一个很常见的场景:我有一个文本框,其值需要根据上下文根据变量数据类型进行验证。例如,如果上下文的数据类型为“int”,则文本框只需要接受可以转换为int32的输入。

    我的第一个想法是从validationrule类继承并包含上下文,并在重写的validate函数内使用开关,但是我无法将任何内容绑定到它,因为它不是frameworkelement。

    有什么想法吗?

    2 回复  |  直到 16 年前
        1
  •  1
  •   Reed Copsey    16 年前

    你可以暴露 IDataErrorInfo . 这允许您使用复杂的逻辑进行数据验证。

        2
  •  1
  •   Ray Burns    16 年前

    就我个人而言,我不喜欢用IDataErrorInfo来处理这么简单的事情,因为它需要免费创建一个视图模型和大量不需要的额外代码。它应该如此简单:

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

    通过对该解决方案进行编码,您可以执行如下操作:

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

    通过在代码后面创建表达式作为lambda并用x:static引用它,您可以轻松地在没有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}
    

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

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