数据注解,IDataErrorInfo和MVVM
本文关键字:MVVM IDataErrorInfo 数据 | 更新日期: 2023-09-27 17:49:56
我试图找到在MVVM中验证数据的最佳方法。目前,我正试图使用IDataErrorInfo与数据注释使用MVVM模式。
然而,似乎没有工作,我不知道我可能做错了什么。我有这样的东西
<标题>public class Person : IDataErrorInfo
{
[Required(ErrorMessage="Please enter your name")]
public string Name { get; set; }
public string Error
{
get { throw new NotImplementedException(); }
}
string IDataErrorInfo.this[string propertyName]
{
get
{
return OnValidate(propertyName);
}
}
protected virtual string OnValidate(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
throw new ArgumentException("Property may not be null or empty", propertyName);
string error = string.Empty;
var value = this.GetType().GetProperty(propertyName).GetValue(this, null);
var results = new List<ValidationResult>();
var context = new ValidationContext(this, null, null) { MemberName = propertyName };
var result = Validator.TryValidateProperty(value, context, results);
if(!result)
{
var validationResult = results.First();
error = validationResult.ErrorMessage;
}
return error;
}
}
模型代码由如何在MVVM中捕获数据注释验证的解决方案提供(不幸的是,这个答案不符合我的标准。)
<标题> 视图
<Label Content="Name:" />
<TextBox Text="{Binding UpdateSourceTrigger=LostFocus,
Path=Name,
ValidatesOnDataErrors=True,
NotifyOnValidationError=true}" />
是否有任何方法可以保持模型,视图和视图模型之间的分离,同时仍然利用数据注释与IDataErrorInfo进行验证?
为了保持验证运行,IDataErrorInfo
必须由数据上下文实现,该属性绑定到控件。所以,它应该是这样的:
public class PersonViewModel : IDataErrorInfo
{
[Required(AllowEmptyStrings = false)]
public string Name
{
get
{
return _person.Name
}
set
{
_person.Name = value;
}
}
public string Error
{
get { throw new NotImplementedException(); }
}
string IDataErrorInfo.this[string propertyName]
{
get
{
return OnValidate(propertyName);
}
}
protected virtual string OnValidate(string propertyName)
{
/* ... */
}
}
不需要在模型中实现IDataErrorInfo
,这是视图模型的责任。通常,IDataErrorInfo
是由视图模型的基类实现的。
顺便问一下,为什么OnValidate
是受保护的?你如何想象重写这个方法?
将您在XAML中的定义notifyonvalidation error和validatesondata errors设置为true。在VM中,使用简单的Viewmodel,它对所需属性的setter函数有验证,如果验证失败,它应该抛出验证错误,xaml将知道它是无效的。
public class PersonViewModel
{
private Person _person;
public string Name
{
get
{
return _person.Name
}
set
{
if(value == string.empty)
throw new ValidationException("Name cannot be empty");
_person.Name = value;
}
}
}
现在您需要在xaml中处理这个问题,并从异常