0

我目前正在使用實體框架5.0和WinForms。我想要做的是在我的POCO類上進行設置驗證,這樣當我將它們綁定到表單字段時,我想通過ErrorProvider顯示UI驗證錯誤。我已經建立了一個基礎「ValidationEntity」類,它實現了IDataErrorInfo接口和一些簡單的驗證方法,供我的子類調用。大多數情況下,驗證字段長度,範圍等等似乎可以正常工作,通過ErrorProvider向用戶顯示錯誤。ErrorProvider - 輸入字符串未採用可識別的格式C#

但是,我似乎遇到了「ValidateRequiredField」方法的問題。如果我有一個具有不可空的整數字段的類,並且用戶恰好在表單上刪除此值,則ErrorProvider確實會向最終用戶顯示一條消息,但消息是「輸入字符串未採用可識別的格式」 。現在我假設這是因爲綁定到整數字段的表單試圖將空文本轉換爲整數,並且在將值發送到POCO類屬性之前發生轉換錯誤。我的問題是,解決這個問題的最佳方法是什麼?

我猜我可能不得不在表單中實現TextBox控件的驗證方法,捕獲空/空項,並在錯誤提供程序上設置相應的錯誤消息。不過,我希望能夠讓類處理空/空值,並在POCO類中設置錯誤,以便傳播到UI。最初我曾想過創建一個自定義的TypeConverter(例如RequiredIntTypeConverter),但由於我從ValidationEntity類繼承而出現問題,因此無法想到添加錯誤的好方法。

以下是來自ValidationEntity類的示例以及公司類的摘錄。

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

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

謝謝您的幫助。

+0

代碼中沒有引發異常。也許下面的內容將有助於說明:將DbContext.Companies綁定到表單內的BindingSource,將ErrorProvider的DataSource設置爲BindingSource,將表單的文本框上的DataBindings屬性設置爲CompanyID,CompanyName屬性。如果您導航到擁有公司ID的公司,然後嘗試刪除公司ID,而不是在ErrorProvider中收到「需要CompanyID」,您將收到「輸入字符串未採用可識別的格式」。 –

回答

0

在對此進行了一些更多的研究並測試了代碼示例之後,我找到了解決此特定項目的方案。一個不可空的整數轉換需要一個自定義的TypeConverter。我能找到的信息here 並結束了與下面的類型轉換器用於測試「要求的整數」:

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。但是,我發現了以下的post,它描述瞭如何抑制調試器突破方法。

我仍然有點不確定爲什麼它在這個ApplicationException中斷以及ErrorProvider知道如何顯示基礎異常。如果任何人都可以指點我一些額外的資源,這將不勝感激。

祝您有美好的一天。