我在类中实现了 IDataErrorInfo 接口(interface)来验证对象。但我现在想做的是以编程方式验证整个对象以了解它是否有效。 我一直在谷歌搜索但找不到任何东西。我以为我可以做一些类似 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);
}
最佳答案
首先你的类必须实现 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 绑定(bind)中 ValidateOnDataErrors 必须为 True
<TextBox x:Name="PhoneNumber" Text="{Binding PhoneNumber, ValidatesOnDataErrors=True}"/>
这里我返回了简单的字符串而不是您的 ErrorMessage,因为我不知道它是什么,您可以简单地用您的 ErrorMessage 替换字符串。我希望这能给您一个想法。
关于c# - 使用 IDataErrorInfo 验证整个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20435554/