我在我的类中实现了一个IDataErrorInfo接口来验证对象。但我现在要做的是以编程方式验证整个对象以了解它是否有效。 我一直在谷歌搜索,但找不到任何东西。我以为我可以做像object.Validate()这样的事情,并知道它是否有效,但IDataErrorInfo不提供任何类似的方法。
我已经使用XAML验证它,但我也需要在方法中检查它。
有人可以帮助我实现这个目标吗?以防万一,这是我的班级:
namespace Plutus.Data.Domain
{
using Plutus.Data.Domain.NameMappings;
using Plutus.Data.Domain.Validation;
using System;
using System.ComponentModel;
public class Phone : IDataErrorInfo
{
/// <summary>
/// Código de área.
/// </summary>
public string AreaCode { get; set; }
/// <summary>
/// Identificador de tipo de teléfono.
/// </summary>
public short? PhoneTypeID { get; set; }
/// <summary>
/// Número de teléfono.
/// </summary>
public long? PhoneNumber { get; set; }
/// <summary>
/// Número de interno.
/// </summary>
public string ExtensionNumber { get; set; }
public string Error { get { return null; } }
public string this[string columnName]
{
get
{
string result = null;
if (columnName == "AreaCode")
{
if (string.IsNullOrWhiteSpace(AreaCode))
result = ErrorMessages.ErrorMessage(ErrorMessages.FieldIsRequired, PhoneNameDictionary.GetValue(columnName));
}
if (columnName == "PhoneTypeID")
{
if (!PhoneTypeID.HasValue)
result = ErrorMessages.ErrorMessage(ErrorMessages.FieldIsRequired, PhoneNameDictionary.GetValue(columnName));
}
if (columnName == "PhoneNumber")
{
if (!PhoneNumber.HasValue)
result = ErrorMessages.ErrorMessage(ErrorMessages.FieldIsRequired, PhoneNameDictionary.GetValue(columnName));
}
return result;
}
}
}
}
扩展解决方案:
也许我没有解释得很好,但我需要的是知道对象是否有任何验证错误。基于ethicallogics解决方案,我创建了一个名为IsValid的新方法,在那里我检查字典上是否有任何错误:
public bool IsValid()
{
ValidateProperty("AreaCode");
ValidateProperty("PhoneNumber");
ValidateProperty("PhoneTypeID");
return Errors.Count == 0 ? true : false;
}
为了实现这一点,我不得不更改ValidateProperty方法,以便不再在字典中添加错误键(或者您将获得异常)。然后我首先检查错误是否已经在字典中,并且只有在它没有时才添加它:
public void ValidateProperty(string propertyName)
{
if (propertyName == "AreaCode" && string.IsNullOrWhiteSpace(AreaCode))
{
if (!Errors.ContainsKey(propertyName))
Errors.Add(propertyName, ErrorMessages.ErrorMessage(ErrorMessages.FieldIsRequired, PhoneNameDictionary.GetValue(propertyName)));
}
else if (propertyName == "PhoneTypeID" && !PhoneTypeID.HasValue)
{
if (!Errors.ContainsKey(propertyName))
Errors.Add(propertyName, ErrorMessages.ErrorMessage(ErrorMessages.FieldIsRequired, PhoneNameDictionary.GetValue(propertyName)));
}
else if (propertyName == "PhoneNumber" && !PhoneNumber.HasValue)
{
if (!Errors.ContainsKey(propertyName))
Errors.Add(propertyName, ErrorMessages.ErrorMessage(ErrorMessages.FieldIsRequired, PhoneNameDictionary.GetValue(propertyName)));
}
else if (Errors.ContainsKey(propertyName))
Errors.Remove(propertyName);
}
答案 0 :(得分:2)
首先,您的班级必须实施INotifyPropertyChanged
public class Phone : IDataErrorInfo, INotifyPropertyChanged
{
string areaCode;
public string AreaCode
{
get
{
return areaCode;
}
set
{
if (areaCode != value)
{
areaCode = value;
ValidateProperty("AreaCode"); //Validate on PropertyChanged
Notify("AreaCode");
}
}
}
short? phoneTypeId;
public short? PhoneTypeID
{
get
{
return phoneTypeId;
}
set
{
if (phoneTypeId != value)
{
phoneTypeId = value;
ValidateProperty("PhoneTypeID");
Notify("PhoneTypeID");
}
}
}
long? phoneNumber;
public long? PhoneNumber
{
get
{
return phoneNumber;
}
set
{
if (phoneNumber != value)
{
phoneNumber = value;
ValidateProperty("PhoneNumber");
Notify("PhoneNumber");
}
}
}
string extensionNumber;
public string ExtensionNumber
{
get
{
return extensionNumber;
}
set
{
if (extensionNumber != value)
extensionNumber = value; Notify("ExtensionNumber");
}
}
public string Error { get { return null; } }
Dictionary<string, string> errors = new Dictionary<string, string>();
public string this[string columnName]
{
get
{
if(errors.ContainsKey(columnName)
return errors[columnName];
return null;
}
}
public event PropertyChangedEventHandler PropertyChanged;
void Notify(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
//This could be much more generic but for simplicity
void ValidateProperty(string propertyName)
{
if (propertyName=="AreaCode" && string.IsNullOrWhiteSpace(AreaCode))
errors.Add(propertyName,"AreaCode is Mandatory");
else if (propertyName == "PhoneNumber" && !PhoneNumber.HasValue)
errors.Add(propertyName, "PhoneNumber can not be null");
else if(propertyName == "PhoneTypeID" && !PhoneTypeID.HasValue)
errors.Add(propertyName, "PhoneTypeID can not be null");
else if(errors.ContainsKey(propertyName))
errors.Remove(propertyName);
}
public void ValidatePhoneObject()
{
ValidateProperty("AreaCode");
ValidateProperty("PhoneNumber");
ValidateProperty("PhoneTypeID");
//Must fire property changed so that binding validation System calls IDataErrorInfo indexer
Notify("AreaCode");
Notify("PhoneNumber");
Notify("PhoneTypeID");
}
}
xaml绑定中的ValidateOnDataErrors必须为True
<TextBox x:Name="PhoneNumber" Text="{Binding PhoneNumber, ValidatesOnDataErrors=True}"/>
这里我返回了简单的字符串而不是你的ErrorMessage,因为我不知道它是什么,你可以简单地用你的ErrorMessage替换字符串。我希望这会给你一个想法。
答案 1 :(得分:0)
ReactiveValidatedObject有一个IsObjectValid方法可以满足你的需要。您可以使用它,或调整该代码。
答案 2 :(得分:0)
// you can implement this Vali class in any of your classes
// which you need to check their validation
// Vali class will loop throw the properties of any another class
// which implement it. and check their validations
// and has IsValid which return the state of validation
// return true if valid
public abstract class Vali {
public bool IsValid {
get {
PropertyInfo propInfo = GetType().GetProperty("Error");
object itemValue = propInfo.GetValue(this , null);
string iiiii = (string)itemValue;
foreach (PropertyInfo prop in GetType().GetProperties()) {
if (!String.IsNullOrWhiteSpace(met(prop.Name))) {
//MessageBox.Show("تاكد من صحة البيانات");
return false;
}
}
return true;
}
}
public abstract string met(string columnName);
}
// as example your class will be like this
public class Phone : Vali , IDataErrorInfo {
/// <summary>
/// Código de área.
/// </summary>
public string AreaCode { get; set; }
/// <summary>
/// Identificador de tipo de teléfono.
/// </summary>
public short? PhoneTypeID { get; set; }
/// <summary>
/// Número de teléfono.
/// </summary>
public long? PhoneNumber { get; set; }
/// <summary>
/// Número de interno.
/// </summary>
public string ExtensionNumber { get; set; }
public string Error {
get { return null; }
}
public string this[string columnName] {
get {
return met(columnName);
}
}
public override string met(string columnName)
{
if (columnName == "AreaCode") {
if (string.IsNullOrWhiteSpace(AreaCode))
Error = ErrorMessages.ErrorMessage(ErrorMessages.FieldIsRequired , PhoneNameDictionary.GetValue(columnName));
}
if (columnName == "PhoneTypeID") {
if (!PhoneTypeID.HasValue)
Error = ErrorMessages.ErrorMessage(ErrorMessages.FieldIsRequired , PhoneNameDictionary.GetValue(columnName));
}
if (columnName == "PhoneNumber") {
if (!PhoneNumber.HasValue)
Error = ErrorMessages.ErrorMessage(ErrorMessages.FieldIsRequired , PhoneNameDictionary.GetValue(columnName));
}
return Error;
}
}
class sdfasfd
{
public sdfasfd()
{
// u can do this in ur code
Phone p = new Phone();
//assign properties here for p
MessageBox.Show(p.IsValid.ToString());
}
}