视图中没有显示简单的数据注释验证(没有红色网格线)

本文关键字:验证 红色 网格线 注释 显示 简单 视图 数据 | 更新日期: 2023-09-27 18:15:45

我使用实体框架。

根据这个:https://msdn.microsoft.com/en-us/data/gg193959.aspx

"在应用程序中没有额外的代码或标记更改的情况下现有MVC应用程序将执行客户端验证"

绑定正确。

验证没有过滤到DataGrid,我在SaveChanges上得到一个异常。

private string _Sponsor;
[Required]
[StringLength(20, MinimumLength = 3)]
public string Sponsor
{
    get
    {
        return _Sponsor;
    }
    set
    {
        _Sponsor = value;
        NotifyPropertyChanged("Sponsor");
    }
}

MainWindow.xaml.cs

JobCollectionContext _context = new JobCollectionContext();
CollectionViewSource jobViewSource = ((CollectionViewSource)(this.FindResource("jobViewSource")));
_context.JobCollection.Load();
jobViewSource.Source = _context.JobCollection.Local;

MainWindow.xaml

<DataGridTextColumn Header="Sponsor" Binding="{Binding Sponsor, UpdateSourceTrigger=LostFocus, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" />

视图中没有显示简单的数据注释验证(没有红色网格线)

因为这不是一个MVC应用程序。您正在开发一个WPF应用程序。

如果要显示WPF应用程序中的错误,则需要实现INotifyDataErrorInfo接口。

我有一个实现必要逻辑的基类。只需继承它并调用ValidateProperty("propertyName"),它将使用Attributes来验证给定的属性。

你应该在所有应该被验证的属性设置中这样做,就像你在NotifyPropertyChanged()中做的那样,以保持UI的更新。

public abstract class NotifyDataErrorModel : INotifyDataErrorInfo
{
    /// <summary>
    /// Maps properties to their error sets
    /// </summary>
    protected Dictionary<string, HashSet<string>> errors;
    /// <summary>
    /// maps a property to a list of properties 
    /// the list of properties will get the ValidationErrors of the property
    /// </summary>
    protected NotifyDataErrorModel()
    {
        errors = new Dictionary<string, HashSet<string>>();
        var properties = getProperties();
        foreach (var property in properties)
        {
            errors.Add(property, new HashSet<string>());
        }
    }
    private IEnumerable<string> getProperties()
    {
        var properties = this.GetType().GetProperties().Select(p => p.Name).ToList();
        properties.Remove("HasErrors"); //remove the HasErrors property, because it is part of the interface INotifyDataErrorInfo and not of the actual model
        return properties;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="property">the property to validate</param>
    public virtual void ValidateProperty(string property)
    {
        //clear the errors on the matched property
        errors[property].Clear();
        var type = this.GetType();
        //the entity framework proxies sometimes dont inherit the attributes of the properties
        //so if it is a entity framework proxy object, get the base class (which is the actual model class) instead
        if (type.FullName.Contains("System.Data.Entity.DynamicProxies"))
        {
            type = type.BaseType;
        }
        var propertyInfo = type.GetProperty(property);
        var propertyValue = propertyInfo.GetValue(this);
        var validationAttributes = propertyInfo.GetCustomAttributes(true).OfType<ValidationAttribute>();
        foreach (var validationAttribute in validationAttributes)
        {
            if (!validationAttribute.IsValid(propertyValue))
            {
                errors[property].Add(validationAttribute.FormatErrorMessage(string.Empty));
            }
        }
        raiseErrorsChanged(property);
    }
    public virtual void ValidateAllProperties()
    {
        var properties = getProperties();
        foreach (var property in properties) ValidateProperty(property);
    }
    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
    public System.Collections.IEnumerable GetErrors(string propertyName)
    {
        //if the propertyname is not valid, return an empty IEnumerable
        if (String.IsNullOrEmpty(propertyName)) return new List<string>();
        return errors[propertyName];
    }
    public bool HasErrors
    {
        get { return errors.Any((propertyErrors) => propertyErrors.Value.Count > 0); }
    }
    private void raiseErrorsChanged(string property)
    {
        if (ErrorsChanged != null)
        {
            var eventArgs = new DataErrorsChangedEventArgs(property);
            ErrorsChanged(this, eventArgs);
        }
    }
}