0

我目前正在使用 Entity Framework 5.0 和 WinForms。我想做的是在我的 POCO 类上设置验证,这样当我将它们数据绑定到表单字段时,我想通过 ErrorProvider 显示 UI 验证错误。我已经建立了一个基本的“ValidationEntity”类,它实现了 IDataErrorInfo 接口,并带有一些简单的验证方法供我的子类调用。在大多数情况下,验证字段长度、范围等似乎工作正常,通过 ErrorProvider 向用户显示错误。

但是,我似乎遇到了“ValidateRequiredField”方法的问题。如果我有一个具有不可为空的整数字段的类,并且用户碰巧在表单上删除了此值,则 ErrorProvider 会向最终用户显示一条消息,但消息是“输入字符串不是可识别的格式” . 现在我假设这是因为绑定到整数字段的表单正在尝试将空文本转换为整数,并且在将值发送到 POCO 类属性之前发生转换错误。我的问题是,解决这个问题的最佳方法是什么?

我猜我可能必须在表单内实现 TextBox 控件的验证方法,捕获空/空条目,并在错误提供程序上设置适当的错误消息。但是,我希望有一种方法可以让类处理空/空值并在 POCO 类中设置错误,以便它传播到 UI。最初我曾想过创建一个自定义 TypeConverter(例如 RequiredIntTypeConverter),但由于我从 ValidationEntity 类继承而遇到了问题,并且想不出添加错误的好方法。

下面是来自 ValidationEntity 类的示例以及来自 Company 类的片段。

验证实体.cs

public class ValidationEntity : IDataErrorInfo
{
    private readonly Dictionary<string, List<string>> errors = new Dictionary<string, List<string>>();

    string IDataErrorInfo.Error
    {
        get { return string.Empty; }
    }

    string IDataErrorInfo.this[string propertyName]
    {
        get
        {
            return (!errors.ContainsKey(propertyName) ? null : String.Join(Environment.NewLine, errors[propertyName]));
        }
    }

    public void AddError(string propertyName, string error, bool isWarning)
    {
        if (!errors.ContainsKey(propertyName))
        {
            errors[propertyName] = new List<string>();
        }

        if (!errors[propertyName].Contains(error))
        {
            if (isWarning)
            {
                errors[propertyName].Add(error);
            }
            else
            {
                errors[propertyName].Insert(0, error);
            }
        }
    }

    public void RemoveError(string propertyName, string error)
    {
        if (errors.ContainsKey(propertyName) &&
            errors[propertyName].Contains(error))
        {
            errors[propertyName].Remove(error);
            if (errors[propertyName].Count == 0)
            {
                errors.Remove(propertyName);
            }
        }
    }

    public void ValidateFieldLength(string propertyName, string value, int maxLength)
    {
        string errorMessage = string.Format("Text entered exceeds max length of {0} characters", maxLength);

        if (value != null)
        {
            if (value.Length > maxLength)
            {
                if (!errors.ContainsKey(propertyName))
                {
                    AddError(propertyName, errorMessage, false);
                }
            }
            else
            {
                RemoveError(propertyName, errorMessage);
            }
        }
        else
        {
            RemoveError(propertyName, errorMessage);
        }
    }

    public void ValidateRequiredField(string propertyName, string value)
    {
        string errorMessage = string.Format("{0} is required.", propertyName);

        if (string.IsNullOrWhiteSpace(value))
        {
            AddError(propertyName, errorMessage, false);
        }
        else
        {
            RemoveError(propertyName, errorMessage);
        }
    }        
}

公司.cs

public class Company : ValidationEntity
{
   private int companyID;
   private string companyName;

   public int CompanyID 
   {
     get { return this.companyID; }
     set 
     {
       OnCompanyIdChanging(value.ToString());
       this.companyID = value;
     } 
   }
   public string CompanyName
   {
     get { return this.companyName; }
     set 
     {
       OnCompanyNameChanging(value);
       this.companyName = value; 
     }
   }

   private void OnCompanyIdChanging(string value)
   {
     ValidateRequiredField("CompanyID", value);
   }

   private void OnCompanyNameChanging(string value)
   {
     ValidateRequiredField("CompanyName", value);
     ValidateFieldLength("CompanyName", value, 30);
   }
}

谢谢您的帮助。

4

1 回答 1

0

在对此进行了更多研究并测试了代码示例之后,我能够找到解决此特定项目的方法。不可为空的整数转换需要自定义 TypeConverter。我能够在此处找到信息 并最终使用以下 TypeConverter 来测试“必需的整数”:

public class RequiredIntConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string))
        {
            return true;
        }
        return base.CanConvertFrom(context, sourceType);
    }

    [System.Diagnostics.DebuggerNonUserCode]
    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
        {
            throw new ApplicationException("This field requires an integer value and cannot be blank.");
        }
        int result = 0;
        if (!int.TryParse(value.ToString(), out result))
        {
            throw new ApplicationException("The value could not be parsed as a valid integer data type.");
        }
        else
        {
            return result;
        }
    }
}

当我最初从上面的链接测试代码时,当我尝试抛出 ApplicationException 时,我的调试器不断中断。认为这是我的代码中的一个错误,我对如何使用 TypeConverter 感到困惑。但是,我发现以下帖子描述了如何禁止调试器中断方法。

我仍然有点不确定为什么它会在这个 ApplicationException 上中断,以及 ErrorProvider 如何知道显示底层异常。如果有人能指出我在这方面的一些额外资源,将不胜感激。

祝你有美好的一天。

于 2013-01-24T17:07:04.210 回答