-->

使用IDataErrorInfo的使用嵌套对象(Using IDataErrorInfo with

2019-07-31 15:43发布

我使用MVVM,我想用IDataErrorInfo的验证我的看法。

我目前的实现包括嵌套的对象和不同的ViewModels。 例如,业务实体“客户”包括业务实体“地址”。 我直接在我看来访问地址,如“Customer.Address”。 为了验证在地址变化我会在地址来实现IDataErrorInfo的。

我使用客户或地址在不同的视图/的ViewModels。 在不同的视图使用/的ViewModels导致不同的验证行为。 因此,在实体本身执行验证是不够的。

揭我想直接在视图模型改变的属性(创造直接设置新的属性/获取实体)似乎使视图模型的方式太死板。 而且相当太大。

我不能从基类继承,因为一些业务实体已经从其他物体(实际上我不能改变)获得。 我看到目前唯一的选择就是增加了视图模型的接口,业务实体,并在转发实体企业到视图模型接口这[]调用。

是否有关于如何验证在视图模型这些嵌套对象最好的做法?

编辑:还有一个原因验证我没有看到验证在Business Objects公司作为一个可用的想法是,我需要在我的ViewModel不同的业务对象来验证视图和数据录入。

Answer 1:

我在过去做到了这一点的一种方法是暴露模型上的ValidationDelegate ,它允许视图模型,以它自己的验证代码附加到模型。

通常我这样做是因为我用的Model层为纯数据对象,所以我只模型验证基本的东西,如最大长度或不空,而不是特定于数据模型中的任何先进的验证在视图模型得到执行。 这通常包括诸如确保一个项目是独一无二的,或者用户有权限设置一个值在特定范围内,甚至一些你的情况下验证只存在于一个特定的操作。

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;
    }
}

下面是我通常使用的验证委托的代码:

#region IDataErrorInfo & Validation Members

#region Validation Delegate

public delegate string ValidationDelegate(
    object sender, string propertyName);

private List<ValidationDelegate> _validationDelegates = 
    new List<ValidationDelegate>();

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


Answer 2:

在不同的视图使用/的ViewModels导致不同的验证行为。

因此,你有不同的视图模型。 如果你不能继承一些基本视图模型中,这些视图模型,使用聚合:

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
}


Answer 3:

怎么样使用依赖注入和注入validationservice客户对象为每个不同的视图模型?

但我认为,实施IDataErrorInfo的,在你的ViewModel所有需要的属性将是更清洁,但当然一次更多的工作。



文章来源: Using IDataErrorInfo with Nested Objects