RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1153171
Accepted
Vladimir
Vladimir
Asked:2020-07-15 20:04:42 +0000 UTC2020-07-15 20:04:42 +0000 UTC 2020-07-15 20:04:42 +0000 UTC

如何正确检查集合属性是否正确输入!

  • 772

我需要检查OfferModel类的所有属性。

问题是您需要检查:Picture、Descriptions、Param因为它们是集合而不是属性。

例如:如何检查 Descriptions.Text 集合的属性是否为空(即用户输入数据,一切正常,如果不是这样,文本框变为红色,我用 IDataErrorInfo做)并检查集合有元素 Descriptions.Count()>0 然后按钮被禁用。

也就是说,如果集合中的 Descriptions.Count()>0 超过 0 个元素,并且如果元素都是空的空激活按钮。

我用这个例子来检查数据验证。我有集合模型,但我不知道如何检查数据验证。

报价模型

class OfferModel:ChangeProperty,IDataErrorInfo
    {
        #region Cвойства
        string url { get; set; }
        public string Url
        {
            get { return url; }
            set
            {
                url = value;
                OnPropertyChanged("Url");
            }
        }

        decimal price { get; set; }
        public decimal Price
        {
            get { return price; }
            set
            {
                price = value;
                OnPropertyChanged("Price");
            }
        }

        string currencyId { get; set; }
        public string CurrencyId
        {
            get { return currencyId; }
            set
            {
                currencyId = value;
                OnPropertyChanged("CurrencyId");
            }
        }

        int categoryId { get; set; }
        public int CategoryId
        {
            get { return categoryId; }
            set
            {
                categoryId = value;
                OnPropertyChanged("CategoryId");
            }
        }
        public ObservableCollection<string> Picture { get; set; } = new ObservableCollection<string>();
        string name { get; set; }
        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }
        string vendor { get; set; }
        public string Vendor
        {
            get { return vendor; }
            set
            {
                vendor = value;
                OnPropertyChanged("Vendor");
            }
        }
        public ObservableCollection<DescriptionModel> Descriptions { get; set; } = new ObservableCollection<DescriptionModel>();
        public ObservableCollection<ParamModel> Param { get; set; } = new ObservableCollection<ParamModel>();
       
        int stock_quantity { get; set; }
        public int Stock_quantity
        {
            get { return stock_quantity; }
            set
            {
                stock_quantity = value;
                OnPropertyChanged("Stock_quantity");
            }
        }

        bool аvailable { get; set; }
        public bool Available
        {
            get { return аvailable; }
            set
            {
                аvailable = value;
                OnPropertyChanged("Available");
            }
        }

        int id { get; set; }
        public int Id
        {
            get { return id; }
            set
            {
                id = value;
                OnPropertyChanged("Id");
            }
        }
        #endregion

        #region Проверка свойств
        string er { get; set; }
        public string Error
        {
            get { return er; }
        }

        public string this[string propertyName]
        {
            get
            {
                string validationResult = null;
                switch (propertyName)
                {
                    case "Name":
                        validationResult = Validation.Name(Name);
                        break;
                    case "Url":
                        validationResult = Validation.Ui(Url);
                        break;
                    case "Price":
                        validationResult = Validation.Price(Price);
                        break;
                    case "Vendor":
                        validationResult = Validation.Vendor(Vendor);
                        break;
                    case "Stock_quantity":
                        validationResult = Validation.StockQuantity(Stock_quantity);
                        break;
                    default:throw new ApplicationException("Неизвестное свойство проверяется модели OfferModel.");
                }
                return validationResult;
            }
        }
        #endregion
        public OfferModel(){}
        public OfferModel(string url, decimal price, string currencyId, int categoryId, string name, string vendor, int stock_quantity, bool available, int id)
        {
            Url = url;
            Price = price;
            CurrencyId = currencyId;
            CategoryId = categoryId;
            Name = name;
            Vendor = vendor;
            Stock_quantity = stock_quantity;
            Available = available;
            Id = id;
        }
 
    }

参数模型

