[英]INotifyPropertyChanged not firing on ViewModel inside ItemsControl
I'm using ObservableCollection<MyItemViewModel> myItemVMList
as the ItemsSouce
. 我正在使用ObservableCollection<MyItemViewModel> myItemVMList
作为ItemsSouce
。 I am able to bind Command
perfectly but the INotifyPropertyChanged
isn't working. 我能够完美地绑定Command
,但是INotifyPropertyChanged
无法正常工作。 Here's my code: 这是我的代码:
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");
}
}
Needless to say, the binding is set as Content="{Binding MyItem.SomeProperty}"
inside the DataTemplate
, and it shows the correct value. 不用说,绑定在DataTemplate
内部设置为Content="{Binding MyItem.SomeProperty}"
,并且显示正确的值。 Problem is it isn't updated when I run the function. 问题是我运行该功能时未更新。
SideNote: If I implement the INotifyPropertyChanged
inside MyItem
it works, but I want it on the ViewModel
. 注意:如果我在MyItem
实现INotifyPropertyChanged
,则可以使用,但我希望在ViewModel
上使用它。
If I implement the
INotifyPropertyChanged
insideMyItem
it works, but I want it on theViewModel
如果我在MyItem
实现INotifyPropertyChanged
,则可以使用,但我希望在ViewModel
Yes, because that's how it's designed. 是的,因为那是它的设计方式。 How it's supposed to know it should listen to your ViewModel's property changed event? 应该如何知道它应该侦听ViewModel的属性更改事件? It doesn't bind to it, it binds to the model, so it listens to the changes on the model. 它不绑定到它,而是绑定到模型,因此它侦听模型上的更改。
You have two choices basically: 您基本上有两种选择:
Implement INotifyPropertyChanged
on MyItem
在MyItem
上实现INotifyPropertyChanged
Bind to the ViewModel
绑定到ViewModel
Content="{Binding SomeProperty}"
And add a wrapper property: 并添加包装器属性:
public string SomeProperty { get { return MyItem.SomeProperty; } set { MyItem.SomeProperty = value; OnPropertyChanged("SomeProperty"); } }
You should prefer binding to the ViewModel if you want to follow MVVM practices. 如果要遵循MVVM做法,则应首选绑定到ViewModel。
Side note: If you add [CallerMemberName]
to OnPropertyChanged
like this: 附注:如果您添加[CallerMemberName]
到OnPropertyChanged
是这样的:
protected void OnPropertyChanged([CallerMemberName] string name = null) {
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(name));
}
You'll be able to skip the property name altogether: 您将可以完全跳过属性名称:
public string SomeProperty
{
get { return MyItem.SomeProperty; }
set
{
MyItem.SomeProperty = value;
OnPropertyChanged(); // <-- no need for property name anymore
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.