我在试图找出在我的WPF应用程序中实现IDataErrorInfo的最佳方法时遇到了麻烦。我有几个模型,每个都有很多属性,正在使用。 ViewModel具有每个模型的属性,View使用这些属性绑定到模型。这是我所拥有的结构的简化版本:
public class ModelA
{
public string PropertyA1 {get; set;}
public string PropertyA2 {get; set;}
}
public class ModelB
{
public string Property B1 {get; set;}
public string Property B2 {get; set;}
}
public class ViewModel
{
public ModelA modelA {get; set;}
public ModelB modelB {get; set;}
}
我的问题是 - 我在哪里实现IDataErrorInfo - 在ViewModel或模型中? View将这些属性绑定为modelA.PropertyA1,依此类推,因此错误在模型中而不是在ViewModel中引发,这使得必须在模型中实现IDataErrorInfo。但是,我听说在ViewModel中实现验证逻辑是一种很好的做法。
我想知道是否有办法捕获ViewModel中的错误而不为每个可能引发错误的属性编写包装器,因为有很多属性并且为每个属性编写包装器会很繁琐。
感谢您的帮助!
答案 0 :(得分:1)
我认为你应该在视图模型中实现IDataErrorInfo
。如果你有一个视图模型的基类,你可能应该,你可以在那里实现它。现在,您的所有实现/验证逻辑都在您的基类中,而不是在 n - 视图模型中传播。
答案 1 :(得分:1)
您希望对模型属性进行Valaidation,只有在Base类中实现或模型中的每个Model时才能实现。如果要在ViewModel中验证ModelA,则需要在ViewModel中实现它,但如果要实现A1的验证,则需要在ModelA中实现它。
如果更改modelA的实例,IDataViewModel将进入该类并尝试调用(ViewModel的实例)[“modelA”]。好的,但这不是你想要的,如果你改变了modelA的属性,IDataViewModel将进入modelA的实例并调用modelA [“B1”],如果你现在在ViewModel中实现验证,modelA将返回一个空字符串
答案 2 :(得分:0)
感谢您的帮助!以下是我决定解决问题的方法:
我创建了两个基类,一个用于普通模型(一个没有任何验证。它只实现了INotifyPropertyChanged),另一个用于具有验证的模型,如下所示。
public abstract class ModelBase : INotifyPropertyChanged
{
//Implement INotifyPropertyChanged here
}
public delegate string ValidateProperty(string propertyName);
public abstract class ValidationModelBase : ModelBase, IDataErrorInfo
{
private bool _canValidate;
public bool CanValidate
{
get { return _canValidate; }
set { _canValidate = value; }
}
#region IDataErrorInfo Members
public string Error
{
get { return string.Empty; }
}
public string this[string columnName]
{
get
{
if (this.CanValidate)
{
return this.Validate(columnName);
}
return string.Empty;
}
}
#endregion
#region Validation Section
public event ValidateProperty OnValidateProperty;
public string Validate(string propertyName)
{
if (this.OnValidateProperty != null)
{
return OnValidateProperty(propertyName);
}
return string.Empty;
}
#endregion
}
现在我的模特看起来像这样:
public class ModelA : validationModelBase
{
public string PropertyA1 {get; set;}
public string PropertyA2 {get; set;}
}
public class ModelB : ValidationModelBase
{
public string Property B1 {get; set;}
public string Property B2 {get; set;}
}
那里没有太大的变化。 ViewModel现在看起来像这样:
public class ViewModel
{
public ModelA modelA {get; set;}
public ModelB modelB {get; set;}
public ViewModel()
{
this.modelA.OnValidateProperty += new ValidateProperty(ValidateModelA);
this.modelB.OnValidateProperty += new ValidateProperty(ValidateModelB);
}
private string ValidateModelA(string propertyName)
{
//Implement validation logic for ModelA here
}
private string ValidateModelB(string propertyName)
{
//Implement validation logic for ModelB here
}
}
到目前为止,这似乎对我有用。这样,任何具有验证的新模型都只需要从ValidationModelBase派生,并让ViewModel为验证事件添加事件处理程序。
如果有人有更好的方法来解决我的问题,请告诉我 - 我愿意接受建议和改进。