ErrorProvider-输入字符串的格式不是可识别的C#

ErrorProvider-输入字符串的格式不是可识别的C#,c#,winforms,entity-framework,data-binding,entity-framework-5,C#,Winforms,Entity Framework,Data Binding,Entity Framework 5,我目前正在使用EntityFramework5.0和WinForms。我想做的是在我的POCO类上设置验证,这样当我将它们数据绑定到表单字段时,我想通过ErrorProvider显示UI验证错误。我已经建立了一个基本的“ValidationEntity”类,该类使用一些简单的验证方法实现IDataErrorInfo接口,供我的子类调用。在大多数情况下,验证字段长度、范围等。。似乎可以通过ErrorProvider向用户显示错误 然而,我似乎遇到了“ValidateRequiredField”方法

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

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

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

下面是ValidationEntity类的一个示例以及Company类的一个片段

ValidationEntity.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);
        }
    }        
}
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);
   }
}

感谢您的帮助。

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

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

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


祝您度过愉快的一天。

代码中没有出现异常。以下内容可能有助于说明:将DbContext.companys绑定到表单内的BindingSource,将ErrorProvider的数据源设置为BindingSource,将表单文本框上的DataBindings属性设置为CompanyID、CompanyName属性。如果您导航到具有公司ID的公司,然后尝试删除该公司ID,而不是在ErrorProvider中接收“CompanyID is required”,您将收到“输入字符串未采用可识别的格式”。
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;
        }
    }
}