對於基於業務規則的驗證,我通常公開一個驗證委託,我的ViewModel可以設置。
例如,包含您的收藏視圖模型可能是這樣的:
public ParentViewModel()
{
foreach(var user in UserCollection)
user.AddValidationErrorDelegate(ValidateUser);
}
private string ValidateUser(object sender, string propertyName)
{
if (propertyName == "Email")
{
var user = (UserVM)sender;
if (UserCollection.Count(p => p.Email== user.Email) > 1)
return "Another user already has this Email Address";
}
return null;
}
的想法是,你Model
應該只包含原始數據,因此它應該只驗證原始數據。這可以包括驗證最大長度,必填字段和允許的字符等內容。包含業務規則的業務邏輯應在ViewModel
中進行驗證,並允許這樣做。
在UserVM
類實際執行的我IDataErrorInfo
應該是這樣的:
#region IDataErrorInfo & Validation Members
/// <summary>
/// List of Property Names that should be validated
/// </summary>
protected List<string> ValidatedProperties = new List<string>();
#region Validation Delegate
public delegate string ValidationErrorDelegate(object sender, string propertyName);
private List<ValidationErrorDelegate> _validationDelegates = new List<ValidationErrorDelegate>();
public void AddValidationErrorDelegate(ValidationErrorDelegate func)
{
_validationDelegates.Add(func);
}
#endregion // Validation Delegate
#region IDataErrorInfo for binding errors
string IDataErrorInfo.Error { get { return null; } }
string IDataErrorInfo.this[string propertyName]
{
get { return this.GetValidationError(propertyName); }
}
public string GetValidationError(string propertyName)
{
// If user specified properties to validate, check to see if this one exists in the list
if (ValidatedProperties.IndexOf(propertyName) < 0)
{
//Debug.Fail("Unexpected property being validated on " + this.GetType().ToString() + ": " + propertyName);
return null;
}
string s = null;
// If user specified a Validation method to use, Validate property
if (_validationDelegates.Count > 0)
{
foreach (ValidationErrorDelegate func in _validationDelegates)
{
s = func(this, propertyName);
if (s != null)
{
return s;
}
}
}
return s;
}
#endregion // IDataErrorInfo for binding errors
#region IsValid Property
public bool IsValid
{
get
{
return (GetValidationError() == null);
}
}
public string GetValidationError()
{
string error = null;
if (ValidatedProperties != null)
{
foreach (string s in ValidatedProperties)
{
error = GetValidationError(s);
if (error != null)
{
return error;
}
}
}
return error;
}
#endregion // IsValid Property
#endregion // IDataErrorInfo & Validation Members
我喜歡@Rachel了這裏的方法。我一直在使用IDataErrorInfo.this []從模型中暴露範圍錯誤,但只有在用戶單擊確定後才能運行業務規則檢查。在用戶完成填寫表單的其餘部分並單擊確定之前,能夠使用像這樣的方法將業務規則錯誤暴露給UI *是很好的。 – Kendrick
這就是我正在尋找的!填寫表單時,通過IDataErrorInfo執行「更高級別」檢查的一種非常好且簡單的方法。 :) – Christian