4

我在试图找出在我的 WPF 应用程序中实现 IDataErrorInfo 的最佳方法时遇到了麻烦。我有几个模型,每个模型都有很多属性,正在使用中。ViewModel 具有每个模型的属性,视图使用这些属性绑定到模型。这是我所拥有的结构的简化版本:

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 中的错误,而无需为每个会引发错误的属性编写包装器,因为有很多属性并且为每个属性编写包装器会很乏味。

谢谢你的帮助!

4

3 回答 3

2

我认为你应该IDataErrorInfo在视图模型中实现。如果你的视图模型有一个基类,你可能应该,你可以在那里实现它。现在,您的所有实现/验证逻辑都在您的基类中,而不是分布在n个视图模型中。

于 2013-01-11T16:02:17.697 回答
1

您需要对模型的属性进行验证,这只能在您在基类中实现或为模型中的每个模型实现时才能完成。如果你想在 ViewModel 中验证 ModelA,你需要在 ViewModel 中实现它,但如果你想为 A1 实现验证,你需要在 ModelA 中实现它。

如果您更改模型A 的实例,IDataViewModel 将进入该类并尝试调用 (您的 ViewModel 的实例)["modelA"]。好的,但这不是您想要的,如果您更改 modelA 的属性,IDataViewModel 将进入 modelA 的实例并调用 modelA["B1"],如果您现在在 ViewModel 中实现验证,modelA 将返回一个空字符串

于 2013-01-11T16:07:54.153 回答
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 为验证事件添加事件处理程序。

如果有人有更好的方法来解决我的问题,请告诉我——我愿意接受建议和改进。

于 2013-01-11T18:02:08.253 回答