INotifyPropertyChanged没有在ItemsControl内的ViewModel上触发

时间:2015-01-20 20:52:30

标签: c# wpf mvvm

我正在使用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

1 个答案:

答案 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
        }
    }