【问题标题】:Accessing Validation.HasError from ViewModel with WPF MVVM使用 WPF MVVM 从 ViewModel 访问 Validation.HasError
【发布时间】:2013-06-27 21:26:59
【问题描述】:

所以我承认我已经搜索了一些,但找不到我正在寻找的答案。我觉得我可能在搜索错误的标签。

我有一个视图,它有一个文本框,它通过实现 ValidationRule 的验证类应用一些验证。我对其进行了正确验证,并且我的文本框适当地突出显示/工具提示。

现在我已经对其进行了验证,我想也许我可以在 Validation.HasError = true 时阻止启用提交按钮。我的 ViewModel 不知道这个 ValidationRule,也不知道 ValidationRule 返回了 false,“一些错误消息”。现在这样做的正确方法是什么?我更愿意将验证保留在我的“模型”之外,并将其留在 ValidationRule 类中。

我可以创建一个布尔属性“HasValidationError”并在 Validation.HasError 设置为 true 时将其设置为 true 吗?

【问题讨论】:

    标签: c# wpf validation mvvm


    【解决方案1】:

    我建议您将验证逻辑放在 ViewModel 中,并使用 IDataErrorInfo 来处理 UI 验证。在我们的应用程序中,验证是一项独立的服务。

    好处是您可以完全控制处理 ViewModel 级别错误和属性级别错误。即使您找到了一种将 ViewModel 的 hasValidationError 与所有控件的 ValidationRule 相关联的方法,仍然存在一个潜在问题,即您的 ViewModel 的错误仅取决于 UI 而不是它的真实逻辑,这意味着,在您的 UI 验证 ViewModel 之前,您永远无法判断 ViewModel 是否是正确的。

    【讨论】:

      【解决方案2】:

      我同意 Bill Zhang 的观点,当您使用 MVVM 模式时,验证逻辑应该驻留在视图模型中。原因很多,但最主要的原因是视图的验证应该是可测试的,而且测试视图模型比测试视图容易得多。

      讲完了,让我们看一些代码。你可以看看我的文章 Zip My Code on CodeProject 我在视图模型中验证。我可以像这样注册一个验证器:

      class ExcludeItemDialogViewModel : DialogViewModelBase
      {
        public ExcludeItemDialogViewModel(string title, string excludeItem)
        {
          AddValidator(() => ExcludedItem, new NotNullOrEmptyValidationRule());
      
          // Code removed for clarity...
        }
      
        // Code removed for clarity...
      }
      

      调用 AddValidator 方法将为视图模型中的特定属性注册一个验证器,在本例中为 ExcludedItem。验证规则如下所示:

      class NotNullOrEmptyValidationRule : IValidationRule
      {
        public string ErrorMessage { get; private set; }
      
        public bool Validate(object value)
        {
          string valueText = value as string;
      
          if (string.IsNullOrEmpty(valueText))
          {
            ErrorMessage = Resources.NotNullValidationRule_Error;
            return false;
          }
      
          ErrorMessage = string.Empty;
          return true;
        } 
      }
      

      【讨论】:

      • 所以我查看了您的该项目的源代码。看起来所有验证都是由 ViewModel 单独处理的,这是否意味着 View 永远不会意识到验证错误?最好利用视图的内置 ValidationError 东西(就像文本框以红色突出显示,在框的左上角有一个标记指示错误消息等)。这不能完成还是我错过了代码中的某些内容?
      • 视图知道验证错误,因为视图模型实现了 IDataErrorInfo 接口。然后它接受视图模型负责在发生验证错误时向视图报告。
      猜你喜欢
      • 2017-11-24
      • 2013-07-30
      • 2018-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多