如果我的模型实现了INotifyPropertyChanged并且我的VM需要吗?
澄清:在你有SomeOtherProp的真实情况下,绝对需要实现INotifyPropertyChanged。我真正追求的是我需要为形成良好的模型做多少工作(复制)。
示例:
namespace Question
{
public interface IFoo : INotifyPropertyChanged { }
public interface IBar : INotifyPropertyChanged { }
public interface IModel : INotifyPropertyChanged
{
IFoo Foo { get; set; }
ObservableCollection<IBar> BarCollection { get; }
}
public class VM : TypeSafeViewModelBase
//Clarification: added VM base clase with typesafe override for RaisePropertyChanged
{
private IModel _model;
public VM( IModel model )
{
this._model = model;
//Clarification: added this call...
this._model.PropertyChanged += ( sender, args ) => base.RaisePropertyChanged(args.PropertyName);
//That is the one I have questions about and ultimateley what I want to avoid
}
public IFoo Foo { get { return this._model.Foo; } }
public ObservableCollection<IBar> BarCollection { get { return this._model.BarCollection; } }
//clarification: added this prop declaration
//I know this would be needed as this property is backed by a private member of this class
private string _someOtherProp;
public string SomeOtherProp
{
get { return this._someOtherProp; }
set
{
this._someOtherProp = value;
base.RaisePropertyChanged(() => this.SomeOtherProp);
}
}
}
}
VM是否需要实现INotifyPropertyChanged?并将所有事件转发给V?或者做V中的事情绑定到实现PropertyChanged和CollectionChanged接口的最低级别对象?
如果我有一个结构良好的通知模型层,我似乎找不到需要写多少胶水代码的明确答案......
PS。如果重要的话,我正在使用Prism和Ninject在SL4中开发。我的模型是可变的,有状态的,并且在本地内存中(我保留了一个本地缓存,因为在每次操作后都不能使用服务器)。
答案 0 :(得分:2)
不,您不需要在您的情况下实现接口本身。例如,如果您使用RIA服务业务对象,则VM不需要实现INotifyPropertyChange
,因为那些已经实现了它。
然而!很可能你仍然想这样做,因为像“IsBusy”,“CanSave”等属性通常属于VM本身,然后你需要接口。
通常每个应用程序都有某种类型的VMBase
对象,它实现INotifyPropertyChanged
,INotifyDataErrorInfo
等等。每个VM都继承自这个基类
答案 1 :(得分:1)
实现和维护任何抽象都会受到惩罚,而在MVVM的情况下,有很多胶水代码是不可避免的。要问的问题不是胶水代码是否合适,而是抽象本身是否合适?您是否在视图模型中重用了?你是在大量使用数据绑定吗?单元测试您的视图模型是您的团队所做的事情吗?或者是集成测试你的viewmodels是你开发周期的一部分吗?
要专门回答您的问题,在您的设计中,模型通过实现INotifyPropertyChanged并提供可观察的集合来为viewmodel执行一些工作。我喜欢使用尽可能多的基本语言和库来实现我的模型。这意味着我的集合将是通用列表,哈希集等......而我的事件机制将涉及自定义事件和委托(作为事件聚合器实现)。
我的viewmodel最终会进行更多的包装并适应视图,但这两种方法都不好。