在这个网站上有类似的问题,但我没有找到真正有效的答案,所以我再次发布。
public MyClass
{
public person Person1 {get; set;}
public person Person2 {get; set;}
CalculatedProperty
{
get
{ return Person1.Salary + (Person2.Salary/2) ; }
}
}
public class Person
{
public double Salary
{ get; set;}
}
我希望能够在CalculatedProperty
和/或Person1.Salary
更改时通知Person2.Salary
中的更改。
我尝试在OnPropertyChanged("CalculatedProperty")
和Person1
的设置者上添加Person2
,但它不起作用(我理解为什么),但无法找到通知更改的方法。请帮忙=)
(有没有办法为此使用ObjectDataProvider
?...一直在尝试......)
答案 0 :(得分:6)
您还需要Person
来实施INotifyPropertyChanged
,然后注册到您拥有的两个属性。在其中任何一个上使用PropertyChanged
调用Salary
后,在PropertyChanged
上调用CalculatedProperty
void PersonPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == "Salary")
OnPropertyChanged("CalculatedProperty");
}
请记住在人员被更换时取消注册。
<强>更新强>
正如吉姆所说,你的二传手应该是这样的:
private Person _person;
public Person Person
{
get { return _person; }
set
{
if (Equals(value, _person)) return;
if (_person != null)
_person.PropertyChanged -= PersonPropertyChanged;
_person = value;
if(_person != null)
_person.PropertyChanged += PersonPropertyChanged;
OnPropertyChanged("Person");
}
}
答案 1 :(得分:3)
给CLII检查,但这是一个完整的例子
using System.ComponentModel;
namespace NotifyBubble
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
// 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(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
Person = new Person();
Person.Salary = 100;
}
void PersonPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Salary")
NotifyPropertyChanged("CalculatedProperty");
}
public Double CalculatedProperty
{
get
{
return Person.Salary / 2;
}
}
private Person _person;
public Person Person
{
get { return _person; }
set
{
if (Equals(value, _person)) return;
if (_person != null)
_person.PropertyChanged -= PersonPropertyChanged;
_person = value;
if (_person != null)
_person.PropertyChanged += PersonPropertyChanged;
NotifyPropertyChanged("Person");
}
}
}
public class Person: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
// 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(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private double salary = 0;
public double Salary
{
get { return salary; }
set
{
if (salary == value) return;
salary = value;
NotifyPropertyChanged("Salary");
}
}
}
}
答案 2 :(得分:0)
仅供记录,这是我在集合中实现相同问题的方式(使用不同的示例)
public class Fields : ObservableCollection<Field>
{
protected override event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
void FieldPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsSelected")
{
NotifyPropertyChanged("SelectedItemsCount");
}
}
protected override void InsertItem(int index, Field item)
{
if (item != null)
item.PropertyChanged -= FieldPropertyChanged;
base.InsertItem(index, item);
if (item != null)
item.PropertyChanged += FieldPropertyChanged;
}
protected override void ClearItems()
{
foreach (Field field in this)
{
field.PropertyChanged -= FieldPropertyChanged;
}
base.ClearItems();
}
protected override void RemoveItem(int index)
{
if (this[index] != null)
this[index].PropertyChanged -= FieldPropertyChanged;
base.RemoveItem(index);
}
private int selectedItemsCount;
public int SelectedItemsCount
{
//This can be more efficient, not have to count everytime
get
{
selectedItemsCount = 0;
foreach (Field field in this)
{
if (field.IsSelected)
selectedItemsCount++;
}
return selectedItemsCount;
}
}
}