我想在模型中的Property更改时执行methodToBeCalledWhenPropertyIsSet()。
我怎么能这样做?
如果我理解正确,我可以在我的ViewModel中的某处添加MyModel.PropertyChanged += methodToBeCalledWhenPropertyIsSet
来订阅PropertyChanged事件,但我只关心设置了属性
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));
}
}
答案 0 :(得分:13)
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旨在处理像这样的混乱情况。这仍然保留了你对模型的抽象。
修改强> 正如HighCore指出的那样,这段代码不能复制粘贴。 MyModel需要事先实例化。我为此目的使用MEF(http://msdn.microsoft.com/en-us/library/dd460648(v=vs.110).aspx)。您可以直接获取模型类,也可以使用某种工厂/经理来获取参考。
答案 1 :(得分:3)
一种可能的常用解决方案是使用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交互而发生变化,则会发生该互动" thru" 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);
}
}