class ParamModel :ChangeProperty,IDataErrorInfo
    {
        string name { get; set; }
        string text { get; set; }
        /// <summary>
        /// Xарактеристику параметра.
        /// </summary>
        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }
        /// <summary>
        /// Значение параметра.
        /// </summary>
        public string Text
        {
            get { return text; }
            set
            {
                text = value;
                OnPropertyChanged("Text");
            }
        }


        public ParamModel() { }
        public ParamModel(string name, string text)
        {
            Name = name;
            Text = text;
        }

        #region Проверка свойств
        string er { get; set; }
        public string Error
        {
            get { return er; }
        }

        public string this[string propertyName]
        {
            get
            {
                string validationResult = null;
                switch (propertyName)
                {
                    case "Name":
                        validationResult = Validation.NameParam(Name);
                        break;
 
                    case "Text":
                        validationResult = Validation.TextParam(Text);
                        break;
                    default:throw new ApplicationException("Неизвестное свойство проверяется модели ParamModel.");
                }
                return validationResult;
            }
        }
        #endregion


    }

描述型号

class DescriptionModel:ChangeProperty,IDataErrorInfo
    {
      
        private string text { get; set; }
        public string Text
        {
            get { return text; }
            set 
            {
                text = value;
                OnPropertyChanged(nameof(Text));
            }
        }
        public DescriptionModel() { }
        public DescriptionModel(string text)
        {
            Text = text;
        }

        #region Проверка свойств
        string er { get; set; }
        public string Error
        {
            get { return er; }
        }

        public string this[string propertyName]
        {
            get
            {
                string validationResult = null;
                switch (propertyName)
                {
                    case "Text":
                        validationResult = Validation.Text(Text);
                        break;
                    default: throw new ApplicationException("Неизвестное свойство проверяется модели DescriptionModel.");
                }
                return validationResult;
            }
        }
        #endregion

    }

添加产品时如何检查集合的 AddProductViewModel属性:Picture.CollectionChanged - 添加到集合时,item.PropertyChanged - 属性更改时。

这在触发 CollectionChanged 事件时很好(也就是说,当添加到集合时,如果通过引用将报价传递给用于测量产品的构造函数,则 CollectionChanged 事件将不起作用)。

