【问题标题】:WPF Handling converter errors and view model validationWPF 处理转换器错误和视图模型验证
【发布时间】:2017-08-17 21:34:37
【问题描述】:

我有一个 MVVM 应用程序,其中 INotifyDataErrorInfo 已全部设置并运行。目前,我能够验证我的所有属性并阻止用户继续进行,直到所有错误都得到处理。直到最近,当我们意识到我们的一些控件(文本框和标签组合用于显示数字和单位类型,即 100 毫米)时,一切都是阳光和玫瑰,当值被删除/退格时,没有显示红色错误装饰器。

控件上有一个转换器,它接收一个双精度并将其格式化为一个字符串以显示在文本框中。我们在 convertback 方法中发现了一个问题,如果 convertback 无法将字符串转换回双精度值,它会发送 Binding.DoNothing。我们将其更改为 DependencyProperty.UnsetValue 并认为一切正常,但这发现了一个更大的问题。

我们现在遇到的问题是没有通知视图模型转换器出现故障,我不知道该怎么做。当用户删除文本框内容时,转换器会使用空字符串调用。该空字符串不会解析为双精度。

我觉得我需要一种方法来通知 VM 转换失败,以便它可以将属性标记为 hasError。我没有看到任何方法可以做到这一点。这是 convertback 方法的代码。

        public object[] ConvertBack(object value, Type[] targetTypes, object           parameter, CultureInfo culture)
    {
        var strVal = value as string;
        double dblVal = 0;
        bool isSuccess = double.TryParse(strVal, out dblVal);

        if (_systemUnits == SystemUnits.Metric && isSuccess)
        {
            return new[] { dblVal, Binding.DoNothing };
        }
        else if (_systemUnits != SystemUnits.Metric && isSuccess)
        {
            return new[] { Binding.DoNothing, dblVal };
        }
        else
        {
            return new[] { Binding.DoNothing, Binding.DoNothing };
        }
    }
}

我不确定还有哪些其他代码是相关的,但如果您认为这会有所帮助,我愿意发布更多内容。谢谢你的时间!

【问题讨论】:

  • 我建议将属性转换为正在输入的值的实际类型(这是文本 - 是的,它是一个数字与单位名称的组合,但它只是文本)并验证虚拟机中的内容。便宜又快。其他选项包括创建一个结合数字和单位的特殊结构,定义静态“无效”值(如 double.NaN),并在用户输入无效时返回此值。更复杂,但它不会给你带来太多的震动。
  • @Will 这就是我害怕的。我遇到的几乎所有可行的解决方案都围绕着将属性更改为字符串。这对我来说非常不方便,但开始看起来没有更多选择了。

标签: c# wpf validation mvvm converter


【解决方案1】:

我觉得我需要一种方法来通知虚拟机

提供具有相关 VM 的最新实例的应用程序类的静态关闭,并在转换器中访问该静态并直接调用它的方法/属性以通知状态。

-或-

我建议您创建 computed 属性,这些属性与转换器的工作相同,以提供您提到的故障的估计值。

然后您可以访问计算的属性并执行您需要完成的过程。


这是一个示例属性IsOverLimit,如果需要,可以绑定它并通过其INotifyPropertyChange 等检查状态...

public bool IsOverLimit { get { return ThreadCreationLimit > 120 } }

 public uint ThreadCreationLimit
    {
        get { return _ThreadCreationLimit; }
        set
        {
            _ThreadCreationLimit = value;
            OnPropertyChanged("ThreadCreationLimit");
            OnPropertyChanged("IsOverLimit");
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-11
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    相关资源
    最近更新 更多