MVVM – validation

我们试图在mvvm中确定在业务逻辑或模型中进行validation的validation。 我在业务逻辑中实现了exception类型的validation – 可以在这里找到简化的图表: 替代文字

如果我们有很多输入彼此独立,那么没有问题,抛出exception,文本框会抓住它,标记为每个错误输入的边框为红色。 但是,当我们有依赖值时,我们就遇到了麻烦。 例如

  • 模型中的Value1和Value2必须不一样,所以我们在每个查找equals值的函数中都有一个validate函数,如果发生这种情况则抛出exception

  • 现在,如果我们将Value1设置为0而将Value2设置为1,一切都很好

  • Value1在GUI中设置为1 – >这个被标记为红色,因为未触发其他值的validation,因此GUI中的Value2未标记为错误

  • 在GUI中将Value2设置为2,现在我们已达到有效状态,但只有Value2得到validation,因此Value1仍被标记为有错

有没有一个共同的模式来解决这个问题? 我们不希望在两个文本框之间的GUI中引入依赖关系,因为此逻辑应仅存在于业务逻辑层中。

除了通过exception实现validation之外,还可以实现IDataErrorInfo接口,但问题仍然存在,没有办法强制依赖值再次validation它们的值,至少没有我能看到:)

任何帮助表示赞赏

欢呼,曼尼


[清理,删除不必要的步骤]


15.11.2010 – 第2部分

好的,在这里重新思考,我们将继续使用businesslogic层。 这是我们当前计划的配置: 替代文字 (图像在这里缩小了一点,请在单独的窗口打开以显示全尺寸)一切都或多或少都清楚,除了如果数据模型如何通知不同编辑器的所有视图模型/模型克隆在业务逻辑下变了。 一种方法是跟踪创建它们的业务逻辑中的克隆模型。 使用业务逻辑commit()更改数据模型时,可以将所有其他已注册的模型克隆通知更改并进一步传播它们。 或者,业务逻辑可以发布所有视图模型订阅的事件,以便他们也可以获得更改 – 任何人都可以给我一个提示更好的提示吗?

再次感谢您的帮助,对不起,我是如此精神错乱;)

您可以考虑使用System.ComponentModel.IDataErrorInfo接口。 这个非常方便的界面使您能够:

  • 以符合MVVM的方式进行validation
  • 为任何特定字段进行自定义validation(如果需要,validation可以检查多个值)
  • 将UI绑定到validation错误

您在viewmodel上实现IDataErrorInfo(甚至在视图模型库中实际虚拟,并在派生视图模型中覆盖它)。 由于数据绑定的性质,我需要检查的值都在视图模型中,我可以测试它们的任何组合。 当然,您仍然在业务层中进行validation,但您不再需要访问业务层(或模型),只是为了进行一些validation。

以下是来自(WPF)屏幕的快速示例,该屏幕收集了一些用户详细信息并对其进行了基本validation:

C#代码:

#region IDataErrorInfo Members ///  /// Gets an error message indicating what is wrong with this object. ///  ///  /// An error message indicating what is wrong with this object. The default is an empty string (""). public override string Error { get { return this["UserCode"] + this["UserName"] + this["Password"] + this["ConfirmedPassword"] + this["EmailAddress"]; } } ///  /// Gets the  with the specified column name. ///  ///  public override string this[string columnName] { get { switch (columnName) { case "UserCode": if (!string.IsNullOrEmpty(UserCode) && UserCode.Length > 20) return "User Code must be less than or equal to 20 characters"; break; case "UserName": if (!string.IsNullOrEmpty(UserCode) && UserCode.Length > 60) return "User Name must be less than or equal to 60 characters"; break; case "Password": if (!string.IsNullOrEmpty(Password) && Password.Length > 60) return "Password must be less than or equal to 60 characters"; break; case "ConfirmedPassword": if (Password != ConfirmedPassword) return Properties.Resources.ErrorMessage_Password_ConfirmedPasswordDoesntMatch; break; case "EmailAddress": if (!string.IsNullOrEmpty(EmailAddress)) { var r = new Regex(_emailRegex); if (!r.IsMatch(EmailAddress)) return Properties.Resources.ErrorMessage_Email_InvalidEmailFormat; } break; } return string.Empty; } } #endregion 

这是页面上两个文本框的XAML标记(特别注意Text绑定中的ValidatesOnDataErrorsValidatesOnExceptions属性):

   

有没有一个共同的模式来解决这个问题? 我们不希望在两个文本框之间的GUI中引入依赖关系,因为此逻辑应仅存在于业务逻辑层中。

  1. 由于条件“模型中的Value1和Value2必须不相同”, Value1Value2是相互依赖的。

  2. 这意味着当Value2发生变化时, Value1也会发生变化,反之亦然! 实际上,当Value2更改时, Value1validation结果会更改,但这接近前一个语句。

  3. Value1Value2 setter必须通知Value1Value2属性更改。

  4. 视图必须重新读取并重新validation这两个值并清除错误标记。

  5. 如果WPF发现通知事件已被引发但实际上没有更改,则不确定WPF是否会这样做。