使用WinForms进行entity frameworkUIvalidation

我对使用WinForms应用程序和entity framework5设置客户端validation感兴趣。我知道我可以实现IValidatableObject接口来执行和自定义validation,我可能需要为每个实体。

但是,由于我正在使用WinForms,我想使用ErrorProvider在填写表单时出现validation错误时向用户显示一个很好的通知。 是否能够使用IValidatableObject接口实现此function,还是需要在我的实体上实现IDataErrorInfo接口以使ErrorProvider正常工作?

如果您对此更好的替代方案有任何其他建议,请告诉我,我也很乐意调查。

假设您有一个名为Car的实体,此类包含需要validation的属性。

 public class Car { [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } // Accepted values have to be between 1 and 5. public int NeedToBeValidatedRange { get; set; } } 

你必须在我的名为Entity的例子中为你所有的entites创建一个基类。

 using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; /// This is the base class for all entities and it provide a change notfication. public abstract class Entity : INotifyPropertyChanged { // Event fired when the property is changed! public event PropertyChangedEventHandler PropertyChanged; /// Called when int property in the inherited class is changed for ther others properties like (double, long, or other entities etc,) You have to do it. protected void HandlePropertyChange(ref int value, int newValue, string propertyName) { if (value != newValue) { value = newValue; this.Validate(propertyName); this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } /// Validate the property ///  /// The list of validation errors ///  private ICollection PropertyValidator(string propertyName) { var validationResults = new Collection(); PropertyDescriptor property = TypeDescriptor.GetProperties(this)[propertyName]; Validator.TryValidateProperty( property.GetValue(this), new ValidationContext(this, null, null) { MemberName = propertyName }, validationResults); return validationResults; } /// Validates the given property and return all found validation errors. private void Validate(string propName) { var validationResults = this.PropertyValidator(propName); if (validationResults.Count > 0) { var validationExceptions = validationResults.Select(validationResult => new ValidationException(validationResult.ErrorMessage)); var aggregateException = new AggregateException(validationExceptions); throw aggregateException; } } } 

现在你要修改Car类,它应该是这样的:

 public class Car : Entity { private int id; private int needToBeValidatedRange; [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get { return this.id; } set { this.HandlePropertyChange(ref this.id, value, "Id"); } } [Range(1, 5)] public int NeedToBeValidatedRange { get { return this.needToBeValidatedRange; } set { this.HandlePropertyChange(ref this.needToBeValidatedRange, value, "NeedToBeValidatedRange "); } } } 

在用户界面的某个位置,您将创建汽车实体:

 Car car1 = new Car(); car1.NeedToBeValidatedRange = 3; // This will work! Car car2 = new Car(); car2.NeedToBeValidatedRange = 6; // This will throw ValidationException 
  • WPF支持非常好的ValidationException。
  • Winforms部分支持ValidationException但现在您可以自由地处理这个问题。

有两种选择:

  • 使用IValidateObject和IdataErrorInfo扩展您的poco类,并在validation方法中引发ui错误。
  • 调用保存更改时捕获validation错误,并根据哪个实体字段生成validation错误直接调用ErrorProvider。

有关使用IValidateObject扩展poco类并在调用保存更改时处理validation错误的示例,请参阅以下内容。

http://msdn.microsoft.com/en-us/data/gg193959.aspx

您可能想尝试我在这里建议的内容。 这可能仅适用于您首先使用代码的情况。 您可以将其附加到某些用户输入事件上运行。

https://stackoverflow.com/a/19170277/2592994