C# INotifyPropertyChanged未在ItemsControl内的ViewModel上激发
我正在使用C# INotifyPropertyChanged未在ItemsControl内的ViewModel上激发,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在使用ObservableCollection myItemVMList作为ItemsSource。我能够完美地绑定命令,但是INotifyPropertyChanged不起作用。这是我的密码: public class MyItemViewModel: INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChan
ObservableCollection myItemVMList
作为ItemsSource
。我能够完美地绑定命令
,但是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
上
如果我在MyItem
内部实现了INotifyPropertyChanged
,它可以工作,但我希望它在ViewModel
Content="{Binding SomeProperty}"
是的,因为它就是这样设计的。它如何知道应该侦听ViewModel的属性更改事件?它不绑定到它,它绑定到模型,因此它侦听模型上的更改
基本上有两种选择:
- 在
MyItem
- 绑定到
ViewModel
并添加包装器属性:Content="{Binding SomeProperty}"
如果希望遵循MVVM实践,您应该更喜欢绑定到ViewModelpublic string SomeProperty { get { return MyItem.SomeProperty; } set { MyItem.SomeProperty = value; OnPropertyChanged("SomeProperty"); } }
旁注:如果将
[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
}
}
公共字符串属性
{
获取{return MyItem.SomeProperty;}
设置
{
MyItem.SomeProperty=值;
OnPropertyChanged();//我理解,所以我的错误是不是{Binding MyItem.SomeProperty}
我应该在VM中添加一个包装并绑定到它?@Christopher确实如此。问题是,当你绑定到Foo.Bar.Baz
时,它会监听Foo
和Foo.Bar
上的更改通知。在你的情况下,它会监听MyItem
上的更改通知。哦,我明白了,非常感谢你;我很抱歉NET(不仅是WPF)的新手,所以我很难理解它的内部工作原理(文章通常只说如何做,但不解释内部内容)。不客气。如果你想更好地理解WPF的工作原理,我可以从WPF的作者那里向你提建议。