ViewModel为特定属性订阅Model的PropertyChanged事件

我想在模型中的Property更改时执行methodToBeCalledWhenPropertyIsSet()。

我怎么能这样做?

如果我理解正确,我可以在我的ViewModel中的某处添加MyModel.PropertyChanged += methodToBeCalledWhenPropertyIsSet来订阅PropertyChanged事件,但我只关心Property的设置

 public class ViewModel : INotifyPropertyChanged { ... public Model MyModel { get; set; } public void methodToBeCalledWhenPropertyIsSet() { } public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } public class Model : INotifyPropertyChanged { object _propertyField; public object Property { get { return _propertyField; } set { _propertyField = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } 

INotifyPropertyChanged接口解决了这个问题。 将您的视图模型订阅到模型PropertyChangedEventHandler并过滤您的结果。

 public class ViewModel : INotifyPropertyChanged { ... public Model MyModel { get; set; } public void methodToBeCalledWhenPropertyIsSet() { } public event PropertyChangedEventHandler PropertyChanged; public ViewModel() { // MyModel would need to be set in this example. MyModel.PropertyChanged += Model_PropertyChanged; } private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e) { if(e.PropertyName == "Property") { methodToBeCalledWhenPropertyIsSet(); } } } 

在MVVM模式中,View Model旨在处理像这样的混乱情况。 这仍然保留了您对模型的抽象。

Edit As HighCore指出,此代码无法复制粘贴。 MyModel需要事先实例化。 为此,我使用MEF( http://msdn.microsoft.com/en-us/library/dd460648 ( v=vs.110 ) .aspx )。 您可以直接获取模型类,也可以使用某种工厂/经理来获取参考。

一种可能的常用解决方案是使用ViewModel中的等效属性包装Model的Property

 public class ViewModel { public object Property { get { return Model.Property; } set { Model.Property = value; methodToBeCalledWhenPropertyIsSet(); // Here you call your method directly } } } 

并将您的UI绑定到此属性而不是模型。

编辑:如果模型因UI交互而发生更改,那么该交互将“通过”ViewModel发生。 如果模型由于模型本身的内部业务逻辑而发生变化,那么您将没有其他选择,只能订阅它的PropertyChanged事件,但请确保您稍后取消订阅。 我通常将这样的订阅/取消订阅代码放在VM中的Model属性的setter中:

 public MyModel Model { get { return _model; } set { if (_model != null) _model.PropertyChanged -= OnModelPropertyChanged; _model = value; if (_model != null _model.PropertyChanged += OnModelPropertyChanged; NotifyPropertyChange(() => Model); } }