【问题标题】:Data type validation alongside IDataErrorInfoIDataErrorInfo 旁边的数据类型验证
【发布时间】:2016-04-18 17:37:52
【问题描述】:

我刚刚开始向 WPF MVVM 项目添加一些验证。这种范式中的验证对我来说是新的,但它似乎相当简单:

public partial class Price : IDataErrorInfo
{
    public double Cost { get; set; }

    public string Error
    {
        get { throw new NotImplementedException(); }
    }

    string IDataErrorInfo.this[string columnName]
    {
        get
        {
            string message = null;
            if (columnName == "Cost" && this.Cost > 10000.00)
            {
                message = "This price is high enough to require confirmation";
            }
            return message;
        }
    }
}

成本属性在 ViewModel 中绑定到一个文本框,允许用户输入他们自己的数据。在实现 IDataErrorInfo 之前,用户在此框中键入文本会导致它以红色突出显示,但没有显示错误消息。这被认为是足够的警告。

现在,在我已经实现的样式上输入文本以显示错误,这很好。另外还有一条消息:无法转换值“[文本]”,但这对用户来说有点深奥。真正的问题是,如果有人输入大于 10000.00 的数字并触发自定义消息,然后删除该值并将其替换为文本,则旧的错误消息将保留在原处。

有了断点,发生了什么就很清楚了:因为 View 期望这是一个 double,它甚至从来没有检查过 IDataErrorInfo 是否已经改变。如何清除错误消息并将其替换为更有意义的内容?我无法解析 Cost,因为当然,它是双精度的,所以如果有人输入文本,它甚至永远不会被设置?

【问题讨论】:

  • 为此,您可以将文本框绑定到字符串属性,然后再将其解析为双精度。另一种选择是将输入限制为数值:stackoverflow.com/questions/1268552/…
  • 顺便说一句:如果 Cost 是“金钱”值,您可能需要考虑使用 Decimal 而不是 Double:stackoverflow.com/questions/693372/…
  • @jHilscher 刚试过,谢谢你的建议。问题是当你解析它时,值“1234”。解析失败 - 如此有效地阻止用户输入小数。稍加努力,这种方法可能会奏效,但如果可能的话,我宁愿使用 IDataErrorInfo。
  • 您可以将它与 IDataErrorInfo 结合起来并验证字符串。

标签: c# wpf mvvm idataerrorinfo


【解决方案1】:
 public class Price : IDataErrorInfo
{
    private double _costDouble;

    private string _cost;
    public string Cost
    {
        get {
            return _cost;
        } 
        set {
                _cost = value;
                double.TryParse(value, out _costDouble);
            } 
    }

    public string Error
    {
        get { throw new NotImplementedException(); }
    }

    string IDataErrorInfo.this[string columnName]
    {
        get
        {
            string message = null;
            if (columnName == "Cost")
            {
                double doubleVal;
                if (double.TryParse(this.Cost, out doubleVal))
                {
                    if (doubleVal > 1000.0)
                        message = "This price is high enough to require confirmation";
                }
                else {
                    message = "Format error";
                }
            }
            return message;
        }
    }
}

您最终必须使用字符串属性来绑定到文本框。

奖励:您现在可以验证用户是否输入了数值。

【讨论】:

    【解决方案2】:

    最好将Cost 属性的类型更改为字符串并尝试在验证回调中解析它。使用这种方法无需在 XAML 中使用任何 ValidationRules,只需 IDataErrorInfo。

    更多信息可以在这篇文章中找到:https://joshsmithonwpf.wordpress.com/2008/11/14/using-a-viewmodel-to-provide-meaningful-validation-error-messages/ Josh Smith。

    干杯

    【讨论】:

      猜你喜欢
      • 2016-05-07
      • 1970-01-01
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多