还有另一种实现验证的方法吗?

 readonly OfferModel offer;
 /// <summary>
        /// Хранения валлидность свойств.
        /// </summary>
        private Dictionary<string, bool> validProperties;
        /// <summary>
        /// Включить кнопку если все свойства валлидни.
        /// </summary>
        private bool allPropertiesValid = false;
        public bool AllPropertiesValid
        {
            get { return allPropertiesValid; }
            set
            {
                if (allPropertiesValid != value)
                {
                    allPropertiesValid = value;
                    OnPropertyChanged("AllPropertiesValid");
                }
            }
        }
 #region Валидации данных
            validProperties = new Dictionary<string, bool>();//нужен для того чтобы включить кнопку добавленные если все данные будут коректные.
            validProperties.Add("Name", false);
            validProperties.Add("Url", false);
            validProperties.Add("Price", false);
            validProperties.Add("Vendor", false);
            validProperties.Add("Stock_quantity", false);
            validProperties.Add("Picture", false);
            validProperties.Add("Descriptions", false);
            validProperties.Add("Param", false);
            //Проверки на валидность ввода Picture Descriptions Param.
            Picture.CollectionChanged += (s, e) =>
            {
                validProperties["Picture"] = Picture.Count() > 0 ? true : false;
                ValidateProperties();
            };
            Descriptions.CollectionChanged += (s, e) =>
            {

                bool isEmpty = false;
                if (e.Action == NotifyCollectionChangedAction.Add)
                {
                    foreach (DescriptionModel item in e.NewItems)//Добавление новые элементы
                    {
                        isEmpty = Validation.TextBool(item.Text) ? false : true;
                        item.PropertyChanged += (sender, argument) => //Проходимся по свойствам модели.
                        {
                            int i = 0;
                            foreach (var des in Descriptions)
                            {
                                if (Validation.TextBool(des.Text))
                                {
                                    i++;
                                }
                            }
                            validProperties["Descriptions"] = (i == 0) ? true : false;
                            isEmpty = (i == 0) ? true : false;
                            ValidateProperties();

                        };

                    }
                }
                else if (e.Action == NotifyCollectionChangedAction.Remove)
                {
                    int i = 0;
                    foreach (var des in Descriptions)
                    {
                        if (Validation.TextBool(des.Text))
                        {
                            i++;
                        }
                    }
                    isEmpty = (i == 0) ? true : false;
                }

                validProperties["Descriptions"] = (Descriptions.Count > 0 && isEmpty != false) ? true : false;
                ValidateProperties();
            };
            Param.CollectionChanged += (s, e) =>
            {
                bool isEmpty = false;
                if (e.Action == NotifyCollectionChangedAction.Add)
                {
                    foreach (ParamModel item in e.NewItems)//Добавление новые элементы
                    {

                        var name = Validation.NameBoolParam(item.Name);
                        var text = Validation.TextBoolParam(item.Text);
                        validProperties["Param"] = (name && text) ?  false: true;
                        item.PropertyChanged += (sender, argument) => //Проходимся по свойствам модели.
                        {
                            int nameisvalid = 0;
                            int textisvalid = 0;
                            foreach (var par in Param)//Ищем неправильно заполнены параметры.
                            {
                                if (Validation.NameBoolParam(par.Name)) nameisvalid++;
                                if (Validation.TextBoolParam(par.Text)) textisvalid++;
                            }
                            validProperties["Param"] = (nameisvalid == 0 && textisvalid == 0) ? true : false;
                            isEmpty = (nameisvalid == 0 && textisvalid == 0) ? true : false;
                            ValidateProperties();

                        };

                    }
                }
                else if (e.Action == NotifyCollectionChangedAction.Remove)
                {
                    int nameisvalid = 0;
                    int textisvalid = 0;
                    foreach (var par in Param)
                    {
                        if (Validation.NameBoolParam(par.Name)) nameisvalid++;
                        if (Validation.TextBoolParam(par.Text)) textisvalid++;
                    }
                    isEmpty = (nameisvalid == 0 && textisvalid == 0) ? true : false;
                }

                validProperties["Param"] = (Param.Count > 0 && isEmpty != false) ? true : false;
                ValidateProperties();
            };
            #endregion


#region Реализация IDataErrorInfo 

        public string Error
        {
            get { return (offer as IDataErrorInfo).Error; }
        }

        public string this[string propertyName]
        {
            get
            {   if(offer != null)
                {
                    string error = (offer as IDataErrorInfo)[propertyName];
                    validProperties[propertyName] = string.IsNullOrEmpty(error) ? true : false;
                    ValidateProperties();
                    CommandManager.InvalidateRequerySuggested();
                    return error;
                }
                return null;
            }
        }

        private void ValidateProperties()
        {
            foreach (bool isValid in validProperties.Values)
            {
                if (!isValid)
                {
                    AllPropertiesValid = false;
                    return;
                }
            }
            AllPropertiesValid = true;
        }

        #endregion
