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}"
    
    并添加包装器属性:

    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
        }
    }
公共字符串属性
{
获取{return MyItem.SomeProperty;}
设置
{
MyItem.SomeProperty=值;

OnPropertyChanged();//我理解,所以我的错误是不是
{Binding MyItem.SomeProperty}
我应该在VM中添加一个包装并绑定到它?@Christopher确实如此。问题是,当你绑定到
Foo.Bar.Baz
时,它会监听
Foo
Foo.Bar
上的更改通知。在你的情况下,它会监听
MyItem
上的更改通知。哦,我明白了,非常感谢你;我很抱歉NET(不仅是WPF)的新手,所以我很难理解它的内部工作原理(文章通常只说如何做,但不解释内部内容)。不客气。如果你想更好地理解WPF的工作原理,我可以从WPF的作者那里向你提建议。