There have been similar questions like this on this site but I have not found an answer that really works, so I post it again.
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;}
}
I want to be able to notify changes in CalculatedProperty whenever Person1.Salary and/or Person2.Salary changes.
I have tried adding OnPropertyChanged("CalculatedProperty") on the setters of Person1 and Person2 but it does not work (and I understand why), but can't find a way to notify changes. Please help =)
(Is there a way to use an ObjectDataProvider for this?... Been trying that too...)
You need Person to implement INotifyPropertyChanged too, then register to the two properties you have. Once PropertyChanged is invoked with Salary on either of them, invoke PropertyChanged on CalculatedProperty
void PersonPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == "Salary")
OnPropertyChanged("CalculatedProperty");
}
Just remember to unregister when person is changed.
UPDATE:
As Jim said, your setter should look something like this:
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");
}
}
Give CLII the check but this is a complete example
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");
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With