在不添加私有变量的情况下引发propertychanged事件

我有一个看起来像这样的房产。

public int NumberOfElephants { get; set; } 

此属性在一个observablecollection中,它必须通知另一个属性它已更改。

我该怎么办?

 public int NumberOfElephants { get; set { OnPropertyChanged("totalAnimals"); } 

没有代码需要像这样

 private int _numberOfElephants; public int NumberOfElephants { get { return _numberOfElephants; } set { _numberOfElephants = value; OnPropertyChanged("totalAnimals"); } } 

你没有。 你不能。

自动实现的属性在属性微不足道时才起作用 – 当get / set超出“返回变量的值”或“设置变量的值”时,不需要代码。 你可以通过重新格式化来缩短它…当然……我写的是:

 private int numberOfElephants; public int NumberOfElephants { get { return numberOfElephants; } set { _numberOfElephants = value; OnPropertyChanged("totalAnimals"); } } 

实际上,我会在套装的开始和房产的开始时使用“自行打开支架”,但我保留了你喜欢的款式。 但是在单行上使用“单表达式get / set实现”可以使具有大量属性的类更加清晰。

作为Jon的答案的替代方案,您可以通过IL编织获得可以执行此操作的工具,例如NotifyPropertyWeaver ,也可以通过VS Gallery作为工具使用

对于您的示例,根据他们在属性上的doco ,您应该能够拥有以下内容:

 [NotifyProperty(AlsoNotifyFor = new[] { "TotalAnimals" })] public int NumberOfElephants { get; set; } public int TotalAnimals { get; set; } 

但是,根据下面的示例,它们可能不需要取决于TotalAnimals的实现:

你的守则

 public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public string GivenNames { get; set; } public string FamilyName { get; set; } public string FullName { get { return string.Format("{0} {1}", GivenNames, FamilyName); } } } 

什么被编译

 public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; string givenNames; public string GivenNames { get { return givenNames; } set { if (value != givenNames) { givenNames = value; OnPropertyChanged("GivenNames"); OnPropertyChanged("FullName"); } } } string familyName; public string FamilyName { get { return familyName; } set { if (value != familyName) { familyName = value; OnPropertyChanged("FamilyName"); OnPropertyChanged("FullName"); } } } public string FullName { get { return string.Format("{0} {1}", GivenNames, FamilyName); } } public virtual void OnPropertyChanged(string propertyName) { var propertyChanged = PropertyChanged; if (propertyChanged != null) { propertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } 

扩展@jeffora的答案

使用NotifyPropertyWeaver你可以写这个

 public class Animals: INotifyPropertyChanged { public int NumberOfElephants { get; set; } public int NumberOfMonkeys { get; set; } public int TotalAnimals { get { return NumberOfElephants + NumberOfMonkeys; } } public event PropertyChangedEventHandler PropertyChanged; } 

这将被编译

 public class Animals : INotifyPropertyChanged { int numberOfElephants; int numberOfMonkeys; public int NumberOfElephants { get { return numberOfElephants; } set { numberOfElephants = value; OnPropertyChanged("TotalAnimals"); OnPropertyChanged("NumberOfElephants"); } } public int NumberOfMonkeys { get { return numberOfMonkeys; } set { numberOfMonkeys = value; OnPropertyChanged("TotalAnimals"); OnPropertyChanged("NumberOfMonkeys"); } } public int TotalAnimals { get { return NumberOfElephants + NumberOfMonkeys; } } public virtual void OnPropertyChanged(string propertyName) { var propertyChanged = PropertyChanged; if (propertyChanged != null) { propertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } public event PropertyChangedEventHandler PropertyChanged; } 

使用像PostSharp这样的工具,您可以编织属性以创建锅炉板代码。 更多,您不必实现INotifyPropertyChanged ,PostSharp可以为您完成。

看到这篇博文 。