c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    XelaNimed
    2020-07-16T07:26:08Z2020-07-16T07:26:08Z

    有用于此目的的ValidationAttribute属性。如果您需要实施任何特殊的属性检查,您可以:

    • 创建你的属性
    • 实现 IValidatableObject 接口以验证整个类型。在这种情况下,可以使用Validator。
    • 使用 CustomValidationAttribute调用带有签名的静态方法:
      1. 验证结果方法(对象)
      2. ValidationResult 方法(对象,ValidationContext)

    之后,我们可以使用反射来检查。用法可能如下所示:

    public static class StaticValidators
    {
        public static ValidationResult IsUpperCase(object value, ValidationContext context)
        {
            if (value is null)
            {
                return new ValidationResult(Res.IsUpper_ValueIsNull, new string[] { context.MemberName });
            }
    
            string strValue = value.ToString();
    
            if (string.IsNullOrWhiteSpace(strValue))
            {
                return new ValidationResult(Res.IsUpper_ValueIsEmpty, new string[] { context.MemberName });
            }
    
            bool _isEquals = string.Equals(strValue, strValue.ToUpperInvariant(), StringComparison.InvariantCulture);
    
            return _isEquals
                ? ValidationResult.Success
                : new ValidationResult(Res.IsUpper_ValueIsNotValid, new string[] { context.MemberName });
        }
    }
    
    public class Person
    {
        [Required(AllowEmptyStrings = false),
            StringLength(10),
            RegularExpression(@"^[a-zA-Z-]+$")]
        public string FirstName { get; set; }
    
        [Required(AllowEmptyStrings = false),
            StringLength(10),
            RegularExpression(@"^[a-zA-Z-]+$")]
        public string LastName { get; set; }
    
        public string MiddleName { get; set; }
    
        [Required(AllowEmptyStrings = false),
            CustomValidation(typeof(StaticValidators), method: nameof(StaticValidators.IsUpperCase))]
        public string PersonalNr { get; set; }
    
        [ContainsUnique(typeof(string))]
        public List<string> Emails { get; set; }
    
        [ContainsUnique(typeof(PhoneNumber), PropertyName = nameof(PhoneNumber.TypeOfPhone))]
        public List<PhoneNumber> Phones { get; set; }
    }
    
    public struct PhoneNumber
    {
        public string NumberOfPhone { get; set; }
        public PhoneType TypeOfPhone { get; set; }
    }
    
    var person = new Person
    {
        FirstName = "John",
        LastName = "Doe",
        PersonalNr = "Abc123",
        Emails = new List<string>
        {
            "example@domain.tld", "j.doe@gmail.com", "jd@yahoo.com", "j.doe@gmail.com"
        },
        Phones = new List<PhoneNumber>
        {
            new PhoneNumber{ NumberOfPhone = "123", TypeOfPhone = PhoneType.PrivateMobile },
            new PhoneNumber{ NumberOfPhone = "567", TypeOfPhone = PhoneType.PrivateMobile }
        }
    };
    
    var result = person.ValidateType();
    /*
    result is:
    [{
      "PropertyName": "PersonalNr",
      "AttributeName": "RegularExpressionAttribute",
      "ErrorMessage": "The field PersonalNr must match the regular expression '^[a-zA-Z]{2}[0-9]{5}$'."
    },
    {
      "PropertyName": "Emails",
      "AttributeName": "ContainsUniqueAttribute",
      "ErrorMessage": "Поле Emails не должно содержать повторяющихся значений в свойстве 'value'. Дубликаты значений: j.doe@gmail.com."
    },
    {
      "PropertyName": "Phones",
      "AttributeName": "ContainsUniqueAttribute",
      "ErrorMessage": "Поле Phones не должно содержать повторяющихся значений в свойстве 'TypeOfPhone'. Дубликаты значений: PrivateMobile."
    }]
    */
    

    验证属性实现示例:

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
    public sealed class MinCountAttribute : ValidationAttribute
    {
        public uint MinCount { get; }
    
        public MinCountAttribute(uint minCount)
        {
            MinCount = minCount;
            ErrorMessageResourceType = typeof(AttributesResources);
            ErrorMessageResourceName = nameof(AttributesResources.MinCount_ValidationError);
        }
    
        public override string FormatErrorMessage(string name)
        {
            return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, MinCount);
        }
    
        public override bool IsValid(object value)
        {
            if (value is null)
            {
                return false;
            }
    
            if (value is ICollection collection)
            {
                return MinCount <= (collection?.Count ?? -1);
            }
            throw new InvalidCastException(AttributesResources.MinCount_InvalidCastException);
        }
    }
    

    相关链接

    • 演示项目
    • IValidatableObject 接口
    • ValidationAttribute 类
    • CustomValidationAttribute 类
    • исходный код CustomValidationAttribute.cs

    P.S.: извиняюсь. Только сейчас понял, что речь идёт о WPF. В таком случае вот этот ответ поможет.

    • 2

相关问题

  • 使用嵌套类导出 xml 文件

  • 分层数据模板 [WPF]

  • 如何在 WPF 中为 ListView 手动创建列?

  • 在 2D 空间中,Collider 2D 挂在玩家身上,它对敌人的重量相同,我需要它这样当它们碰撞时,它们不会飞向不同的方向。统一

  • 如何在 c# 中使用 python 神经网络来创建语音合成?

  • 如何知道类中的方法是否属于接口?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5