INotifyPropertyChanged and propertyName



在实现INotifyPropertyChanged时,我一直不确定propertyName的含义。所以通常你实现INotifyPropertyChanged为:

public class Data : INotifyPropertyChanged {
   public event PropertyChangedEventHandler PropertyChanged;
   private void NotifyPropertyChanged(string propertyName = "") {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
   private string itsID;
   public string ID { 
             get { return itsID; }
             set { 
                   if (itsID != value) {
                     itsID = value; 
                     NotifyPropertyChanged("ID");
                  }
   }
}

我从来不确定propertyNameNotifyPropertyChanged(string propertyName)的论证。

  1. 可以是任何任意字符串(如"MyID"在上面的例子)?
  2. 或者。net使用反射来与类中的属性对齐,所以它必须与属性的名称完全匹配?
  3. 如果propertyNameProperty的名称不完全匹配,那么。net是否将整个对象视为changed ?

这不是。net框架本身,而是几乎每个PropertyChanged订阅者(其中一些确实碰巧作为框架的一部分分发)都假设您通过发送属性名按预期使用接口。如果您发送属性MyID已更改的通知,当另一个组件查看属性ID时,它通常会看到通知,比较名称,并得出"此通知不适合我"的结论。

如果你想完全匹配属性的名称,你可以使用c# 6的新特性nameofnameof特性回答了你所有的问题,因为我们可以说,用一个词来描述nameof的主要优点是重构。根据你的问题,"重构"是你要找的词:

NotifyPropertyChanged(nameof(ID));

作为一个例子,重命名ID也会改变属性的名称,或者它会破坏编译,但以下代码不会:

NotifyPropertyChanged("ID")

必须与属性的名称完全匹配。另外,您应该在调用PropertyChanged之前检查值是否已经实际更改,因为这是一个相对昂贵的调用(WPF不会知道属性没有更改)。在VS2015中,您还可以使用操作符的名称

根据INotifyPropertyChanged Interface页面,您可以保留未定义的propertyName参数。原因如下:

// This method is called by the Set accessor of each property.  
// The CallerMemberName attribute that is applied to the optional propertyName  
// parameter causes the property name of the caller to be substituted as an argument.  
private void NotifyPropertyChanged([CallerMemberName] String 
        propertyName = "")  
{  
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}  

注意参数中的[CallerMemberName]属性。这将自动将属性的名称替换为字符串,而无需静态地定义它。文档还指定:

PropertyChanged事件可以通过使用nullString.Empty作为PropertyChangedEventArgs中的属性名来指示对象上的所有属性已经更改。请注意,在UWP应用程序中,必须使用String.Empty而不是null。

这一切都是为了方便您手动处理特定控件或整个表单的更改。INotifyPropertyChanged接口没有定义NotifyPropertyChanged方法,因此必须事先了解CallerMemberName属性。

相关内容

  • 没有找到相关文章

最新更新