使用IDataErrorInfo的使用嵌套对象 [英] Using IDataErrorInfo with Nested Objects

查看:219
本文介绍了使用IDataErrorInfo的使用嵌套对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using MVVM and I want to use IDataErrorInfo to validate my View.

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

My current implementation includes Nested objects and different ViewModels. e.g. Business Entity 'Customer' contains Business Entity 'Address'. I am accessing Address directly in my view, like "Customer.Address". To validate changes in Address I would have to implement IDataErrorInfo in Address.

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

I use Customer or Address in different Views/ViewModels. Usage in different Views/ViewModels lead to different Validation Behavior. Thus, implementing the validation in the Entity itself is insufficient.

暴露欲直接在视图模型以改变性质(创建直接设置/获取实体新属性)似乎使视图模型的方式太死板。而且相当太大。

Exposing the properties I want to change directly in the ViewModel (creating new Properties that directly set/get the entity) seems to make the ViewModel way too rigid. and quite too large.

我不能从基类继承,因为一些业务实体已经从其他对象派生的(事实上我不能改变)。
我看到目前唯一的选择就是增加了一个视图模型接口,业务实体和转发的业务实体到视图模型接口这[]调用。

I cannot inherit from Base Classes, as some Business Entities already derive from other objects (A fact I cannot change). The only option I see at the moment is adding an interface to the ViewModel to the Business Entities, and forwarding this[] calls in the Business Entities to that ViewModel Interface.

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

Is there a best practice on how to validate these nested objects in the ViewModel?

修改最佳实践:一个原因验证我看不到验证了Business Objects公司作为一个有用的想法是,我需要不同的业务对象在我的视图模型来验证视图和数据输入

One more reason Validation I don't see Validation in the Business Objects as a usable idea is that I need different Business Objects in my ViewModel to validate the View and the data entry.

推荐答案

我在过去做到了这一点的方法之一是的上示范的,这使得在ViewModel到其自己的验证代码附加到模型暴露ValidationDelegate

One way I have done this in the past is to expose a ValidationDelegate on the Model, which allows the ViewModel to attach its own validation code to the model.

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

Typically I do this because I use the Model layer as plain data objects, so my Models only validate basic things such as max-length or not-nulls, while any advanced validation not specific to the data model gets done in the ViewModel. This typically includes things such as ensuring an item is unique, or that a user has permission to set a value to a specific range, or even something like your case where the validation only exists for a specific action.

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

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

Here's the code I usually use for the validation delegate:

#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

这篇关于使用IDataErrorInfo的使用嵌套对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