我正在使用ObservableCollection<MyItemViewModel> myItemVMList
作为ItemsSouce
。我能够完美地绑定Command
,但INotifyPropertyChanged
无效。这是我的代码:
public class MyItemViewModel: INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name) {
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(name));
}
}
public MyItem MyItem { set; get; }
private RelayCommand _ChangeMyItemPropertyValue;
public ICommand ChangeMyItemPropertyValueCommand {
get {
if (_ChangeMyItemPropertyValue == null) _ChangeMyItemPropertyValue = new RelayCommand(o => ChangeMyItemPropertyValue());
return _ChangeMyItemPropertyValue;
}
}
private ChangeMyItemPropertyValue() {
MyItem.SomeProperty = someDifferentValue;
// NEITHER OF THESE CALLS WORK
OnPropertyChanged("MyItem.SomeProperty");
OnPropertyChagned("SomeProperty");
}
}
毋庸置疑,绑定在Content="{Binding MyItem.SomeProperty}"
内设置为DataTemplate
,并显示正确的值。问题是我运行该功能时没有更新。
SideNote:如果我在INotifyPropertyChanged
内部MyItem
实施,则可以使用ViewModel
。
答案 0 :(得分:4)
如果我在
INotifyPropertyChanged
内部MyItem
实施它可行,但我希望它在ViewModel
是的,因为这就是它的设计方式。怎么知道它应该听你的ViewModel的属性改变事件?它不绑定它,它绑定到模型,因此它会监听模型上的更改。
您基本上有两种选择:
在INotifyPropertyChanged
MyItem
绑定到ViewModel
Content="{Binding SomeProperty}"
添加包装器属性:
public string SomeProperty
{
get { return MyItem.SomeProperty; }
set
{
MyItem.SomeProperty = value;
OnPropertyChanged("SomeProperty");
}
}
如果您想遵循MVVM实践,则应该更喜欢绑定到ViewModel。
附注:如果您将[CallerMemberName]
添加到OnPropertyChanged
,请执行以下操作:
protected void OnPropertyChanged([CallerMemberName] string name = null) {
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(name));
}
您可以完全跳过属性名称:
public string SomeProperty
{
get { return MyItem.SomeProperty; }
set
{
MyItem.SomeProperty = value;
OnPropertyChanged(); // <-- no need for property name anymore
}
}