INotifyPropertyChanged 未在 ItemsControl 内的 ViewModel 上触发
INotifyPropertyChanged not firing on ViewModel inside ItemsControl
我正在使用 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");
}
}
不用说,DataTemplate
中的绑定设置为 Content="{Binding MyItem.SomeProperty}"
,它显示了正确的值。问题是当我 运行 函数时它没有更新。
旁注: 如果我在 MyItem
中实现 INotifyPropertyChanged
它可以工作,但我希望它在 ViewModel
.
If I implement the INotifyPropertyChanged
inside MyItem
it works, but I want it on the ViewModel
是的,因为它就是这样设计的。它应该如何知道它应该监听您的 ViewModel 的 属性 changed 事件?它不绑定到它,它绑定到模型,所以它会监听模型上的变化。
基本上你有两个选择:
在 MyItem
上实施 INotifyPropertyChanged
绑定到 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
}
}
我正在使用 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");
}
}
不用说,DataTemplate
中的绑定设置为 Content="{Binding MyItem.SomeProperty}"
,它显示了正确的值。问题是当我 运行 函数时它没有更新。
旁注: 如果我在 MyItem
中实现 INotifyPropertyChanged
它可以工作,但我希望它在 ViewModel
.
If I implement the
INotifyPropertyChanged
insideMyItem
it works, but I want it on theViewModel
是的,因为它就是这样设计的。它应该如何知道它应该监听您的 ViewModel 的 属性 changed 事件?它不绑定到它,它绑定到模型,所以它会监听模型上的变化。
基本上你有两个选择:
在
MyItem
上实施 绑定到
ViewModel
Content="{Binding SomeProperty}"
并添加包装器 属性:
public string SomeProperty { get { return MyItem.SomeProperty; } set { MyItem.SomeProperty = value; OnPropertyChanged("SomeProperty"); } }
如果您想遵循 MVVM 实践,您应该更喜欢绑定到 ViewModel。
INotifyPropertyChanged
旁注:如果像这样将 [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
}
}