【问题标题】:Using IDataErrorInfo in Model V/s ViewModel在 Model V/s ViewModel 中使用 IDataErrorInfo
【发布时间】:2013-01-11 15:28:14
【问题描述】:

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

感谢您的帮助!

【问题讨论】:

    标签: wpf idataerrorinfo


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        感谢你们的帮助!以下是我决定解决问题的方法:

        我创建了两个基类,一个用于普通模型(没有任何验证的模型。它仅实现 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 为验证事件添加事件处理程序。

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

        【讨论】:

          猜你喜欢
          • 2010-09-25
          • 2021-02-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-02
          • 2020-05-01
          • 1970-01-01
          相关资源
          最近更新 更多