将IDataErrorInfo与嵌套对象一起使用

我正在使用MVVM,我想使用IDataErrorInfo来validation我的View。

我当前的实现包括嵌套对象和不同的ViewModel。 例如,业务实体“客户”包含业务实体“地址”。 我在我的视图中直接访问Address,例如“Customer.Address”。 要validationAddress中的更改,我必须在Address中实现IDataErrorInfo。

我在不同的Views / ViewModels中使用Customer或Address。 在不同的Views / ViewModel中使用会导致不同的validation行为。 因此,在实体本身中实现validation是不够的。

公开我想在ViewModel中直接更改的属性(创建直接设置/获取实体的新属性)似乎使ViewModel方式过于僵化。 而且太大了。

我无法inheritanceBase Classes,因为一些业务实体已经从其他对象派生(事实上我无法改变)。 我目前看到的唯一选择是向业务实体添加ViewModel接口,并将业务实体中的this []调用转发到该ViewModel接口。

是否有关于如何在ViewModel中validation这些嵌套对象的最佳实践?

编辑:另一个原因validation我没有看到Business Objects中的validation作为一个有用的想法是我需要在我的ViewModel中使用不同的Business Objects来validationView和数据条目。

我过去做过这种方法的一种方法是在Model上公开ValidationDelegate ,它允许ViewModel将自己的validation代码附加到模型中。

通常我这样做是因为我使用Model层作为普通数据对象,所以我的模型只validation基本的东西,如max-length或not-nulls,而任何不是特定于数据模型的高级validation都在ViewModel中完成。 这通常包括诸如确保项目是唯一的,或者用户有权将值设置为特定范围,或者甚至类似于仅针对特定操作存在validation的情况。

 public class CustomerViewModel { // Keeping these generic to reduce code here, but it // should include PropertyChange notification public AddressModel Address { get; set; } public CustomerViewModel() { Address = new AddressModel(); Address.AddValidationDelegate(ValidateAddress); } // Validation Delegate to validate Adderess private string ValidateAddress(object sender, string propertyName) { // Do your ViewModel-specific validation here. // sender is your AddressModel and propertyName // is the property on the address getting validated // For example: if (propertyName == "Street1" && string.IsNullOrEmpty(Address.Street1)) return "Street1 cannot be empty"; return null; } } 

这是我通常用于validation委托的代码:

 #region IDataErrorInfo & Validation Members #region Validation Delegate public delegate string ValidationDelegate( object sender, string propertyName); private List _validationDelegates = new List(); public void AddValidationDelegate(ValidationDelegate func) { _validationDelegates.Add(func); } public void RemoveValidationDelegate(ValidationDelegate func) { if (_validationDelegates.Contains(func)) _validationDelegates.Remove(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) { string s = null; foreach (var func in _validationDelegates) { s = func(this, propertyName); if (s != null) return s; } return s; } #endregion // IDataErrorInfo for binding errors #endregion // IDataErrorInfo & Validation Members 

在不同的Views / ViewModel中使用会导致不同的validation行为。

因此,您有不同的视图模型。 如果您无法从某个基本视图模型inheritance这些视图模型,请使用聚合:

 public class Address {} public class AddressViewModel1 : IDataErrorInfo { private readonly Address address; // other stuff here } public class AddressViewModel2 : IDataErrorInfo { private readonly Address address; // other stuff here } 

如何使用dependency injection并将validation服务注入每个不同视图模型的客户对象?

但我认为在你的viewmodel中实现idataerrorinfo和所有需要的属性会更干净,但当然还有一次更多的工作。